# TP3-comp Recreating **Turbo Pascal 3.0** (shell, editor, compiler, interpreter) in **GNU Modula-2** (`-fiso`). Faithful to the original: the screen layout, keys and behaviours are reconstructed from the disassembled TP3.0 source (`Resources/`) and the reference manual. ## State **Where things are: `SUMMARY.md`.** It holds the milestone table, the list of checks and what each one cannot see, and the numbers behind every claim. There used to be a milestone table here as well, and it drifted six milestones behind while still reading as authoritative: it said "no compiled program has been executed yet" and "`CmdRun` is a stub and the runtime blob does not exist" through five tagged milestones in which those three things all became true. A second copy of a status table is a claim about the world that expires silently and is never noticed expiring, so there is one now, and this file says where it is. In short, current as of `v-TP3-DEAD-FIXTURES`: - The shell and the WordStar-style editor are done. - The compiler front end and 8086 code generator are done for the language subset the fixtures cover, and the emitted `.COM` images **run**: 31 fixtures boot in `qemu-system-i386` and print exactly their expected bytes, and 36 further cases call the runtime's own entries directly. - **The shell's `R` key is still a stub.** There is no in-process 8086 interpreter, so nothing runs a `.COM` from inside `tpshell` itself; execution happens only under the test harness. - `string` *variables*, nested procedures, `var` parameters, range and index checks, typed constants and `array` at its point of use are not implemented. `SUMMARY.md` lists them with the reason for each. ## Build Requires GNU Modula-2 (`gm2`, tested with 16.0.1) and a C compiler for the `FOR "C"` bridge. ```sh cd shell make ./tpshell ``` The shell runs in raw mode: it needs a real ANSI terminal, no wrappers. To run the checks: `cd shell && bash tests/run_all.sh`. It is not part of `make`, because it needs qemu and takes a few minutes. ## Layout - `shell/Term.def|mod` — raw termios keyboard + ANSI screen primitives (blocking `GetCh`, non-blocking `Avail`/`GetKey` via `poll`, `GotoXY`, highlight `Marked`/`Normal`, `Beep`). - `shell/Posix.def|Posix.c` — `DEFINITION MODULE FOR "C"` bridge to libc: read/write/open/close/unlink/rename/getcwd/chdir/opendir/readdir/closedir/ statvfs/poll and termios (`tcgetattr`/`tcsetattr`/`cfmakeraw`). - `shell/TextBuf.def|mod` — the shared TP3-style text buffer: a 62903-char array, lines terminated by CR. Text is kept in memory so the editor and the shell's S (save) operate on the same buffer. - `shell/Editor.def|mod` — WordStar-style full-screen editor. - `shell/Shell.mod` — TP3.0 main-menu dispatcher (`kmenu`/`kcmdtab`), work-file load/save with `.BAK` rotation, directory listing, options menu. - `shell/Compiler.def|mod` — lexer, parser, symbol table and the 8086 code generator. `Compiler.CodeByteAt` exists so a test can read the emitted image. - `shell/Runtime.def|mod` — the 8086 runtime library, built as a byte blob at run time and copied to the front of every image. Its entries are addressed by name from `Runtime.def`; the emitter procedures are audited name-against-decode. - `shell/Linker.def|mod` — assembles `[JMP rel16][runtime][header][program]` and writes a real DOS `.COM` when the Destination option is `COM`. - `shell/Makefile` — the authoritative build recipe; two-phase link, see `SUMMARY.md`. - `shell/tests/` — the harnesses. `run_all.sh` runs them, `nonvacuity.sh` proves each one can go red. `tests/fixtures/expected.tsv` is the live fixture matrix and is asserted against, not copied into prose. - `SUMMARY.md` — **the state document**: milestones, checks, numbers, and what is still missing. - `TP3-COMPILER.md` — how the compiler works, the build recipe, and the codegen bug classes with their fixes. - `TP3-EDITOR.md` — the editor's key handling and screen layout. - `RESUME-TP3.md` — book-derived reference for the 8086 code the TP3 compiler generates (source of the compiler phase). - `Resources/` — OCR of "Au coeur de Turbo Pascal", TP3.0 manual and the disassembled TPSRC1-10. **The disassembly is the ground truth**: when our behaviour and the book disagree, the disassembly wins. ## Shell (TP3.0 main menu) Exact TP3.0 screen: `Logged drive`, `Active directory`, `Work file`, `Main file`, `Edit Compile Run Save` / `Dir Quit compiler Options`, `Text: n bytes`, `Free: n bytes`, `>` prompt. Command letters are drawn bold (TP3 uses high-bit characters). | Key | Action | |---|---| | `L` | new drive / directory | | `A` | new active directory | | `W` | set work file (auto-`.PAS`), `Loading`/`New File` | | `M` | set main file | | `E` | edit work file | | `C` | compile (wired: TP3 error report + editor jumps to the error) | | `R` | run — **stub**, prints `Interpreter pending - compiled code is in memory` | | `S` | save with `^Z` EOF; old version → `.BAK` | | `D` | directory listing, DOS `*.*` mask, `k bytes free` | | `O` | options submenu (compile target, Code/Data/Stack, params) | | `Q` | quit (prompts to save when text changed) | Any other key redraws the menu, like TP3. ## Editor WordStar-style full-screen editing over `TextBuf`. Status line: `Line n Col n Insert/Overwrite Indent X:FILENAME`. Text rows are screen rows 2–24; row 1 carries status/prompt/messages. Highlights: - Movement — ^S/^D/^E/^X/^A/^F/^R/^C/^W/^Z and ^Q S/D/E/X/R/C/B/K/P, arrow keys / PgUp / PgDn / Home / End (ANSI escape sequences). - Editing — insert/overwrite (^V), ^G delete char, backspace joins lines, ^T word, ^Y line, ^Q-Y to end of line, ^N / CR line break, TAB auto-indent to word start on the line above. - Block — ^K B/K mark, ^K T word, ^K H show/hide, ^K C/V/Y copy/move/delete, ^K R/W read/write block to/from a file. - Search — ^Q-F find, ^Q-A replace, ^L repeat last; options B/G/n/U/W, and N (no-confirm) for replace; ^A matches any char, CR LF searches a line break. - ^P prefix inserts a literal control character; ^U / ESC abort prompts. - ^K-D returns to the shell; the text stays in memory, `changed` is reported and S (or the quit prompt) writes it to disk. Disk format matches TP3: CRLF line endings and a trailing `^Z`; load normalizes CRLF/LF, save re-expands. ## Porting notes (gm2) - Foreign modules (`DEFINITION MODULE FOR "C"`) must use `ADDRESS`, not Modula-2 record/pointer types — cast at the call site. - gm2 ICEs on `FOR ... EXIT`; use `WHILE`+flag (or `LOOP`+`EXIT`). - gm2 only emits `main` when the program module source is on the link line: `gm2 -fiso -o tpshell Shell.mod Term.o Posix.o TextBuf.o Editor.o`. - termios is used in raw mode, so every newline is explicit `CR LF`. - `EXIT` is only legal inside `LOOP` (ISO Modula-2), not `WHILE`.