I continue to work on my Modula-2 compiler. This one is more elaborate. Wip.
|
|
9 uur geleden | |
|---|---|---|
| bootstrap | 2 weken geleden | |
| compiler | 9 uur geleden | |
| docs | 9 uur geleden | |
| runtime | 2 weken geleden | |
| stdlib | 2 weken geleden | |
| tools | 1 week geleden | |
| vendor | 3 weken geleden | |
| .gitignore | 2 weken geleden | |
| README.md | 9 uur geleden | |
| m2make.md | 3 weken geleden |
A from-scratch Modula-2 compiler in the Blaise spirit (phased,
test-guarded, self-hosting as the end goal): a Coco/R-generated
frontend in GNU Modula-2, a fresh QBE SSA backend, and a
length-prefixed runtime data model. Modern syntax follows the
Benjamin R10 specs where they don't break classic code
(Kowarsch/Redux cleanups: # not <>, NOT/AND/OR only, no
B/C octals, 0x hex, // comments).
gm2 -fiso; developed with GCC 16.0.1 experimental)CR V1.53 (CRBIN env var, defaults to the sibling
CocoGm2/CR used here)qbe (default target amd64_sysv; pin: vendor/qbe-pin.txt)cc, timeout, standard shell toolscd compiler
./build.sh # M2.atg -> scanner/parser/driver -> ./M2
./run_tests.sh # M2 -> gen_ssa/*.ssa -> qbe -> cc -> exit codes
Pipeline per test: ./M2 tests/foo.mod writes
gen_ssa/FOO.ssa; a global VAR ExitCode : INTEGER selects the
process exit code (else 0). Reject tests assert on .LST messages;
every error also prints as file:line:col: message on stdout.
M2 itself exits 0 on success, 1 on compile errors and 2 on
usage/IO problems (no input, unopenable file) — no aborts.
compiler/src/ M2.atg, frames, FileIO, SymTab, QbeGen, Lower (+ generated)
compiler/tests/ t_*.mod (check/reject/run) + showcase<N>.mod tours
compiler/gen_ssa/ build outputs (gitignored)
runtime/syslib/ always-linked runtime (SYSTEM, Storage, SysIO, …)
stdlib/ opt-in libraries (Strings, TextIO, …; classic form)
tools/ syntax helpers + v3-corpus (coverage harness)
bootstrap/ stage1/2/3 + fixpoint.sh (self-hosting proof)
vendor/ qbe toolchain pin
docs/ STATUS.md, plan.md, plan-*.md, analysis_*.md, summary_*.md
tools/v3-corpus).resolve-check (holds the AST/Lower/parse
refactors and generics).Lowers today: program modules; CONST/VAR/TYPE (scalars,
subranges, enums, arrays, records incl. variants, sets, pointers);
ARRAY/RECORD/SET/POINTER, WITH, IN; whole array/record
copy; NEW/DISPOSE; all scalar arithmetic, relations, boolean
connectives; IF/CASE/WHILE/REPEAT/LOOP/FOR, GOTO/labels;
procedures with value/VAR params, functions, recursion, FORWARD,
nested procedures (static-link display), procedure values;
Clarion-form CLASS with methods, inheritance and virtual dispatch;
PIM coroutines (PROCESS/NEWPROCESS/TRANSFER/IOTRANSFER);
Unicode (UCHAR codepoints, UString, UTF-8 at the edges); ISO type
conversions T(x) (incl. CONST folding); separate compilation
(lib.def lib.mod prog.mod in one run → one image, FROM/IMPORT,
qualified L.x, opaque-type completion); generics — ISO 10514-2
refinement form (GENERIC … MODULE M(T:TYPE) + MODULE X = M(actuals))
with type/value/procedure parameters, constraints
(T : TYPE (ORDINAL|INTEGER|REAL|POINTER|SCALAR)), nested generics,
and generic classes.
Architecture: a two-phase parse — each unit's procedure bodies are
deferred and re-parsed at unit end, so forward references bind
normally and the old forward-reference machinery is gone. There is no
separate resolve/check pass; Lower is the only emitter and walks the
AST. -notwophase restores the legacy inline parse (debug escape).
Long-term rules already locked: every ARRAY is LONGCARD count
UCHAR = 32-bit codepoint, UString = count + codepoints, UTF-8
at the edges with hard lex errors; self-hosting bar is
byte-identical .ssa over three stages.compiler/src/M2.atg
(kept LL(1)-clean — Coco/R must report no errors).docs/summary_*.md; showcase<N>.mod tours each stage.
See docs/INDEX.md for the load-bearing docs.v3-* mark green states; no pushes without asking (see
git.txt for the remote recipe).