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}