summary_m2comp_step1.md 2.7 KB

m2comp step 1 — Coco/R syntax front end (tag: m2comp-step1)

Goal

Fresh m2comp/ project (distinct from m2c/ at step 11): prove the toolchain end to end before any language work — Coco/R grammar → generated scanner/parser/driver → gm2 -fiso build → test runner. Lexer and parser are FULLY Coco/R-generated; no hand-written lexer.

What was built

  • m2comp/src/M2comp.atg — Modula-2 program modules: MODULE + FROM/IMPORT, CONST/TYPE/VAR, PROCEDURE (nested, value/VAR params, function result), local MODULEs (Wirth form: [Priority], [Export [QUALIFIED]]), statements (assign/call, IF, WHILE, REPEAT, LOOP/EXIT, FOR/BY, RETURN), full expressions. Only check is the MODULE/END name match (error 202).
  • Kowarsch adaptations (from docs/, arXiv:1809.07080): unary minus takes a Factor (§3.3: -b+c ok, bare -b*c+a rejected, parens required); abbreviated multi-dim arrays via comma index list with subrange-capable IndexType (§3.1 strict); no octal B/C suffixes (§2.1); <> kept (open, §2.2); (*$ *) still comments (open, §2.3/2.4).
  • m2comp/src/ holds ALL sources: M2comp.atg, compiler.frm (listing driver, no SymTab/MGen yet), scanner.frm, parser.frm, FileIO.def/.mod (copied from m2c/), generated M2compS/M2compP/M2comp (.def/.mod), Hello.mod (gm2 smoke test). Deleted as unnecessary: hand M2Lex (replaced by M2compS), unused Err, empty build/.
  • m2comp/build.sh — regenerate (CRFRAMES=src CR -m -C), compile with gm2 -fiso, link via the two-phase module-list workaround; produces ./M2comp (project root).
  • m2comp/run_tests.sh — expect_ok/expect_fail on tests/ok_minimal.mod, tests/ok_proc.mod (local module, 2-D abbreviated array, -v+1), tests/bad_mismatch.mod (202).

Tests — 3/3

test result
ok_minimal MODULE M; BEGIN END M. accepted
ok_proc imports, VAR, 2-D array, proc + local module accepted
bad_mismatch END WrongName rejected (Incorrect source)

gm2 -fiso src/Hello.mod → Hello m2comp (gm2 -fiso) verified.

Notes

  • Grammar name M2comp keeps generated modules short (M2compS/M2compP/M2comp, no Coco/R truncation surprises).
  • LL(1) fix: FieldSeq = Field { ";" Field } (first field mandatory, may be empty) — the fully-optional form made END ambiguous.
  • ISO gotchas: no anonymous ARRAY[0..63] formals (open ARRAY OF CHAR in GetIdent); no whole-array # (name match via Strings.Equal, hence IMPORT Strings in the .atg).
  • Step 2: SymTab (duplicate/undeclared, type checks 200/210-224, nested-ARRAY OF ARRAY long-form flag) + MGen/MC64 backend.