#!/usr/bin/env node /** * test-named-let-set.js — WASM kernel tests for set! inside named let loops. * * FAILING: set! inside named let body does not persist mutations to * the enclosing scope. This breaks tokenize-sx → highlight → source display. */ const { createSxEnv } = require('./sx-harness'); let passed = 0, failed = 0; const origLog = console.log; const origErr = console.error; function test(name, expr, expected) { let env; try { // Fresh env per test to avoid cross-contamination // But creating env is slow, so we'll reuse one below } catch(e) {} } async function main() { origLog('=== Named Let + set! Tests (WASM kernel) ===\n'); const t0 = Date.now(); const env = await createSxEnv({}); function check(name, expr, expected) { const result = env.eval(expr); const expectedStr = JSON.stringify(expected); const resultVal = result?.items ? result.items : result; const resultStr = JSON.stringify(resultVal); if (resultStr === expectedStr) { passed++; origLog(` \u2713 ${name}`); } else { failed++; origErr(` \u2717 ${name}: expected ${expectedStr}, got ${resultStr}`); } } // ---- Baselines (should pass) ---- origLog('Baselines:'); check('set! in plain let', '(let ((x 0)) (set! x 42) x)', 42); check('named let without set! (functional accumulator)', '(trampoline (let loop ((i 0) (acc 0)) (if (< i 5) (loop (+ i 1) (+ acc i)) acc)))', 10); check('append! on outer binding (no named let)', '(let ((xs (list))) (append! xs 1) (append! xs 2) xs)', [1, 2]); // ---- Named let + set! (the broken cases) ---- origLog('\nNamed let + set!:'); check('set! counter in named let loop', '(let ((x 0)) (let loop () (when (< x 5) (set! x (+ x 1)) (loop))) x)', 5); check('set! counter in named let loop (with param)', '(let ((total 0)) (let loop ((i 1)) (when (<= i 10) (set! total (+ total i)) (loop (+ i 1)))) total)', 55); check('set! list via append in named let', '(let ((acc (list))) (let loop ((i 0)) (when (< i 3) (set! acc (append acc (list i))) (loop (+ i 1)))) acc)', [0, 1, 2]); check('append! in named let', '(let ((acc (list)) (i 0)) (let loop () (when (< i 3) (append! acc i) (set! i (+ i 1)) (loop))) acc)', [0, 1, 2]); check('set! string concat in named let', '(let ((result "")) (let loop ((i 0)) (when (< i 3) (set! result (str result (str i))) (loop (+ i 1)))) result)', "012"); // ---- Nested named let ---- origLog('\nNested:'); check('set! in nested named let', '(let ((count 0)) (let outer ((i 0)) (when (< i 3) (let inner ((j 0)) (when (< j 2) (set! count (+ count 1)) (inner (+ j 1)))) (outer (+ i 1)))) count)', 6); env.close(); const dt = Date.now() - t0; origLog(`\n=== ${passed} passed, ${failed} failed (${dt}ms) ===`); process.exit(failed > 0 ? 1 : 0); } main().catch(e => { origErr(e); process.exit(1); });