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}