From d5ba699744e6a434dfd728ff45cc12b868c7c715 Mon Sep 17 00:00:00 2001 From: Sebastian Jeong Date: Mon, 17 Aug 2026 02:26:02 +0900 Subject: [PATCH] dev: require the pinned toolchain, and clear the QEMU-era leftovers The host gate accepted a WATCOM environment override and skipped when nothing was found. Both are wrong for what it is: a system-wide Open Watcom is a different version reporting different diagnostics, and a gate that skips is a gate that is not running, which is the exact shape of the problem this file was added to close. It now uses .dosboxx/watcom only and fails with the setup command when that is absent, matching how dosboxx.py already behaves. Nothing else in the project reaches for a system install: the DOS session sets WATCOM=W: before calling BUILD.BAT, so the C:\DEVEL\WATCOMC fallback inside it is unreachable. fec/test-dos.bat was tracked but dead -- the runner generates RUN.BAT and only copies build-dos.bat -- so it goes, along with the comment claiming it drives the build and the three fixture READMEs that still pointed at it. The registry decides what runs now. (.qemu/ is untracked local debris from the same era and is left alone.) --- fec/build-dos.bat | 2 +- fec/test-dos.bat | 288 -------------------------------- fec/tests/m6/README.md | 2 +- fec/tests/m7/README.md | 2 +- fec/tests/m8/README.md | 2 +- tools/tests/test_host_syntax.py | 32 ++-- 6 files changed, 19 insertions(+), 309 deletions(-) delete mode 100644 fec/test-dos.bat diff --git a/fec/build-dos.bat b/fec/build-dos.bat index 733cbea..e8c1178 100644 --- a/fec/build-dos.bat +++ b/fec/build-dos.bat @@ -1,5 +1,5 @@ @echo off -rem Open Watcom C89 build. TEST-DOS.BAT runs this from C:\FEC. +rem Open Watcom C89 build. The runner's generated RUN.BAT calls this from C:\FEC. C: cd \FEC if exist BUILD.OK del BUILD.OK diff --git a/fec/test-dos.bat b/fec/test-dos.bat deleted file mode 100644 index bdd2d15..0000000 --- a/fec/test-dos.bat +++ /dev/null @@ -1,288 +0,0 @@ -@echo off -rem FreeDOS smoke tests. All work happens on the writable C: drive. -C: -cd \FEC -if exist TEST.OK del TEST.OK -if exist TEST.FAIL del TEST.FAIL -call C:\FEC\BUILD.BAT -if not exist BUILD.OK goto test_fail -if "%WATCOM%"=="" set WATCOM=C:\DEVEL\WATCOMC -if not exist %WATCOM%\BINW\WCL.EXE goto test_fail -if not exist %WATCOM%\BINW\WCL386.EXE goto test_fail -set PATH=%WATCOM%\BINW;%WATCOM%\BINP;%PATH% - -fec.exe --dump-ast TESTS\PASS\BASIC.FE > nul -if errorlevel 1 goto test_fail -fec.exe --dump-ast TESTS\PASS\LITERALS.FE > nul -if errorlevel 1 goto test_fail -fec.exe --dump-ast TESTS\PASS\KEYBUILT.FE > nul -if errorlevel 1 goto test_fail -fec.exe --dump-ast TESTS\PASS\V012FORM.FE > nul -if errorlevel 1 goto test_fail - -fec.exe --dump-ast STD\CORE.FE > nul -if errorlevel 1 goto test_fail -fec.exe --dump-ast STD\FMT.FE > nul -if errorlevel 1 goto test_fail -fec.exe --dump-ast STD\IO.FE > nul -if errorlevel 1 goto test_fail -fec.exe --dump-ast STD\LIST.FE > nul -if errorlevel 1 goto test_fail -fec.exe --dump-ast STD\MAP.FE > nul -if errorlevel 1 goto test_fail -fec.exe --dump-ast STD\MEM.FE > nul -if errorlevel 1 goto test_fail -fec.exe --dump-ast STD\STR.FE > nul -if errorlevel 1 goto test_fail -fec.exe --dump-ast STD\SYS.FE > nul -if errorlevel 1 goto test_fail - -fec.exe --dump-ast TESTS\FAIL\MISSSEMI.FE > nul -if not errorlevel 1 goto test_fail -fec.exe --dump-ast TESTS\FAIL\UNCLCOMM.FE > nul -if not errorlevel 1 goto test_fail -fec.exe --dump-ast TESTS\FAIL\LOGICAL.FE > nul -if not errorlevel 1 goto test_fail - -if exist TESTS\M2\HELLO.C del TESTS\M2\HELLO.C -if exist TESTS\M2\HELLO.EXE del TESTS\M2\HELLO.EXE -if exist TESTS\M2\SCOPES.C del TESTS\M2\SCOPES.C -if exist TESTS\M2\SCOPES.EXE del TESTS\M2\SCOPES.EXE -if exist TESTS\M2\CAST16.C del TESTS\M2\CAST16.C -if exist TESTS\M2\CAST16.EXE del TESTS\M2\CAST16.EXE - -rem M2 bits32 path: Open Watcom 32-bit compiler and DOS extender executable. -fec.exe --target=bits32 --emit-c TESTS\M2\HELLO.FE -o TESTS\M2\HELLO.C > nul -if errorlevel 1 goto test_fail -wcl386 -q -za -bt=dos -fe=TESTS\M2\HELLO.EXE TESTS\M2\HELLO.C -if errorlevel 1 goto test_fail -TESTS\M2\HELLO.EXE -if errorlevel 1 goto test_fail - -fec.exe --target=bits32 --emit-c TESTS\M2\SCOPES.FE -o TESTS\M2\SCOPES.C > nul -if errorlevel 1 goto test_fail -wcl386 -q -za -bt=dos -fe=TESTS\M2\SCOPES.EXE TESTS\M2\SCOPES.C -if errorlevel 1 goto test_fail -TESTS\M2\SCOPES.EXE -if errorlevel 1 goto test_fail - -rem M2 bits16 regression path remains on compiler A (wcl). -fec.exe --target=bits16 --emit-c TESTS\M2\CASTWHIL.FE -o TESTS\M2\CAST16.C > nul -if errorlevel 1 goto test_fail -wcl -q -za -bt=dos -fe=TESTS\M2\CAST16.EXE TESTS\M2\CAST16.C -if errorlevel 1 goto test_fail -TESTS\M2\CAST16.EXE -if errorlevel 1 goto test_fail - -fec.exe --target=bits32 --emit-c TESTS\M2\BAD-COND.FE -o TESTS\M2\BAD-CO.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M2\BAD-CAST.FE -o TESTS\M2\BAD-CA.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M2\BAD-ASGN.FE -o TESTS\M2\BAD-AS.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M2\BAD-UNK.FE -o TESTS\M2\BAD-UN.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M2\BAD-ARI.FE -o TESTS\M2\BAD-AR.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M2\BAD-TYPE.FE -o TESTS\M2\BAD-TY.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M2\BAD-RET.FE -o TESTS\M2\BAD-RE.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M2\BAD-UNIT.FE -o TESTS\M2\BAD-UI.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M2\BAD-VOID.FE -o TESTS\M2\BAD-VO.C > nul -if not errorlevel 1 goto test_fail - -if exist TESTS\M3\STRUCT.C del TESTS\M3\STRUCT.C -if exist TESTS\M3\STRUCT.EXE del TESTS\M3\STRUCT.EXE -if exist TESTS\M3\ENUM.C del TESTS\M3\ENUM.C -if exist TESTS\M3\ENUM.EXE del TESTS\M3\ENUM.EXE -if exist TESTS\M3\ARRAY.C del TESTS\M3\ARRAY.C -if exist TESTS\M3\ARRAY.EXE del TESTS\M3\ARRAY.EXE -if exist TESTS\M3\STR.C del TESTS\M3\STR.C -if exist TESTS\M3\STR.EXE del TESTS\M3\STR.EXE -if exist TESTS\M3\FOR.C del TESTS\M3\FOR.C -if exist TESTS\M3\FOR.EXE del TESTS\M3\FOR.EXE -if exist TESTS\M3\NESTED.C del TESTS\M3\NESTED.C -if exist TESTS\M3\NESTED.EXE del TESTS\M3\NESTED.EXE -if exist TESTS\M3\CHAR.C del TESTS\M3\CHAR.C -if exist TESTS\M3\CHAR.EXE del TESTS\M3\CHAR.EXE -if exist TESTS\M3\ARRAYCTX.C del TESTS\M3\ARRAYCTX.C -if exist TESTS\M3\ARRAYCTX.EXE del TESTS\M3\ARRAYCTX.EXE -if exist TESTS\M3\BOUNDS.C del TESTS\M3\BOUNDS.C -if exist TESTS\M3\BOUNDS.EXE del TESTS\M3\BOUNDS.EXE -if exist TESTS\M3\BOUNDS-N.C del TESTS\M3\BOUNDS-N.C -if exist TESTS\M3\BOUNDS-N.EXE del TESTS\M3\BOUNDS-N.EXE - -fec.exe --target=bits32 --emit-c TESTS\M3\STRUCT.FE -o TESTS\M3\STRUCT.C > nul -if errorlevel 1 goto test_fail -wcl386 -q -za -bt=dos -fe=TESTS\M3\STRUCT.EXE TESTS\M3\STRUCT.C -if errorlevel 1 goto test_fail -TESTS\M3\STRUCT.EXE -if errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M3\ENUM.FE -o TESTS\M3\ENUM.C > nul -if errorlevel 1 goto test_fail -wcl386 -q -za -bt=dos -fe=TESTS\M3\ENUM.EXE TESTS\M3\ENUM.C -if errorlevel 1 goto test_fail -TESTS\M3\ENUM.EXE -if errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M3\ARRAY.FE -o TESTS\M3\ARRAY.C > nul -if errorlevel 1 goto test_fail -wcl386 -q -za -bt=dos -fe=TESTS\M3\ARRAY.EXE TESTS\M3\ARRAY.C -if errorlevel 1 goto test_fail -TESTS\M3\ARRAY.EXE -if errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M3\MUTABLE.FE -o TESTS\M3\MUTABLE.C > nul -if errorlevel 1 goto test_fail -wcl386 -q -za -bt=dos -fe=TESTS\M3\MUTABLE.EXE TESTS\M3\MUTABLE.C -if errorlevel 1 goto test_fail -TESTS\M3\MUTABLE.EXE -if errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M3\BAD-MLET.FE -o TESTS\M3\BAD-MLET.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M3\BAD-SHWR.FE -o TESTS\M3\BAD-SHWR.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M3\STR.FE -o TESTS\M3\STR.C > nul -if errorlevel 1 goto test_fail -wcl386 -q -za -bt=dos -fe=TESTS\M3\STR.EXE TESTS\M3\STR.C -if errorlevel 1 goto test_fail -TESTS\M3\STR.EXE -if errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M3\FOR.FE -o TESTS\M3\FOR.C > nul -if errorlevel 1 goto test_fail -wcl386 -q -za -bt=dos -fe=TESTS\M3\FOR.EXE TESTS\M3\FOR.C -if errorlevel 1 goto test_fail -TESTS\M3\FOR.EXE -if errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M3\NESTED.FE -o TESTS\M3\NESTED.C > nul -if errorlevel 1 goto test_fail -wcl386 -q -za -bt=dos -fe=TESTS\M3\NESTED.EXE TESTS\M3\NESTED.C -if errorlevel 1 goto test_fail -TESTS\M3\NESTED.EXE -if errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M3\CHAR.FE -o TESTS\M3\CHAR.C > nul -if errorlevel 1 goto test_fail -wcl386 -q -za -bt=dos -fe=TESTS\M3\CHAR.EXE TESTS\M3\CHAR.C -if errorlevel 1 goto test_fail -TESTS\M3\CHAR.EXE -if errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M3\ARRAYCTX.FE -o TESTS\M3\ARRAYCTX.C > nul -if errorlevel 1 goto test_fail -wcl386 -q -za -bt=dos -fe=TESTS\M3\ARRAYCTX.EXE TESTS\M3\ARRAYCTX.C -if errorlevel 1 goto test_fail -TESTS\M3\ARRAYCTX.EXE -if errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M3\BOUNDS.FE -o TESTS\M3\BOUNDS.C > nul -if errorlevel 1 goto test_fail -wcl386 -q -za -bt=dos -fe=TESTS\M3\BOUNDS.EXE TESTS\M3\BOUNDS.C -if errorlevel 1 goto test_fail -TESTS\M3\BOUNDS.EXE -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M3\SLCBOUND.FE -o TESTS\M3\SLCBOUND.C > nul -if errorlevel 1 goto test_fail -wcl386 -q -za -bt=dos -fe=TESTS\M3\SLCBOUND.EXE TESTS\M3\SLCBOUND.C -if errorlevel 1 goto test_fail -TESTS\M3\SLCBOUND.EXE -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --no-checks --emit-c TESTS\M3\BOUNDS.FE -o TESTS\M3\BOUNDS-N.C > nul -if errorlevel 1 goto test_fail -wcl386 -q -za -bt=dos -fe=TESTS\M3\BOUNDS-N.EXE TESTS\M3\BOUNDS-N.C -if errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M3\BADFLD.FE -o TESTS\M3\BADFLD.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M3\BADMAT.FE -o TESTS\M3\BADMAT.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M3\BADARR.FE -o TESTS\M3\BADARR.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M3\BADCYCLE.FE -o TESTS\M3\BADCYCLE.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M3\BADSTR.FE -o TESTS\M3\BADSTR.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M3\BADCHAR.FE -o TESTS\M3\BADCHAR.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M3\BADFIELD.FE -o TESTS\M3\BADFIELD.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M3\BADINDEX.FE -o TESTS\M3\BADINDEX.C > nul -if not errorlevel 1 goto test_fail - -if exist TESTS\M4\FORMAT.C del TESTS\M4\FORMAT.C -if exist TESTS\M4\FORMAT.EXE del TESTS\M4\FORMAT.EXE -fec.exe --target=bits32 --emit-c TESTS\M4\FORMAT.FE -o TESTS\M4\FORMAT.C > nul -if errorlevel 1 goto test_fail -wcl386 -q -za -wx -wcd=202 -bt=dos -fe=TESTS\M4\FORMAT.EXE TESTS\M4\FORMAT.C -if errorlevel 1 goto test_fail -TESTS\M4\FORMAT.EXE > nul -if errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M4\TRY-FPR.FE -o TESTS\M4\TRY-FPR.C > nul -if errorlevel 1 goto test_fail -wcl386 -q -za -wx -wcd=202 -bt=dos -fe=TESTS\M4\TRY-FPR.EXE TESTS\M4\TRY-FPR.C -if errorlevel 1 goto test_fail -TESTS\M4\TRY-FPR.EXE > nul -if errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M4\PROP.FE -o TESTS\M4\PROP.C > nul -if errorlevel 1 goto test_fail -wcl386 -q -za -wx -wcd=202 -bt=dos -fe=TESTS\M4\PROP.EXE TESTS\M4\PROPTEST.C -if errorlevel 1 goto test_fail -TESTS\M4\PROP.EXE > nul -if errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M4\BAD-ARI.FE -o TESTS\M4\BAD-ARI.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M4\BAD-VERB.FE -o TESTS\M4\BAD-VERB.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M4\BAD-RUN.FE -o TESTS\M4\BAD-RUN.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M4\BAD-TYPE.FE -o TESTS\M4\BAD-TYP.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M4\BAD-TRY.FE -o TESTS\M4\BAD-TRY.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M4\BAD-WRIT.FE -o TESTS\M4\BAD-WRI.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M4\BAD-BUFW.FE -o TESTS\M4\BAD-BUFW.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M4\BAD-MANY.FE -o TESTS\M4\BAD-MANY.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M4\BAD-OPEN.FE -o TESTS\M4\BAD-OPEN.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M4\BAD-CLS.FE -o TESTS\M4\BAD-CLS.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M5\DEFER.FE -o TESTS\M5\DEFER.C > nul -if errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M5\OWNED.FE -o TESTS\M5\OWNED.C > nul -if errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M5\BAD-MOVE.FE -o TESTS\M5\BAD-MOVE.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M5\BAD-DEST.FE -o TESTS\M5\BAD-DES.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M5\BAD-DROP.FE -o TESTS\M5\BAD-DROP.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M5\BAD-DBL.FE -o TESTS\M5\BAD-DBL.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M5\BAD-COND.FE -o TESTS\M5\BAD-COND.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M5\BAD-PROJ.FE -o TESTS\M5\BAD-PROJ.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M5\BAD-CLOS.FE -o TESTS\M5\BAD-CLOS.C > nul -if not errorlevel 1 goto test_fail -fec.exe --target=bits32 --emit-c TESTS\M5\BAD-LOOP.FE -o TESTS\M5\BAD-LOOP.C > nul -if not errorlevel 1 goto test_fail -if exist TESTS\M5\RUNT-G.C del TESTS\M5\RUNT-G.C -if exist TESTS\M5\RUNTIME.O del TESTS\M5\RUNTIME.O -if exist TESTS\M5\RUNTIME.EXE del TESTS\M5\RUNTIME.EXE -fec.exe --target=bits32 --emit-c TESTS\M5\RUNTIME.FE -o TESTS\M5\RUNT-G.C > nul -if errorlevel 1 goto test_fail -rem Compile generated source and the C89 runtime harness in one WCL386 invocation -rem so both objects use the same DOS/4GW startup and runtime library. -wcl386 -q -za -bt=dos -dmalloc=m5_malloc -dfree=m5_free -fe=TESTS\M5\RUNTIME.EXE TESTS\M5\RUNT-G.C TESTS\M5\RUNTIME.C -if errorlevel 1 goto test_fail -TESTS\M5\RUNTIME.EXE -if errorlevel 1 goto test_fail - -echo OK>TEST.OK -cd C:\FEC -goto test_done - -:test_fail -echo FAIL>TEST.FAIL -verify other 2>nul - -:test_done diff --git a/fec/tests/m6/README.md b/fec/tests/m6/README.md index 743005f..3d0fcd7 100644 --- a/fec/tests/m6/README.md +++ b/fec/tests/m6/README.md @@ -4,7 +4,7 @@ These fixtures pin the M6 ownership/borrow rules before implementation. - `ok*.fe` must compile with `--target=bits32 --emit-c`. - `bad*.fe` must fail compilation; the first line follows the `// ERROR::` convention from SPEC ยง12. -- They are intentionally not wired into `TEST-DOS.BAT` while `master` is M5, so adding these fixtures does not make the current milestone red. +- They are registered in `src/ferrolang_vm/registry.py`, which is what decides whether a milestone runs. - When M6 starts, wire this directory into the DOS/QEMU gate without changing the expected result of any fixture. - M6 also owns the general-global borrow restriction from R10 because AGENTS.md explicitly groups that change with the `own.c` state-machine work. diff --git a/fec/tests/m7/README.md b/fec/tests/m7/README.md index 3679b4b..237a2e6 100644 --- a/fec/tests/m7/README.md +++ b/fec/tests/m7/README.md @@ -3,6 +3,6 @@ M7 adds optionals and error unions on top of the M6 ownership model. `ok*.fe` must compile. `bad*.fe` must fail according to the first-line error marker. -The files are not wired into `TEST-DOS.BAT` until M7 work begins. +The files are registered in `src/ferrolang_vm/registry.py`. Coverage: contextual `null`, `?T`, `.?`, `Some`/`None` pattern-only non-destructive views, `mem.replace` extraction, lazy `orelse`/`catch`, nominal error unions, `try`, block/short `catch`, and error code/name uniqueness, plus R4/R7 interactions with optional references/owners. diff --git a/fec/tests/m8/README.md b/fec/tests/m8/README.md index 6271483..c5ac55b 100644 --- a/fec/tests/m8/README.md +++ b/fec/tests/m8/README.md @@ -21,6 +21,6 @@ Fail cases: - `pubpriv`: a public signature cannot expose a private nominal type. - `errnom`: nominal error cannot flow into `core.Error` via `try`. -The current M5 `TEST-DOS.BAT` is intentionally unchanged. M8 should add procedural checks for `.fei` creation/hash invalidation and deterministic `fe_errors.h` using these fixtures. +They are not registered in `src/ferrolang_vm/registry.py` yet. M8 should add procedural checks for `.fei` creation/hash invalidation and deterministic `fe_errors.h` using these fixtures. The M8 DOS gate must additionally construct two separate `-I` roots containing the same canonical unit and require an ambiguity error; repeat the case with two paths to the same canonical file and require deduplication. It must also verify that `std.*` resolves only from the built-in std root, ordinary user units never do, and that changing a private non-generic implementation preserves the dependent interface-cache hit. Those checks need temporary roots/cache inspection and deliberately remain procedural rather than encoding host paths in fixtures. diff --git a/tools/tests/test_host_syntax.py b/tools/tests/test_host_syntax.py index 8fb4972..69a3e2b 100644 --- a/tools/tests/test_host_syntax.py +++ b/tools/tests/test_host_syntax.py @@ -17,13 +17,14 @@ What it still cannot see is the DOS environment itself -- memory limits, the command line length, the filesystem. The DOS build and the milestone suite remain the gate. -Skipped when the toolchain has not been downloaded, so the suite runs anywhere. +It uses the pinned toolchain only. There is no environment override and no +skip: a system-wide Watcom is a different version reporting different things, +and a gate that quietly skips is not a gate. """ from __future__ import annotations import os import re -import shutil import subprocess from pathlib import Path @@ -37,23 +38,20 @@ SOURCES = ("arena", "diag", "lexer", "ast", "parser", "types", "m7", "own", "check", "lower", "emit_c", "driver") -def _watcom() -> Path | None: - """Prefer the toolchain the runner pins over anything installed system-wide.""" - root = os.environ.get("WATCOM") - candidates = [ROOT / ".dosboxx" / "watcom"] - if root: - candidates.append(Path(root)) - for base in candidates: - if (base / "binnt" / "wcl.exe").is_file(): - return base - return None - - @pytest.fixture(scope="session") def watcom() -> Path: - base = _watcom() - if base is None: - pytest.skip("run `ferro-dos setup` to download the pinned toolchain") + """The pinned toolchain, and nothing else. + + Deliberately no environment override and no skip. A system-wide Open Watcom + is a different version with different diagnostics, and a gate that skips is + a gate that is not running -- which is the failure mode this file exists to + close. dosboxx.py fails the same way when the toolchain is missing. + """ + base = ROOT / ".dosboxx" / "watcom" + if not (base / "binnt" / "wcl.exe").is_file(): + raise AssertionError( + f"the pinned Open Watcom is not at {base}; " + "run `uv run ferro-dos setup --accept-watcom-license`") return base