code wiki / _hdl_build / nx_nishi_builder.nx

nx_nishi_builder.nx source

↩ module page · 104 lines · 6028 B

1// nx_nishi_builder.nx -- THE NISHI BUILDER: one universal, self-growing emitter catalog for the WHOLE 2// ecosystem (websites, games, ads, ... -- "truly our builder"). Every emitter we build in any domain is TAUGHT 3// here as DATA; the builder reads the catalog to emit, and a GROW loop generates new emitters and registers 4// them -- so ONE builder keeps growing its emitters across ALL domains (the emitter-of-emitters, universal). 5// 6// Generalises the ad-domain registry with a DOMAIN axis. Append-only + idempotent (rule 10/13). One row: 7// domain<TAB>kind<TAB>id<TAB>label<TAB>template 8// domain in {ad, web, game, ...}; kind is domain-scoped (ad: size/theme/accent/animation; web: section/nav/ 9// button/layout; game: sprite/tilemap/mechanic/entity); template = the emit DATA for that block. 10// SOVEREIGNTY INVARIANT (the whole builder, by construction): nb_template_safe REJECTS any template carrying a 11// <script or src= -> NO third-party JS, NO external fetch, in ANY domain. Functions take `path` (hermetic test). 12// Registry: knowledge/registry/nishi_builder.tsv. (TSV now; seg-store = the doctrine follow-on.) license_tier: ORIGINAL 13import "nx_syscalls.nx" 14 15const NB_PATH: *u8 = "knowledge/registry/nishi_builder.tsv" 16const NB_MAXTPL: i64 = 4096 17 18func nb_streq(a: *u8, b: *u8) -> i64 { var i: i64 = 0; while a[i] != (0 as u8) { if a[i] != b[i] { return 0 } i = i + 1 } if b[i] != (0 as u8) { return 0 } return 1 } 19func nb_field(line: *u8, linelen: i64, idx: i64, out: *u8) -> i64 { 20 var f: i64 = 0; var i: i64 = 0 21 while f < idx { if i < linelen { if line[i] == (9 as u8) { f = f + 1 } i = i + 1 } else { f = idx; i = linelen } } 22 var o: i64 = 0; var stop: i64 = 0 23 while i < linelen { if stop == 0 { if line[i] == (9 as u8) { stop = 1 } } if stop == 0 { out[o] = line[i]; o = o + 1 } i = i + 1 } 24 out[o] = 0 as u8; return 1 25} 26// 1 if a row matches (domain, kind, id). 27func nb_present(path: *u8, domain: *u8, kind: *u8, id: *u8) -> i64 { 28 let lp: *i64 = sys_mmap(16) as *i64; lp[0] = 0 29 let data: *u8 = sys_read_file(path, lp) 30 if (data as i64) == 0 { return 0 } 31 let n: i64 = lp[0]; let f0: *u8 = sys_mmap(64); let f1: *u8 = sys_mmap(64); let f2: *u8 = sys_mmap(128) 32 var i: i64 = 0; var ls: i64 = 0; var found: i64 = 0 33 while i < n { 34 if data[i] == (10 as u8) { 35 let line: *u8 = ((data as i64) + ls) as *u8; let ll: i64 = i - ls 36 nb_field(line, ll, 0, f0); nb_field(line, ll, 1, f1); nb_field(line, ll, 2, f2) 37 if nb_streq(f0, domain) == 1 { if nb_streq(f1, kind) == 1 { if nb_streq(f2, id) == 1 { found = 1 } } } 38 ls = i + 1 39 } 40 i = i + 1 41 } 42 return found 43} 44// TEACH one emitter into `path`. 1 newly-taught, 0 already-known, -1 IO fail. 45func nb_register(path: *u8, domain: *u8, kind: *u8, id: *u8, label: *u8, template: *u8) -> i64 { 46 if nb_present(path, domain, kind, id) == 1 { return 0 } 47 let line: *u8 = sys_mmap(NB_MAXTPL + 512); var o: i64 = 0 48 var i: i64 = 0; while domain[i] != (0 as u8) { line[o] = domain[i]; o = o + 1; i = i + 1 } line[o] = 9 as u8; o = o + 1 49 i = 0; while kind[i] != (0 as u8) { line[o] = kind[i]; o = o + 1; i = i + 1 } line[o] = 9 as u8; o = o + 1 50 i = 0; while id[i] != (0 as u8) { line[o] = id[i]; o = o + 1; i = i + 1 } line[o] = 9 as u8; o = o + 1 51 i = 0; while label[i] != (0 as u8) { line[o] = label[i]; o = o + 1; i = i + 1 } line[o] = 9 as u8; o = o + 1 52 i = 0; while template[i] != (0 as u8) { line[o] = template[i]; o = o + 1; i = i + 1 } line[o] = 10 as u8; o = o + 1 53 let fd: i64 = sys_openat_append(path, 420) 54 if fd < 0 { return 0 - 1 } 55 sys_write(fd, line, o); sys_close(fd) 56 return 1 57} 58// count emitters of (domain, kind); kind="*" counts the whole domain. 59func nb_count(path: *u8, domain: *u8, kind: *u8) -> i64 { 60 let lp: *i64 = sys_mmap(16) as *i64; lp[0] = 0 61 let data: *u8 = sys_read_file(path, lp) 62 if (data as i64) == 0 { return 0 } 63 let n: i64 = lp[0]; let f0: *u8 = sys_mmap(64); let f1: *u8 = sys_mmap(64) 64 var i: i64 = 0; var ls: i64 = 0; var c: i64 = 0 65 var anyk: i64 = 0; if kind[0] == (42 as u8) { anyk = 1 } // '*' 66 while i < n { 67 if data[i] == (10 as u8) { 68 let line: *u8 = ((data as i64) + ls) as *u8; let ll: i64 = i - ls 69 nb_field(line, ll, 0, f0); nb_field(line, ll, 1, f1) 70 if nb_streq(f0, domain) == 1 { if anyk == 1 { c = c + 1 } else { if nb_streq(f1, kind) == 1 { c = c + 1 } } } 71 ls = i + 1 72 } 73 i = i + 1 74 } 75 return c 76} 77// resolve (domain, kind, id) -> template (field4). 1 found, 0 not. 78func nb_lookup(path: *u8, domain: *u8, kind: *u8, id: *u8, out_template: *u8) -> i64 { 79 let lp: *i64 = sys_mmap(16) as *i64; lp[0] = 0 80 let data: *u8 = sys_read_file(path, lp) 81 if (data as i64) == 0 { return 0 } 82 let n: i64 = lp[0]; let f0: *u8 = sys_mmap(64); let f1: *u8 = sys_mmap(64); let f2: *u8 = sys_mmap(128) 83 var i: i64 = 0; var ls: i64 = 0; var got: i64 = 0 84 while i < n { 85 if data[i] == (10 as u8) { 86 let line: *u8 = ((data as i64) + ls) as *u8; let ll: i64 = i - ls 87 nb_field(line, ll, 0, f0); nb_field(line, ll, 1, f1); nb_field(line, ll, 2, f2) 88 if nb_streq(f0, domain) == 1 { if nb_streq(f1, kind) == 1 { if nb_streq(f2, id) == 1 { if got == 0 { nb_field(line, ll, 4, out_template); got = 1 } } } } 89 ls = i + 1 90 } 91 i = i + 1 92 } 93 return got 94} 95// SOVEREIGNTY INVARIANT: 1 if a template is sovereign-safe (no <script and no src=) -> applies to EVERY domain. 96func nb_template_safe(template: *u8) -> i64 { 97 var i: i64 = 0 98 while template[i] != (0 as u8) { 99 if template[i] == (60 as u8) { if template[i+1] == (115 as u8) { if template[i+2] == (99 as u8) { if template[i+3] == (114 as u8) { return 0 } } } } 100 if template[i] == (115 as u8) { if template[i+1] == (114 as u8) { if template[i+2] == (99 as u8) { if template[i+3] == (61 as u8) { return 0 } } } } 101 i = i + 1 102 } 103 return 1 104}