code wiki / _hdl_build / nx_eoe_branch.nx
nx_eoe_branch.nx source
↩ module page · 115 lines · 6127 B
1// nx_eoe_branch.nx -- EMITTER-OF-EMITTERS, GENERALITY RUNG 3: BRANCHES-from-spec.
2//
3// The ladder so far: nx_eoe (006e) synthesizes control-flow DEPTH (N unconditional
4// nested loops); nx_eoe_oplist (006g) synthesizes a LINEAR COMPUTATION (op-list, no
5// branching). Neither can take a DIFFERENT PATH based on data. This rung
6// synthesizes a CONDITIONAL: an if/else whose PREDICATE comes from the spec, so the
7// emitted program takes a DIFFERENT BRANCH for different inputs -- real data-driven
8// control-flow divergence, which a linear op-list and an unconditional loop nest
9// provably cannot produce.
10//
11// nx_eoe_branch <basename> <start> <pred> <then-op> <else-op>
12// pred = g<t> | l<t> | e<t> (acc > t | acc < t | acc == t)
13// then-op = a<n> | m<n> | s<n> (applied iff pred true)
14// else-op = a<n> | m<n> | s<n> (applied iff pred false)
15// -> writes runtime/_hdl_build/<basename>.nx whose main() sets acc=start, applies
16// then-op OR else-op per the predicate, and prints "RESULT=<acc>\n". nx_cc
17// compiles it (the if/else MACHINE CODE is delegated to the compiler the team
18// owns -- the emitter only synthesizes the STRUCTURE from data).
19//
20// no-false-green plan (X-AUT-006d): same ops but a START that flips the predicate
21// -> the OTHER branch runs -> a DIFFERENT correct result (proves the branch is
22// really evaluated, not constant-folded to one side); tamper the threshold -> flips.
23// Sovereign, no gcc/.sh. HONEST SCOPE: a single 2-way branch over one comparison;
24// NOT yet nested/op-list branches or loops-with-conditions -- ONE rung.
25// license_tier: ORIGINAL
26import "nx_syscalls.nx"
27const K_MAGIC_65536: i64 = 65536
28
29func eob_cat(dst: *u8, off: i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { dst[off+i] = s[i]; i = i + 1 } return off + i }
30func eob_catn(dst: *u8, off: i64, v: i64) -> i64 {
31 var o: i64 = off
32 if v < 0 { dst[o] = 45 as u8; o = o + 1; return eob_catn(dst, o, 0 - v) }
33 if v == 0 { dst[o] = 48 as u8; return o + 1 }
34 var m: i64 = v
35 let t: *u8 = sys_mmap(28)
36 var k: i64 = 0
37 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
38 var i: i64 = 0
39 while i < k { dst[o+i] = t[k-1-i]; i = i + 1 }
40 return o + k
41}
42func eob_p(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
43func eob_atoi_from(s: *u8, from: i64) -> i64 {
44 var n: i64 = 0; var i: i64 = from
45 while s[i] != (0 as u8) { if s[i] >= (48 as u8) { if s[i] <= (57 as u8) { n = n * 10 + ((s[i] as i64) - 48) } } i = i + 1 }
46 return n
47}
48// emit one "acc = acc <op> <n>" line for op char c (a/m/s) at the given indent.
49func eob_emit_op(buf: *u8, off: i64, indent: *u8, c: i64, n: i64) -> i64 {
50 var o: i64 = off
51 o = eob_cat(buf, o, indent)
52 o = eob_cat(buf, o, "acc = acc " as *u8)
53 if c == 97 { o = eob_cat(buf, o, "+ " as *u8) } // 'a'
54 if c == 109 { o = eob_cat(buf, o, "* " as *u8) } // 'm'
55 if c == 115 { o = eob_cat(buf, o, "- " as *u8) } // 's'
56 o = eob_catn(buf, o, n)
57 o = eob_cat(buf, o, "\n" as *u8)
58 return o
59}
60
61func main(argc: i64, argv: *i64) -> i64 {
62 if argc < 6 { eob_p("usage: nx_eoe_branch <basename> <start> <pred g<t>|l<t>|e<t>> <then a|m|s<n>> <else a|m|s<n>>\n" as *u8); return 2 }
63 let base: *u8 = argv[1] as *u8
64 let start: i64 = eob_atoi_from(argv[2] as *u8, 0)
65 let pred: *u8 = argv[3] as *u8
66 let pc: i64 = pred[0] as i64 // 'g'/'l'/'e'
67 let thr: i64 = eob_atoi_from(pred, 1)
68 let thenop: *u8 = argv[4] as *u8
69 let elseop: *u8 = argv[5] as *u8
70
71 let path: *u8 = sys_mmap(512)
72 var po: i64 = 0
73 po = eob_cat(path, po, "runtime/_hdl_build/" as *u8)
74 po = eob_cat(path, po, base)
75 po = eob_cat(path, po, ".nx" as *u8)
76 path[po] = 0 as u8
77
78 let buf: *u8 = sys_mmap(K_MAGIC_65536)
79 var o: i64 = 0
80 o = eob_cat(buf, o, "// GENERATED BY nx_eoe_branch (emitter-of-emitters, branches-from-spec) -- if/else structure synthesized from a DATA predicate, compiled by nx_cc. license_tier: ORIGINAL\n" as *u8)
81 o = eob_cat(buf, o, "import \"nx_syscalls.nx\"\n" as *u8)
82 o = eob_cat(buf, o, "func main() -> i64 {\n" as *u8)
83 o = eob_cat(buf, o, " var acc: i64 = " as *u8); o = eob_catn(buf, o, start); o = eob_cat(buf, o, "\n" as *u8)
84
85 // the SYNTHESIZED conditional: if acc <cmp> thr { then-op } else { else-op }
86 o = eob_cat(buf, o, " if acc " as *u8)
87 if pc == 103 { o = eob_cat(buf, o, "> " as *u8) } // 'g'
88 if pc == 108 { o = eob_cat(buf, o, "< " as *u8) } // 'l'
89 if pc == 101 { o = eob_cat(buf, o, "== " as *u8) } // 'e'
90 o = eob_catn(buf, o, thr)
91 o = eob_cat(buf, o, " {\n" as *u8)
92 o = eob_emit_op(buf, o, " " as *u8, thenop[0] as i64, eob_atoi_from(thenop, 1))
93 o = eob_cat(buf, o, " } else {\n" as *u8)
94 o = eob_emit_op(buf, o, " " as *u8, elseop[0] as i64, eob_atoi_from(elseop, 1))
95 o = eob_cat(buf, o, " }\n" as *u8)
96
97 // emitted decimal print "RESULT=<acc>\n".
98 o = eob_cat(buf, o, " sys_write(1, \"RESULT=\" as *u8, 7)\n" as *u8)
99 o = eob_cat(buf, o, " var m: i64 = acc\n" as *u8)
100 o = eob_cat(buf, o, " if m < 0 { sys_write(1, \"-\" as *u8, 1); m = 0 - m }\n" as *u8)
101 o = eob_cat(buf, o, " let t: *u8 = sys_mmap(28)\n" as *u8)
102 o = eob_cat(buf, o, " var k: i64 = 0\n" as *u8)
103 o = eob_cat(buf, o, " if m == 0 { t[0] = 48 as u8; k = 1 }\n" as *u8)
104 o = eob_cat(buf, o, " while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }\n" as *u8)
105 o = eob_cat(buf, o, " while k > 0 { k = k - 1; sys_write(1, (((t as i64)+k) as *u8), 1) }\n" as *u8)
106 o = eob_cat(buf, o, " sys_write(1, \"\\n\" as *u8, 1)\n" as *u8)
107 o = eob_cat(buf, o, " return 0\n}\n" as *u8)
108
109 let fd: i64 = sys_openat_wr(path, 420)
110 if fd < 0 { eob_p("EOEBRANCH verdict=RED reason=out-unwritable\n" as *u8); return 1 }
111 sys_write(fd, buf, o)
112 sys_close(fd)
113 eob_p("EOEBRANCH name=" as *u8); eob_p(path); eob_p(" verdict=EMITTED\n" as *u8)
114 return 0
115}