code wiki / _hdl_build / nx_research_signal.nx
nx_research_signal.nx source
↩ module page · 35 lines · 1898 B
1// nx_research_signal.nx -- a GROWTH rung for the Nishi researcher: turn FETCHED raw sources into structured SIGNALS.
2// The researcher was fetch-only; this adds the first ANALYSIS stage -- a case-insensitive corpus signal-scan that
3// counts decisive exceed-relevant terms per source (cloud-lock, accessibility, tracking/privacy, open-source,
4// design-tokens, ...). Output grounds an exceed plan in the live data instead of hand-read HTML. Reusable across any
5// `*_research_fetch` corpus. Sovereign (nx_syscalls only). [[feedback-grow-researcher-team-continuously]]
6// license_tier: ORIGINAL
7import "nx_syscalls.nx"
8
9func rs_strlen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
10func rs_lc(c: i64) -> i64 { if c >= 65 { if c <= 90 { return c + 32 } } return c }
11// case-insensitive match of lowercase `kw` at data[i..)
12func rs_match_ci(data: *u8, i: i64, n: i64, kw: *u8, klen: i64) -> i64 {
13 if i + klen > n { return 0 }
14 var j: i64 = 0
15 while j < klen { if rs_lc(data[i+j] as i64) != (kw[j] as i64) { return 0 } j = j + 1 }
16 return 1
17}
18// count (case-insensitive, non-overlapping) occurrences of lowercase `kw` in data[0..n).
19func rs_count(data: *u8, n: i64, kw: *u8) -> i64 {
20 let klen: i64 = rs_strlen(kw)
21 if klen == 0 { return 0 }
22 var c: i64 = 0
23 var i: i64 = 0
24 while i + klen <= n { if rs_match_ci(data, i, n, kw, klen) == 1 { c = c + 1; i = i + klen } else { i = i + 1 } }
25 return c
26}
27// read a fetched source + count keyword occurrences. -1 if the file is missing.
28func rs_scan(path: *u8, kw: *u8) -> i64 {
29 let lp: *i64 = sys_mmap(8) as *i64
30 let data: *u8 = sys_read_file(path, lp)
31 if (data as i64) == 0 { return 0 - 1 }
32 return rs_count(data, lp[0], kw)
33}
34// 1 iff the keyword is present at least `min` times.
35func rs_has(path: *u8, kw: *u8, min: i64) -> i64 { if rs_scan(path, kw) >= min { return 1 } return 0 }