# 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 `MODULE`s (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.