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}