code wiki / _hdl_build / nx_eoe_while.nx

nx_eoe_while.nx source

↩ module page · 110 lines · 5959 B

1// nx_eoe_while.nx -- EMITTER-OF-EMITTERS, GENERALITY RUNG 4: DATA-DRIVEN ITERATION. 2// 3// The ladder: nx_eoe (006e) = control-flow DEPTH (N nested loops, FIXED bound); 4// nx_eoe_oplist (006g) = linear COMPUTATION; nx_eoe_branch (006h) = a 2-way BRANCH 5// (predicate from spec). nx_eoe's loops run a FIXED number of times (bound is a 6// spec constant). This rung synthesizes a CONDITIONAL while-loop: it runs UNTIL a 7// data PREDICATE flips, so the ITERATION COUNT is COMPUTED from the running data, 8// not specified -- the same spec on different effective dynamics loops a different 9// number of times. That data-dependent iteration is exactly what a fixed-bound 10// loop nest and a linear op-list provably cannot express. 11// 12// nx_eoe_while <basename> <start> <whilepred> <body-op> 13// whilepred = g<t> | l<t> | e<t> (loop runs WHILE acc > t | acc < t | acc == t) 14// body-op = a<n> | m<n> | s<n> (applied once per iteration) 15// -> writes runtime/_hdl_build/<basename>.nx whose main() runs the loop and prints 16// "RESULT=<acc>\n". nx_cc compiles the loop (the team owns the loop codegen). 17// A safety GUARD (break after 100000 iters) prevents a runaway emitted organ from 18// hanging -- it never fires for a well-formed terminating spec. 19// 20// no-false-green plan (X-AUT-006d): DIFFERENT body ops -> DIFFERENT iteration counts 21// -> DIFFERENT correct results (e.g. <100 by *2 = 7 iters -> 128; <100 by +1 = 99 22// iters -> 100), proving the COUNT is data-driven not templated; tamper threshold -> 23// different result. Sovereign, no gcc/.sh. HONEST SCOPE: one predicate-driven 24// while over a single body op -- NOT yet op-list bodies or nested loops. ONE rung. 25// license_tier: ORIGINAL 26import "nx_syscalls.nx" 27const K_MAGIC_65536: i64 = 65536 28 29func eow_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 eow_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 eow_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 eow_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 eow_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 49func main(argc: i64, argv: *i64) -> i64 { 50 if argc < 5 { eow_p("usage: nx_eoe_while <basename> <start> <whilepred g<t>|l<t>|e<t>> <body a|m|s<n>>\n" as *u8); return 2 } 51 let base: *u8 = argv[1] as *u8 52 let start: i64 = eow_atoi_from(argv[2] as *u8, 0) 53 let pred: *u8 = argv[3] as *u8 54 let pc: i64 = pred[0] as i64 55 let thr: i64 = eow_atoi_from(pred, 1) 56 let body: *u8 = argv[4] as *u8 57 let bc: i64 = body[0] as i64 58 let bn: i64 = eow_atoi_from(body, 1) 59 60 let path: *u8 = sys_mmap(512) 61 var po: i64 = 0 62 po = eow_cat(path, po, "runtime/_hdl_build/" as *u8) 63 po = eow_cat(path, po, base) 64 po = eow_cat(path, po, ".nx" as *u8) 65 path[po] = 0 as u8 66 67 let buf: *u8 = sys_mmap(K_MAGIC_65536) 68 var o: i64 = 0 69 o = eow_cat(buf, o, "// GENERATED BY nx_eoe_while (emitter-of-emitters, data-driven iteration) -- a predicate-driven while synthesized from a DATA spec, compiled by nx_cc. license_tier: ORIGINAL\n" as *u8) 70 o = eow_cat(buf, o, "import \"nx_syscalls.nx\"\n" as *u8) 71 o = eow_cat(buf, o, "func main() -> i64 {\n" as *u8) 72 o = eow_cat(buf, o, " var acc: i64 = " as *u8); o = eow_catn(buf, o, start); o = eow_cat(buf, o, "\n" as *u8) 73 o = eow_cat(buf, o, " var guard: i64 = 0\n" as *u8) 74 75 // SYNTHESIZED loop: while acc <cmp> thr { body ; guard safety } 76 o = eow_cat(buf, o, " while acc " as *u8) 77 if pc == 103 { o = eow_cat(buf, o, "> " as *u8) } // 'g' 78 if pc == 108 { o = eow_cat(buf, o, "< " as *u8) } // 'l' 79 if pc == 101 { o = eow_cat(buf, o, "== " as *u8) } // 'e' 80 o = eow_catn(buf, o, thr) 81 o = eow_cat(buf, o, " {\n" as *u8) 82 o = eow_cat(buf, o, " acc = acc " as *u8) 83 if bc == 97 { o = eow_cat(buf, o, "+ " as *u8) } // 'a' 84 if bc == 109 { o = eow_cat(buf, o, "* " as *u8) } // 'm' 85 if bc == 115 { o = eow_cat(buf, o, "- " as *u8) } // 's' 86 o = eow_catn(buf, o, bn) 87 o = eow_cat(buf, o, "\n" as *u8) 88 o = eow_cat(buf, o, " guard = guard + 1\n" as *u8) 89 o = eow_cat(buf, o, " if guard >= 100000 { break }\n" as *u8) // runaway safety net 90 o = eow_cat(buf, o, " }\n" as *u8) 91 92 // emitted decimal print "RESULT=<acc>\n". 93 o = eow_cat(buf, o, " sys_write(1, \"RESULT=\" as *u8, 7)\n" as *u8) 94 o = eow_cat(buf, o, " var m: i64 = acc\n" as *u8) 95 o = eow_cat(buf, o, " if m < 0 { sys_write(1, \"-\" as *u8, 1); m = 0 - m }\n" as *u8) 96 o = eow_cat(buf, o, " let t: *u8 = sys_mmap(28)\n" as *u8) 97 o = eow_cat(buf, o, " var k: i64 = 0\n" as *u8) 98 o = eow_cat(buf, o, " if m == 0 { t[0] = 48 as u8; k = 1 }\n" as *u8) 99 o = eow_cat(buf, o, " while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }\n" as *u8) 100 o = eow_cat(buf, o, " while k > 0 { k = k - 1; sys_write(1, (((t as i64)+k) as *u8), 1) }\n" as *u8) 101 o = eow_cat(buf, o, " sys_write(1, \"\\n\" as *u8, 1)\n" as *u8) 102 o = eow_cat(buf, o, " return 0\n}\n" as *u8) 103 104 let fd: i64 = sys_openat_wr(path, 420) 105 if fd < 0 { eow_p("EOEWHILE verdict=RED reason=out-unwritable\n" as *u8); return 1 } 106 sys_write(fd, buf, o) 107 sys_close(fd) 108 eow_p("EOEWHILE name=" as *u8); eow_p(path); eow_p(" verdict=EMITTED\n" as *u8) 109 return 0 110}