code wiki / _hdl_build / nx_asset_emit_gen.nx

nx_asset_emit_gen.nx source

↩ module page · 110 lines · 6206 B

1// nx_asset_emit_gen.nx -- EMITTER-GENERATOR: turns any text asset into a NISHILANG EMITTER ORGAN, 2// making the .nx the SSOT and the asset a generated artifact (operator 2026-07-02: "use and build up 3// the nishi ecosystem including nishi lang" -- the last mile must be EMITTED by an organ, never 4// hand-edited). usage: nx_asset_emit_gen <asset> <out.nx> <organ_name> <target_path> 5// The generated organ: main(argc,argv) emits the asset bytes to <target_path> (argv[1] overrides the 6// target -- that is the DRIFT-KILL seam: emit to a compare path, byte-diff vs the canonical file). 7// Escaping: printable ASCII raw; '"'->\" '\\'->\\ LF->\n; all else -> \xHH with a FORCED literal 8// break when the next byte is a hex digit (so the lexer can never over-consume the escape). 9// license_tier: ORIGINAL 10import "nx_syscalls.nx" 11const K_MAGIC_65536: i64 = 65536 12const K_MAGIC_1200: i64 = 1200 13 14func gl(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 15func ap(b: *u8, n: i64, s: *u8) -> i64 { var i: i64=0; while s[i]!=(0 as u8){b[n+i]=s[i];i=i+1} return n+i } 16func apn(b: *u8, n: i64, v: i64) -> i64 { 17 let t: *u8=sys_mmap(28); var m: i64=v; var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} 18 var i: i64=0; var p: i64=n; while i<k{b[p]=t[k-1-i];p=p+1;i=i+1} return p } 19func hexd(v: i64) -> i64 { if v < 10 { return 48 + v } return 87 + v } // 0-9 a-f 20func ishex(c: i64) -> i64 { 21 if c >= 48 { if c <= 57 { return 1 } } 22 if c >= 97 { if c <= 102 { return 1 } } 23 if c >= 65 { if c <= 70 { return 1 } } 24 return 0 } 25 26func main(argc: i64, argv: *i64) -> i64 { 27 if argc < 5 { sys_write(1, "usage: nx_asset_emit_gen <asset> <out.nx> <organ_name> <target_path>\n" as *u8, 70); return 2 } 28 let srcp: *u8 = argv[1] as *u8 29 let outp: *u8 = argv[2] as *u8 30 let name: *u8 = argv[3] as *u8 31 let tgt: *u8 = argv[4] as *u8 32 let box: *i64 = sys_mmap(16) as *i64 33 let src: *u8 = sys_read_file(srcp, box) 34 if (src as i64) == 0 { sys_write(1, "cannot read asset\n" as *u8, 18); return 1 } 35 let sn: i64 = box[0] 36 let out: *u8 = sys_mmap(sn * 6 + K_MAGIC_65536) 37 var o: i64 = 0 38 o = ap(out, o, "// " as *u8) 39 o = ap(out, o, name) 40 o = ap(out, o, ".nx -- GENERATED EMITTER (nx_asset_emit_gen). THIS ORGAN IS THE SSOT for\n// " as *u8) 41 o = ap(out, o, tgt) 42 o = ap(out, o, " -- edit HERE (or regenerate), NEVER the emitted artifact.\n// argv[1] overrides the target (the drift-kill seam: emit to a compare path + byte-diff).\n// license_tier: ORIGINAL\nimport \"nx_syscalls.nx\"\n\n" as *u8) 43 // parts: cap ~1200 source bytes per literal; break early after \xHH if next is a hex digit 44 var parts: i64 = 0 45 var i: i64 = 0 46 while i < sn { 47 o = ap(out, o, "const P" as *u8) 48 o = apn(out, o, parts) 49 o = ap(out, o, ": *u8 = \"" as *u8) 50 var used: i64 = 0 51 var open: i64 = 1 52 while open == 1 { 53 if i >= sn { open = 0 } else { if used >= K_MAGIC_1200 { open = 0 } else { 54 let c: i64 = src[i] as i64 55 if c == 34 { out[o]=92 as u8; out[o+1]=34 as u8; o=o+2 } 56 else { if c == 92 { out[o]=92 as u8; out[o+1]=92 as u8; o=o+2 } 57 else { if c == 10 { out[o]=92 as u8; out[o+1]=110 as u8; o=o+2 } 58 else { if c >= 32 { if c <= 126 { out[o]=c as u8; o=o+1 } else { 59 out[o]=92 as u8; out[o+1]=120 as u8; out[o+2]=hexd(c/16) as u8; out[o+3]=hexd(c%16) as u8; o=o+4 60 if i+1 < sn { if ishex(src[i+1] as i64)==1 { open = 0 } } // force break: lexer safety 61 } } else { 62 out[o]=92 as u8; out[o+1]=120 as u8; out[o+2]=hexd(c/16) as u8; out[o+3]=hexd(c%16) as u8; o=o+4 63 if i+1 < sn { if ishex(src[i+1] as i64)==1 { open = 0 } } 64 } } } } 65 i = i + 1 66 used = used + 1 67 } } 68 } 69 o = ap(out, o, "\"\n" as *u8) 70 parts = parts + 1 71 } 72 o = ap(out, o, "\nfunc ep(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd,s,n); return n }\n\nfunc main(argc: i64, argv: *i64) -> i64 {\n var tgt: *u8 = \"" as *u8) 73 // target path into the generated organ (escape just \" and \\ -- paths are plain ASCII) 74 var q: i64 = 0 75 while tgt[q] != (0 as u8) { 76 let tc: i64 = tgt[q] as i64 77 if tc == 34 { out[o]=92 as u8; out[o+1]=34 as u8; o=o+2 } else { if tc == 92 { out[o]=92 as u8; out[o+1]=92 as u8; o=o+2 } else { out[o]=tc as u8; o=o+1 } } 78 q = q + 1 79 } 80 o = ap(out, o, "\" as *u8\n if argc >= 2 { tgt = argv[1] as *u8 }\n let fd: i64 = sys_openat_wr(tgt, 0x1a4)\n if fd < 0 { sys_write(1, \"emit: cannot open target\\n\" as *u8, 25); return 1 }\n var n: i64 = 0\n" as *u8) 81 var pctr: i64 = 0 82 while pctr < parts { 83 o = ap(out, o, " n = n + ep(fd, P" as *u8) 84 o = apn(out, o, pctr) 85 o = ap(out, o, ")\n" as *u8) 86 pctr = pctr + 1 87 } 88 o = ap(out, o, " sys_close(fd)\n sys_write(1, \"EMITTED \" as *u8, 8)\n let b: *u8 = sys_mmap(28)\n var m: i64 = n\n let t: *u8 = sys_mmap(28)\n var k: i64 = 0\n if m == 0 { t[0] = 48 as u8; k = 1 }\n while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }\n var i: i64 = 0\n while i < k { b[i] = t[k-1-i]; i = i + 1 }\n sys_write(1, b, k)\n sys_write(1, \" bytes\\n\" as *u8, 7)\n return 0\n}\n" as *u8) 89 let fd: i64 = sys_openat_wr(outp, 0x1a4) 90 if fd < 0 { sys_write(1, "cannot write out.nx\n" as *u8, 20); return 1 } 91 var wr: i64 = 0 92 while wr < o { 93 let w: i64 = sys_write(fd, out + wr, o - wr) 94 if w <= 0 { sys_close(fd); return 1 } 95 wr = wr + w 96 } 97 sys_close(fd) 98 sys_write(1, "GENERATED emitter organ: parts=" as *u8, 31) 99 let b2: *u8 = sys_mmap(28) 100 var m2: i64 = parts 101 let t2: *u8 = sys_mmap(28) 102 var k2: i64 = 0 103 if m2 == 0 { t2[0]=48 as u8; k2=1 } 104 while m2 > 0 { t2[k2]=(48+(m2%10)) as u8; m2=m2/10; k2=k2+1 } 105 var i2: i64 = 0 106 while i2 < k2 { b2[i2]=t2[k2-1-i2]; i2=i2+1 } 107 sys_write(1, b2, k2) 108 sys_write(1, "\n" as *u8, 1) 109 return 0 110}