Fix LEAVE+LOOP hang, DEPTH off-by-one, division flavor, EVALUATE, WORD, ACCEPT

Six fixes for compliance test regressions introduced in Phases 7-8:

- LEAVE + +LOOP with step=0 caused infinite loop: the XOR termination
  check yields 0 when index=limit and step=0. Added SYSVAR_LEAVE_FLAG
  mechanism — LEAVE sets flag, +LOOP checks it, all loops clear on exit.

- DEPTH was off-by-one: `5440 SP@ -` pushed the literal before SP@
  read the stack pointer, making SP@ see one extra cell. Reordered to
  `SP@ 5440 SWAP -` so SP@ reads dsp before any literal push.

- */ and */MOD used FM/MOD (floored) but WAFER's / uses WASM i32.div_s
  (symmetric). Changed to SM/REM for consistency.

- EVALUATE didn't sync input buffer to WASM memory, breaking SOURCE
  and >IN manipulation inside evaluated strings. Added input-only sync
  (without touching STATE/BASE) and >IN readback after each token.

- WORD didn't skip leading spaces when delimiter != space, causing
  GN' and GS3 tests to read whitespace instead of content.

- Added ACCEPT stub returning 0 for non-interactive mode.

- Added bounds check in refresh_user_here to reject corrupted
  SYSVAR_HERE values beyond WASM memory size.

Core and Facility compliance suites now pass. Other suites have
pre-existing regressions from Phases 1-8 still under investigation.
This commit is contained in:
2026-04-07 20:30:16 +02:00
parent b7256e3130
commit 4bfe6976ee
4 changed files with 142 additions and 20 deletions
+3
View File
@@ -86,6 +86,8 @@ pub const SYSVAR_SOURCE_ID: u32 = SYSVAR_BASE + 20;
pub const SYSVAR_NUM_TIB: u32 = SYSVAR_BASE + 24;
/// HLD: pointer for pictured numeric output.
pub const SYSVAR_HLD: u32 = SYSVAR_BASE + 28;
/// LEAVE flag: nonzero when LEAVE has been called inside a DO loop.
pub const SYSVAR_LEAVE_FLAG: u32 = SYSVAR_BASE + 32;
#[cfg(test)]
mod tests {
@@ -125,6 +127,7 @@ mod tests {
SYSVAR_SOURCE_ID,
SYSVAR_NUM_TIB,
SYSVAR_HLD,
SYSVAR_LEAVE_FLAG,
];
for offset in all_offsets {
assert!(offset >= SYSVAR_BASE);