- AMPL 34.5%
- HTML 17.1%
- Pascal 13%
- Python 12.1%
- DIGITAL Command Language 12%
- Other 11.1%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| calc-port | ||
| Resources | ||
| shell | ||
| .gitignore | ||
| CALC-COMPILE.md | ||
| CALC-PORT.md | ||
| CORPUS-TEST.md | ||
| FREEDOS-CALC.md | ||
| README.md | ||
| RESUME-TP3.md | ||
| SUMMARY.md | ||
| TERMINAL.md | ||
| TP3-COMPILER.md | ||
| TP3-CONFORMANCE.md | ||
| TP3-EDITOR-PSEUDOCODE.md | ||
| TP3-EDITOR.md | ||
| TUTORIAL.md | ||
| v-TP3-8086-LOWERING.md | ||
| v-TP3-DEAD-FIXTURES.md | ||
| v-TP3-DECL-WINDOW-STRIDX.md | ||
| v-TP3-INTERRUPT-RESTORE.md | ||
| v-TP3-STRCAT.md | ||
| v-TP3-STRCMP.md | ||
| v-TP3-STRIDX-VAR.md | ||
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. The
short version:
- The shell, WordStar-style editor, compiler, linker and in-process 8086 interpreter all build and run.
- The compiler is split into focused modules:
CompilerShared,CompilerUtil,CompilerSource,CompilerSymbols,CompilerLex,CompilerExpr,CompilerIO,CompilerEmit,CompilerStmt(statements),CompilerDecl(declarations) andCompilerCode(the address-forming and small emitters the parsers call);Compiler.modis the driver. The runtime is split the same way:RuntimeEmit(state and instruction emitters),RuntimeText,RuntimeReal,RuntimeFile,RuntimeDataand a smallRuntime.moddriver. - The surviving TP3 corpus compiles 71/71;
CALC.PAScompiles to its final.COMand runs through the welcome screen, grid, menu and a formula. - Emitted
.COMimages run under bothqemu-system-i386and Exec86; the shell'sRkey now runs the linked image in-process. - Current measured runtime: 11,476 bytes / 86 entries. CALC:
39,359-byte
.COM(code 25,945 + data 19,694), and its full Help path allocates and reads the 16,281-bytePagesarray, then pages through it with N/P/Esc. - Data and heap live in a separate DS segment (
DataStart = 5000h), as in the original TP3; the.COMis code plus a small initialised-data image. - A call takes up to 64 arguments (
MaxArgs);t168_manyargsruns 20 andt169_arglimitpins the 65th. A malformed program-header list such asprogram p(1;)is an error, not an infinite loop. - Latest code checkpoint:
v-TP3-ABS-INLINE; conformance details are inTP3-CONFORMANCE.md.
The remaining work is TP3-conformance and verification, not basic compilation:
interrupt services beyond the ones the harnesses answer, heap coalescing, and
the accepted no-op runtime/editor options. SUMMARY.md lists these in
priority order.
Build
Requires GNU Modula-2 (gm2, tested with 16.0.1) and a C compiler for the
FOR "C" bridge.
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. DOS file tests use
dosbox-x when available and skip cleanly when it is not. The mutation suite
is bash tests/nonvacuity.sh.
New here? Start with TUTORIAL.md. It walks through the
build, the shell, editing and compiling a program, running the emitted image,
and the test harnesses.
CALC launcher
tests/calc_cli.py builds CALC.COM in a temporary include directory, boots it
under qemu and prints its serial output:
cd shell
python3 tests/calc_cli.py # build + default welcome/quit keys
python3 tests/calc_cli.py --com CALC.PAS.COM --keys '\r\r/Q'
python3 tests/calc_cli.py --keys-file keys.bin --raw > screen.bin
Options: --keys (Python escapes such as \r, \n, \x1b), --keys-file,
--com, --timeout, --raw, --quiet, --verbose, and --no-keypress
(make AH=0Bh report no queued key; useful for scripted CALC input).
Input is a static boot-time key stream, not a live terminal. The automated
smoke check is python3 tests/calc_smoke.py, run by tests/run_all.sh.
For a manual FreeDOS/qemu setup, see FREEDOS-CALC.md; CALC is verified
under the FreeDOS 1.4 LiveCD.
Layout
shell/Term.def|mod— raw termios keyboard + ANSI screen primitives (blockingGetCh, non-blockingAvail/GetKeyviapoll,GotoXY, highlightMarked/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.BAKrotation, directory listing, options menu.shell/Compiler.def|mod— the compiler's public interface and the statement/declaration/driver core.shell/CompilerShared.def— shared compiler state, constants and types.shell/CompilerUtil.def|mod— pure character/word/bit/string helpers.shell/CompilerSource.def|mod— source cursor and{$I}expansion.shell/CompilerSymbols.def|mod— symbol table, lookup, insertion and scope hiding.shell/CompilerLex.def|mod— keyword table, scanning, constants and the string-literal pool.shell/CompilerExpr.def|mod— expression parser and value construction.shell/CompilerIO.def|mod— standard-procedure dispatch.shell/CompilerEmit.def|mod— primitive 8086 emitters and patch machinery.Compiler.CodeByteAtexists 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 fromRuntime.def; the emitter procedures are audited name-against-decode.shell/Linker.def|mod— assembles[JMP rel16][runtime][header][program]and writes a real DOS.COMwhen the Destination option isCOM.shell/Makefile— the authoritative build recipe; two-phase link, seeSUMMARY.md.shell/tests/— the harnesses.run_all.shruns them,nonvacuity.shproves each one can go red.tests/fixtures/expected.tsvis 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. It also carries the prioritized next milestones.TUTORIAL.md— a hands-on walkthrough from build to compile/run and tests.TP3-CONFORMANCE.md— directive, type and library conformance matrix.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 the linked image in-process through Exec86 and report its exit status |
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,
changedis 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 useADDRESS, not Modula-2 record/pointer types — cast at the call site. - gm2 ICEs on
FOR ... EXIT; useWHILE+flag (orLOOP+EXIT). - gm2 only emits
mainwhen 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. EXITis only legal insideLOOP(ISO Modula-2), notWHILE.