selfhost/runtime: Stage 0-1 runner + MIR JSON loader (summary) with trace; compiler: scopebox/loopform prepass wiring (flags, child args); libs: add P1 standard boxes (console/string/array/map) as thin wrappers; runner: pass --box-pref via env; ops_calls dispatcher skeleton; docs: selfhost executor roadmap + scopebox/loopform notes; smokes: selfhost runner + identity prepasses; CURRENT_TASK: update plan and box lib schedule

This commit is contained in:
Selfhosting Dev
2025-09-22 21:52:39 +09:00
parent b00dc4ec37
commit da78fc174b
72 changed files with 3163 additions and 2557 deletions

View File

@ -0,0 +1,65 @@
#[cfg(test)]
mod tests {
use crate::parser::NyashParser;
use crate::mir::MirInstruction;
// Regression for predecessor mis-selection on nested if inside loop in PHI-off mode
// Path: cond == true && cond2 == false should observe inner else assignment at merge.
#[test]
fn nested_if_inside_loop_edges_copy_from_exiting_blocks() {
// Force PHI-off
std::env::set_var("NYASH_MIR_NO_PHI", "1");
let code = r#"
x = 0
i = 0
loop (i < 1) {
i = i + 1
if (1 == 1) {
if (1 == 0) {
x = 1
} else {
x = 2
}
}
}
return x
"#;
let ast = NyashParser::parse_from_string(code).expect("parse");
let mut compiler = crate::mir::MirCompiler::new();
let result = compiler.compile(ast).expect("compile");
// Find return block/value id
let f = result.module.functions.get("main").expect("main");
let (ret_block, out_v) = f
.blocks
.iter()
.find_map(|(bid, bb)| match &bb.terminator {
Some(MirInstruction::Return { value: Some(v) }) => Some((*bid, *v)),
_ => None,
})
.expect("ret block");
// Every predecessor must carry a Copy to the merged value in PHI-off mode
let preds: Vec<_> = f.blocks.get(&ret_block).unwrap().predecessors.iter().copied().collect();
assert!(!preds.is_empty(), "ret must have predecessors");
for p in preds {
let bb = f.blocks.get(&p).unwrap();
let has_copy = bb
.instructions
.iter()
.any(|inst| matches!(inst, MirInstruction::Copy { dst, .. } if *dst == out_v));
assert!(has_copy, "missing Copy to merged value in predecessor {:?}", p);
}
// ret block must not contain Copy to out_v
let merge_has_copy = f
.blocks
.get(&ret_block)
.unwrap()
.instructions
.iter()
.any(|inst| matches!(inst, MirInstruction::Copy { dst, .. } if *dst == out_v));
assert!(!merge_has_copy, "merge/ret must not contain Copy to merged value");
}
}