code wiki / _hdl_build / nx_js_extends_gate.nx
nx_js_extends_gate.nx source
↩ module page · 70 lines · 5948 B
1import "nx_gate_gn.nx"
2import "nx_gate_base.nx"
3// nx_js_extends_gate.nx -- proves CLASS INHERITANCE (`extends` + `super`) works FROM JAVASCRIPT end-to-end:
4// a derived class links its prototype to the base (inherited methods resolve), `super(...)` in a
5// constructor chains the PARENT ctor onto the same `this` (inherited fields init), and `super.m(...)`
6// invokes the parent's prototype method with the current `this` (override delegation). ABSOLUTE expected
7// values via the tree-walker (the VM DECLINES extends/super -> tree fallback, so tree IS the oracle).
8// SCOPE: explicit super() constructors AND implicit derived ctors (no explicit constructor -> synthesized
9// `constructor(...N){super(...N)}`, forwarding args to the parent) are both supported. license_tier: ORIGINAL expect_exit: 0
10import "nx_syscalls.nx"
11import "nx_js_eval.nx"
12
13func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw("
14" as *u8); return ok }
15func gsl(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
16
17// run `src` through the tree-walker; pass iff rc==0 AND result == [etag,epay].
18func rjs(src: *u8, etag: i64, epay: i64) -> i64 {
19 let out: *i64 = sys_mmap(16) as *i64
20 let rc: i64 = js_run_source(src, gsl(src), out)
21 if rc != 0 { return 0 }
22 if out[0] != etag { return 0 }
23 if out[1] != epay { return 0 }
24 return 1
25}
26// run `src`; pass iff rc==0 AND result is a STRING equal to `exp`.
27func rjs_str(src: *u8, exp: *u8) -> i64 {
28 let out: *i64 = sys_mmap(16) as *i64
29 if js_run_source(src, gsl(src), out) != 0 { return 0 }
30 if out[0] != VAL_STR { return 0 }
31 let srec: *i64 = (out[1]) as *i64
32 let sb: *u8 = ev_str_bytes(srec); let sl: i64 = ev_str_len(srec)
33 if sl != gsl(exp) { return 0 }
34 var i: i64 = 0
35 while i < sl { if sb[i] != exp[i] { return 0 } i = i + 1 }
36 return 1
37}
38
39func main() -> i64 {
40 gw("js-extends SOVEREIGN gate (class B extends A: inherited methods + super() ctor chain + super.m())\n" as *u8)
41 var pass: i64 = 0
42 var ttl: i64 = 0
43
44 // --- inherited methods (prototype chain B.prototype -> A.prototype) ---
45 ttl=ttl+1; pass=pass+grow("E1 inherited method: new B().greet()=42\x00" as *u8, rjs("class A{greet(){return 42}} class B extends A{} new B().greet()" as *u8, VAL_NUM, 42))
46 ttl=ttl+1; pass=pass+grow("E6 own + inherited method: o.a()+o.b()=3\x00" as *u8, rjs("class A{a(){return 1}} class B extends A{b(){return 2}} var o=new B();o.a()+o.b()" as *u8, VAL_NUM, 3))
47 ttl=ttl+1; pass=pass+grow("E7 three-level chain: new C().m()=7\x00" as *u8, rjs("class A{m(){return 7}} class B extends A{} class C extends B{} new C().m()" as *u8, VAL_NUM, 7))
48 // --- override resolution (derived method shadows base) ---
49 ttl=ttl+1; pass=pass+grow("E5 override wins: new B().f()=2\x00" as *u8, rjs("class A{f(){return 1}} class B extends A{f(){return 2}} new B().f()" as *u8, VAL_NUM, 2))
50 // --- super() constructor chaining (inherited fields init on the instance) ---
51 ttl=ttl+1; pass=pass+grow("E2 super() ctor: b.x+b.y=12\x00" as *u8, rjs("class A{constructor(){this.x=5}} class B extends A{constructor(){super();this.y=7}} var b=new B();b.x+b.y" as *u8, VAL_NUM, 12))
52 ttl=ttl+1; pass=pass+grow("E3 super(9) forwards arg: new B().n=9\x00" as *u8, rjs("class A{constructor(n){this.n=n}} class B extends A{constructor(){super(9)}} new B().n" as *u8, VAL_NUM, 9))
53 ttl=ttl+1; pass=pass+grow("E9 super(4)+own field: b.w*b.h=20\x00" as *u8, rjs("class A{constructor(w){this.w=w}} class B extends A{constructor(){super(4);this.h=5}} var b=new B();b.w*b.h" as *u8, VAL_NUM, 20))
54 // --- super.method() delegation to parent prototype, bound to current `this` ---
55 ttl=ttl+1; pass=pass+grow("E4 super.val()+5=15\x00" as *u8, rjs("class A{val(){return 10}} class B extends A{val(){return super.val()+5}} new B().val()" as *u8, VAL_NUM, 15))
56 ttl=ttl+1; pass=pass+grow("E8 super.get3()*2 uses this set by super() =6\x00" as *u8, rjs("class A{constructor(){this.v=3} get3(){return this.v}} class B extends A{constructor(){super()} calc(){return super.get3()*2}} new B().calc()" as *u8, VAL_NUM, 6))
57 ttl=ttl+1; pass=pass+grow("E11 super.name()+'B' string delegate = 'AB'\x00" as *u8, rjs_str("class A{name(){return 'A'}} class B extends A{name(){return super.name()+'B'}} new B().name()" as *u8, "AB\x00" as *u8))
58 // --- implicit derived ctor (no explicit constructor) auto-forwards to the parent ctor ---
59 ttl=ttl+1; pass=pass+grow("E13 implicit ctor forwards arg: new B(7).n=7\x00" as *u8, rjs("class A{constructor(n){this.n=n}} class B extends A{} new B(7).n" as *u8, VAL_NUM, 7))
60 ttl=ttl+1; pass=pass+grow("E14 implicit ctor no-arg: new B().k=3\x00" as *u8, rjs("class A{constructor(){this.k=3}} class B extends A{} new B().k" as *u8, VAL_NUM, 3))
61 ttl=ttl+1; pass=pass+grow("E15 implicit ctor + inherited method: new B(9).get()=9\x00" as *u8, rjs("class A{constructor(v){this.v=v} get(){return this.v}} class B extends A{} new B(9).get()" as *u8, VAL_NUM, 9))
62 ttl=ttl+1; pass=pass+grow("E16 implicit ctor forwards 2 args: b.p+b.q=30\x00" as *u8, rjs("class A{constructor(p,q){this.p=p;this.q=q}} class B extends A{} var b=new B(10,20);b.p+b.q" as *u8, VAL_NUM, 30))
63 // --- regressions: plain class + division still parse with extends/super keywords in play ---
64 ttl=ttl+1; pass=pass+grow("E10 plain class unchanged: new P().z=8\x00" as *u8, rjs("class P{constructor(){this.z=8}} new P().z" as *u8, VAL_NUM, 8))
65 ttl=ttl+1; pass=pass+grow("E12 division unbroken near extends: a/2=5\x00" as *u8, rjs("class A{} class B extends A{} var a=10;a/2" as *u8, VAL_NUM, 5))
66
67 gw("pass=" as *u8); gn(pass); gw("/" as *u8); gn(ttl); gw("\n" as *u8)
68 if pass == ttl { gw("verdict=GREEN (class inheritance runs from JS: extends chain + super() + super.method)\n" as *u8); sys_exit(0); return 0 }
69 gw("verdict=RED\n" as *u8); sys_exit(1); return 1
70}