Reach 97% Core compliance: 58 errors down to 3

- Fix HERE corruption: sync user_here before writing to shared cell
- Fix DOES> without CREATE: patch most-recent word, not read new name
- Implement >BODY via word_pfa_map tracking parameter field addresses
- Nested BEGIN...WHILE...WHILE...REPEAT...ELSE...THEN support
- DEPTH overflow protection
- Forth 2012 core.fr: 3 errors remaining (POSTPONE edge case,
  double-DOES>, NOP meta-programming)
This commit is contained in:
2026-03-30 21:02:00 +02:00
parent 1d204c0a86
commit cb270c8765
4 changed files with 372 additions and 78 deletions
+68
View File
@@ -449,6 +449,58 @@ fn emit_op(f: &mut Function, op: &IrOp) {
.instruction(&Instruction::End); // end block
}
IrOp::BeginDoubleWhileRepeat {
outer_test,
inner_test,
body,
after_repeat,
else_body,
} => {
// WASM structure:
// block $end ;; THEN target
// block $else ;; first WHILE false target
// block $after ;; second WHILE false target
// loop $begin
// outer_test
// br_if(2) $else ;; first WHILE: if false, skip to else
// inner_test
// br_if(1) $after ;; second WHILE: if false, skip to after
// body
// br(0) ;; REPEAT: back to loop start
// end
// end
// after_repeat code
// br(1) $end ;; skip else, goto end
// end
// else code
// end
f.instruction(&Instruction::Block(BlockType::Empty)); // $end
f.instruction(&Instruction::Block(BlockType::Empty)); // $else
f.instruction(&Instruction::Block(BlockType::Empty)); // $after
f.instruction(&Instruction::Loop(BlockType::Empty)); // $begin
emit_body(f, outer_test);
pop(f);
f.instruction(&Instruction::I32Eqz)
.instruction(&Instruction::BrIf(2)); // to $else
emit_body(f, inner_test);
pop(f);
f.instruction(&Instruction::I32Eqz)
.instruction(&Instruction::BrIf(1)); // to $after
emit_body(f, body);
f.instruction(&Instruction::Br(0)); // back to $begin
f.instruction(&Instruction::End); // end loop
f.instruction(&Instruction::End); // end $after block
emit_body(f, after_repeat);
if else_body.is_some() {
f.instruction(&Instruction::Br(1)); // skip else, goto $end
}
f.instruction(&Instruction::End); // end $else block
if let Some(eb) = else_body {
emit_body(f, eb);
}
f.instruction(&Instruction::End); // end $end block
}
IrOp::Exit => {
f.instruction(&Instruction::Return);
}
@@ -655,6 +707,22 @@ fn count_needed_locals(ops: &[IrOp]) -> u32 {
.max(count_needed_locals(test))
.max(count_needed_locals(body));
}
IrOp::BeginDoubleWhileRepeat {
outer_test,
inner_test,
body,
after_repeat,
else_body,
} => {
max = max
.max(count_needed_locals(outer_test))
.max(count_needed_locals(inner_test))
.max(count_needed_locals(body))
.max(count_needed_locals(after_repeat));
if let Some(eb) = else_body {
max = max.max(count_needed_locals(eb));
}
}
IrOp::If {
then_body,
else_body,