code wiki / _hdl_build / nx_doc_autoheal.nx

nx_doc_autoheal.nx source

↩ module page · 63 lines · 3888 B

1// nx_doc_autoheal.nx -- the Doctor's autonomous RESOLVE loop. Closes the two halves the team already has 2// (RECALL: the ki- known-issue catalogue; FIX: nx_doc_heal_let) into ONE hands-free pass: given a source that hit 3// the empty-.s symptom AND the diagnostic the runner/compiler emitted, it (1) RECALLs the lesson from the catalogue, 4// (2) ROUTEs to the matching auto-fixer iff the recalled class is one we can fix, (3) APPLIEs the fix, and (4) 5// VERIFIEs the defect is actually gone (static post-condition: no reassigned `let` remains). The real recompile is 6// the caller's next step on the healed bytes -- nesting a full rebuild HERE would trip NX-GATE-NESTED-BUILD (a 7// lesson we recorded), so the safe, honest boundary is decision+transform+postcondition. Honest by construction: 8// no recall -> DAH_UNKNOWN (invents nothing); recalled but not our class / no applicable change -> DAH_NOFIX (does 9// not falsely claim a heal); only a verified-clean rewrite returns DAH_HEALED. license_tier: ORIGINAL 10import "nx_syscalls.nx" 11import "nx_known_issue_store.nx" 12import "nx_doc_heal_let.nx" 13 14const DAH_HEALED: i64 = 1 // recalled + fixed + verified the reassigned-let defect is gone 15const DAH_NOFIX: i64 = 0 // recalled (or off-class) but our auto-fixer had no applicable change -- honest 16const DAH_UNKNOWN: i64 = 0-1 // no lesson recalled -> genuinely novel; resolve invents nothing 17 18func dah_tlen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 19func dah_copy(src: *u8, n: i64, out: *u8, outcap: i64) -> i64 { 20 var c: i64 = 0 21 while c < n { if c < outcap-1 { out[c] = src[c] } c = c + 1 } 22 out[n] = 0 as u8 23 return n 24} 25// 1 if any `let NAME` in src is later REASSIGNED (the post-condition we must clear). Reuses the fixer's own 26// detectors (dhl_isident / dhl_name_at / dhl_is_reassigned) so "fixed" means fixed by the SAME definition. 27func dah_has_reassigned_let(src: *u8, n: i64) -> i64 { 28 let nb: *u8 = sys_mmap(256) 29 var i: i64 = 0 30 while i + 4 <= n { 31 if src[i]==(108 as u8) { if src[i+1]==(101 as u8) { if src[i+2]==(116 as u8) { if src[i+3]==(32 as u8) { 32 var bb: i64 = 0 33 if i==0 { bb=1 } else { if dhl_isident(src[i-1] as i64)==0 { bb=1 } } 34 if bb==1 { 35 var np: i64 = i + 4 36 var sk: i64 = 0 37 while sk==0 { if np<n { if src[np]==(32 as u8) { np=np+1 } else { sk=1 } } else { sk=1 } } 38 let nl: i64 = dhl_name_at(src, n, np, nb) 39 if nl>0 { if dhl_is_reassigned(src, n, nb, nl, np)==1 { return 1 } } 40 } 41 } } } } 42 i = i + 1 43 } 44 return 0 45} 46// the closed loop. diag = the diagnostic the runner/compiler emitted; src = the failing source. out gets the 47// healed source (or an unchanged copy when we cannot fix); outid/outrem get the recalled lesson id + remedy. 48func dah_resolve(diag: *u8, dlen: i64, src: *u8, n: i64, out: *u8, outcap: i64, outid: *u8, outrem: *u8) -> i64 { 49 let ostat: *u8 = sys_mmap(64) 50 let r: i64 = ki_recall(KI_PREFIX, diag, dlen, outid, outrem, ostat) 51 if r != KI_HIT { dah_copy(src, n, out, outcap); return DAH_UNKNOWN } 52 // ROUTE: only the empty-.s / let-reassign class is one our auto-fixer handles. 53 var ours: i64 = 0 54 if ki_substr(outid, dah_tlen(outid), "EMPTYS" as *u8, 6) >= 0 { ours = 1 } 55 if ki_substr(outid, dah_tlen(outid), "LET-REASSIGN" as *u8, 12) >= 0 { ours = 1 } 56 if ours == 0 { dah_copy(src, n, out, outcap); return DAH_NOFIX } 57 // APPLY the let-reassign fixer. 58 let changes: i64 = dhl_heal(src, n, out, outcap) 59 if changes <= 0 { return DAH_NOFIX } // off-sub-case (e.g. reserved-kw): honest no-claim 60 // VERIFY the defect is actually gone before claiming a heal. 61 if dah_has_reassigned_let(out, dah_tlen(out)) == 0 { return DAH_HEALED } 62 return DAH_NOFIX 63}