code wiki / _hdl_build / nx_js_spread_gate.nx
nx_js_spread_gate.nx source
↩ module page · 52 lines · 3758 B
1import "nx_gate_gn.nx"
2import "nx_gate_base.nx"
3// nx_js_spread_gate.nx -- proves SPREAD IN CALL ARGUMENTS works FROM JAVASCRIPT: `f(...xs)` splices an
4// array into positional args, mixes with fixed args (`f(a, ...xs, b)`), stacks multiple spreads, feeds
5// `new C(...xs)`, and reaches native builtins (`Math.max(...xs)`). ABSOLUTE expected values via the
6// tree-walker (the VM DECLINES spread-args -> tree fallback, so tree IS the oracle). license_tier: ORIGINAL expect_exit: 0
7import "nx_syscalls.nx"
8import "nx_js_eval.nx"
9import "nx_gate_verdict.nx"
10
11func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw("
12" as *u8); return ok }
13func gsl(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
14
15func rjs(src: *u8, etag: i64, epay: i64) -> i64 {
16 let out: *i64 = sys_mmap(16) as *i64
17 let rc: i64 = js_run_source(src, gsl(src), out)
18 if rc != 0 { return 0 }
19 if out[0] != etag { return 0 }
20 if out[1] != epay { return 0 }
21 return 1
22}
23
24func main() -> i64 {
25 gw("js-spread SOVEREIGN gate (f(...xs) call-arg spread: user fns, mixed, stacked, new, natives)\n" as *u8)
26 var pass: i64 = 0
27 var ttl: i64 = 0
28
29 ttl=ttl+1; pass=pass+grow("S1 add(...[1,2,3])=6\x00" as *u8, rjs("function add(a,b,c){return a+b+c} var xs=[1,2,3];add(...xs)" as *u8, VAL_NUM, 6))
30 ttl=ttl+1; pass=pass+grow("S2 f(1,...[2,3])=123 (leading fixed)\x00" as *u8, rjs("function f(a,b,c){return a*100+b*10+c} f(1,...[2,3])" as *u8, VAL_NUM, 123))
31 ttl=ttl+1; pass=pass+grow("S3 f(...[1,2],3)=123 (trailing fixed)\x00" as *u8, rjs("function f(a,b,c){return a*100+b*10+c} f(...[1,2],3)" as *u8, VAL_NUM, 123))
32 ttl=ttl+1; pass=pass+grow("S4 f(...[1,2],...[3,4])=10 (two spreads)\x00" as *u8, rjs("function f(a,b,c,d){return a+b+c+d} f(...[1,2],...[3,4])" as *u8, VAL_NUM, 10))
33 ttl=ttl+1; pass=pass+grow("S5 f(...[])=0 (empty spread)\x00" as *u8, rjs("function f(a,b){return (a||0)+(b||0)} f(...[])" as *u8, VAL_NUM, 0))
34 ttl=ttl+1; pass=pass+grow("S6 spread of a variable: f(...a)=24\x00" as *u8, rjs("var a=[2,3,4];function f(x,y,z){return x*y*z} f(...a)" as *u8, VAL_NUM, 24))
35 ttl=ttl+1; pass=pass+grow("S7 new P(...[4,5]).s=9 (spread into new)\x00" as *u8, rjs("class P{constructor(a,b){this.s=a+b}} var xs=[4,5];new P(...xs).s" as *u8, VAL_NUM, 9))
36 ttl=ttl+1; pass=pass+grow("S8 forwarding wrapper inner(...x)=30\x00" as *u8, rjs("function inner(a,b){return a+b} function wrap(x){return inner(...x)} wrap([10,20])" as *u8, VAL_NUM, 30))
37 ttl=ttl+1; pass=pass+grow("S9 Math.max(...[3,7,2,9,1])=9 (native)\x00" as *u8, rjs("Math.max(...[3,7,2,9,1])" as *u8, VAL_NUM, 9))
38 ttl=ttl+1; pass=pass+grow("S10 Math.min(...[5,2,8])=2 (native)\x00" as *u8, rjs("Math.min(...[5,2,8])" as *u8, VAL_NUM, 2))
39 ttl=ttl+1; pass=pass+grow("S11 mixed spread+fixed reaches all: f(0,...[1,2,3],4)=10\x00" as *u8, rjs("function f(a,b,c,d,e){return a+b+c+d+e} f(0,...[1,2,3],4)" as *u8, VAL_NUM, 10))
40 ttl=ttl+1; pass=pass+grow("S12 normal call unbroken: g(10,3)=7\x00" as *u8, rjs("function g(a,b){return a-b} g(10,3)" as *u8, VAL_NUM, 7))
41
42 gw("pass=" as *u8); gn(pass); gw("/" as *u8); gn(ttl); gw("\n" as *u8)
43 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
44 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
45 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
46 let ctr__dry: *i64 = gv_ctr()
47 ctr__dry[0] = pass
48 ctr__dry[1] = ttl
49 let rc__dry: i64 = gv_verdict("JS-SPREAD-GATE" as *u8, ctr__dry, "call-arg spread runs from JS: user/new/native, mixed + stacked)" as *u8)
50 sys_exit(rc__dry)
51 return rc__dry
52}