code wiki / _hdl_build / nx_game_ingest.nx
nx_game_ingest.nx source
↩ module page · 101 lines · 4940 B
1// nx_game_ingest.nx -- Imports and processes an open-source games catalog to populate a structured genre registry.
2import "nx_gate_base.nx"
3// nx_game_ingest.nx -- NISHI GAME ECOSYSTEM, rung 0: sovereign INGEST of an open-source-games catalog
4// into a structured GENRE REGISTRY (the emitter's test set). One self-contained pipeline: sovereign TLS
5// fetch -> parse markdown "## <Genre>" sections + count game links (`](http`) per section -> write the
6// registry knowledge/store/nx_game_genres.reg (organ-written records: genre<TAB>game_count). No txt
7// config, no manual grep. 100% sovereign (own TLS, nx_cc->nxasm). license_tier: ORIGINAL expect_exit: 0
8import "nx_syscalls.nx"
9import "nx_x509_trust_store.nx"
10import "nx_trust_store_load_from_certdata.nx"
11import "nx_https_fetch_follow.nx"
12const K_MAGIC_4194304: i64 = 4194304
13const K_MAGIC_8388608: i64 = 8388608
14
15func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw("
16" as *u8); return ok }
17func gn(v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m;sys_write(1,"-" as *u8,1)} let t: *u8=sys_mmap(28); 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} var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1} sys_write(1,bb,k); return 0 }
18
19// does buf[i..] start with pat (null-terminated)?
20func match_at(buf: *u8, n: i64, i: i64, pat: *u8) -> i64 {
21 var j: i64 = 0
22 while pat[j] != (0 as u8) {
23 if i + j >= n { return 0 }
24 if buf[i + j] != pat[j] { return 0 }
25 j = j + 1
26 }
27 return 1
28}
29
30func wfd_n(fd: i64, v: i64) -> i64 {
31 if v == 0 { let z: *u8=sys_mmap(1); z[0]=48 as u8; sys_write(fd,z,1); return 0 }
32 let d: *u8=sys_mmap(24); var m: i64=v; var k: i64=0
33 while m>0 { d[k]=(48+(m%10)) as u8; m=m/10; k=k+1 }
34 let b: *u8=sys_mmap(24); var i: i64=0; while i<k { b[i]=d[k-1-i]; i=i+1 }
35 sys_write(fd,b,k); return 0
36}
37
38// emit one registry record + echo to stdout. name = buf[g0..g1).
39func emit_genre(fd: i64, buf: *u8, g0: i64, g1: i64, count: i64) -> i64 {
40 let p: *u8 = ((buf as i64) + g0) as *u8
41 let len: i64 = g1 - g0
42 sys_write(fd, p, len); sys_write(fd, "\t" as *u8, 1); wfd_n(fd, count); sys_write(fd, "\n" as *u8, 1)
43 gw(" "); sys_write(1, p, len); gw(" ("); gn(count); gw(" games)\n")
44 return 0
45}
46
47func main() -> i64 {
48 let r: i64 = nx_trust_store_load_from_certdata("data/mozilla_certdata.txt" as *u8, 512, K_MAGIC_4194304)
49 if r <= 0 { gw("INGEST: certdata load failed\n"); return 1 }
50 let store: *TrustStore = r as *TrustStore
51 let cap: i64 = K_MAGIC_8388608
52 let out: *u8 = sys_mmap(cap)
53 let status: *i64 = sys_mmap(8) as *i64
54 let n: i64 = nx_https_fetch_follow("https://raw.githubusercontent.com/bobeff/open-source-games/master/README.md" as *u8, store, out, cap, 6, status)
55 if n <= 0 { gw("INGEST: fetch failed code "); gn(n); gw("\n"); return 2 }
56 gw("INGEST catalog status="); gn(status[0]); gw(" bytes="); gn(n); gw("\n")
57
58 // bank the raw catalog so the per-game detail (repo URLs, languages) is available for review
59 let rawfd: i64 = sys_openat_wr("knowledge/store/bobeff_games.md" as *u8, 0x1a4)
60 if rawfd >= 0 { sys_write(rawfd, out, n); sys_close(rawfd); gw("INGEST: banked raw catalog -> knowledge/store/bobeff_games.md\n") }
61
62 let fd: i64 = sys_openat_wr("knowledge/store/nx_game_genres.reg" as *u8, 0x1a4)
63 if fd < 0 { gw("INGEST: registry open failed\n"); return 3 }
64
65 var i: i64 = 0
66 var ngenres: i64 = 0
67 var total_links: i64 = 0
68 var links_sec: i64 = 0
69 var have_genre: i64 = 0
70 var g0: i64 = 0
71 var g1: i64 = 0
72 gw("== GENRES INGESTED ==\n")
73 while i < n {
74 var at_ls: i64 = 0
75 if i == 0 { at_ls = 1 } else { if out[i-1] == 10 as u8 { at_ls = 1 } }
76 if at_ls == 1 {
77 if match_at(out, n, i, "## " as *u8) == 1 {
78 if have_genre == 1 { emit_genre(fd, out, g0, g1, links_sec); ngenres = ngenres + 1 }
79 g0 = i + 3
80 var k: i64 = g0
81 while k < n { if out[k] == 10 as u8 { k = n } else { k = k + 1 } }
82 // recompute g1 as the newline position (k stopped at n on newline-or-end; find it cleanly)
83 var m: i64 = g0
84 while m < n { if out[m] == 10 as u8 { break } m = m + 1 }
85 g1 = m
86 links_sec = 0
87 have_genre = 1
88 }
89 }
90 if match_at(out, n, i, "](http" as *u8) == 1 { links_sec = links_sec + 1; total_links = total_links + 1 }
91 i = i + 1
92 }
93 if have_genre == 1 { emit_genre(fd, out, g0, g1, links_sec); ngenres = ngenres + 1 }
94 sys_close(fd)
95
96 gw("INGESTED genres="); gn(ngenres); gw(" total_game_links="); gn(total_links)
97 gw(" -> knowledge/store/nx_game_genres.reg\n")
98 if ngenres > 0 { gw("INGEST-OK\n"); return 0 }
99 gw("INGEST: 0 genres parsed (format?)\n")
100 return 4
101}