v-TP3-DEAD-FIXTURES.md 3.9 KB

v-TP3-DEAD-FIXTURES — Summary

Tag: v-TP3-DEAD-FIXTURES Commit: 30f9fae

What changed

  • The 9 fixtures that compiled but never executed (t08_const, t09_if, t10_while, t11_for, t12_repeat, t13_proc, t15_label, t27_localvar, t28_farparam) were rewritten to print observable results. Their .out files were hand-derived from the Pascal semantics, never blessed from machine output. Each now has a behavioural counterpart.

Bugs found and fixed

  1. ParseMul used the same operator code as + (both 1). * therefore emitted ADD; constant folding hid it for constant operands. Now named OpAdd/OpSub/OpMul constants, so levels cannot collide. (t08 and a variable-multiply path)

  2. ParseCmp had > and >= swapped: 9DH = SETGE for > and 9FH = SETG for >=. Boundary cases failed. Fixed, and each CASE arm now carries its mnemonic beside the hex.

  3. REPEAT…UNTIL used JNZ to loop back (condition TRUE), so it behaved like WHILE. Now uses JZ → loop back while condition is FALSE. Verified by i:=0; repeat i:=i+1 until i>5 printing 6 (not 1).

  4. Sibling procedures shared the same parameter namespace. HideLocals relabels a procedure's own symbols to 0FFFFH on close (relabelled, not popped, because symtab[old].resvar holds an index). This prevents cross- procedure collisions and fixes the "two procedures both declare a" case.

Scope decisions and findings

  • Parameter lists require commas; variable lists in this compiler require separate var declarations. ; between params is rejected.
  • A parameter may not shadow a global (DupTest rejects any name found).
  • Call arity capped at 16 arguments; exceeding raises ECompOvf = 99.
  • EmJcc/EmSetcc emit 386-only opcodes (0F 8x/0F 9x) on a 8086 target; invisible to qemu-i386 (which defaults to post-386). Worth trying -cpu 8086 as a future check.

Tests / harness

  • run_all.sh: 12 checks ALL PASS.
  • nonvacuity.sh: 39 ok / 0 failed (includes 5 new cases that mutate each of the four bugs back and require run_com_exec.py to go red on the exact fixture that pins them).
  • Compile matrix: 33 passed / 0 failed.
  • Execution: 30 passed / 0 failed.
  • .COM linker: 30 checked / 0 failed.
  • Runtime entries: 36 passed / 0 failed.
  • t28_farparam references p63/p70 to exercise disp16 encoding but does not assert their runtime values (they are unpassed due to the 16-arg cap). (Later v-TP3-ARGORDER milestone: the frame now follows TP3's "last declared parameter at BP+4" rule, so the same two offsets, +128 and +142, are read through p8 and p1; the encoding this row is about is unchanged.)

Tag placement

v-TP3-DEAD-FIXTURES points to 30f9fae (the work commit). An additional tag v-TP3-COM-IMAGE was placed at 7dada57 (where Linker/ComTest first appeared), because the documentation for that milestone was written later; the reasoning is in the tag message. HEAD is 30f9fae, 17 commits ahead of origin/master, nothing pushed.

What remains (next steps)

  1. 8086 branch/compare lowering: rewrite conditional branches to TP3's excond + JZ rel8 idiom (or try qemu -cpu 8086 first to see the class turn red under an 8086 CPU model). Wide golden blast radius.
  2. CmdRun (R key): in-process 8086 interpreter, cross-validated against qemu on the same images.
  3. String variables (s : string, assignment, writeln(s)).
  4. Nested procedures/recursion, var parameters (SEG:OFF), range/index checks, typed constants, array at use (t14), case subrange labels.
  5. readln of a BYTE (separate xrdbyte / TU_RdByte).
  6. Enforce the 4 KiB code window (error if pc reaches data start).
  7. Harmonise multi-name declarations (both , and ; spellings).
  8. Harden program-header parameter loop against non-advancing input.
  9. FreeDOS as a third opinion (untried).