# SimpleMod2 project — summary Subset of Modula-2 (no procedures/functions) with a Coco/R-generated compiler featuring a symbol table, static type checking and a Modula-2-generating backend. All work lives in `Test1/`, built with `../CR -m -C` and GNU Modula-2 (`gm2 -fiso`). ## 1. Starting point Analysed `Sample grammars/` (21 Coco/R `.atg` files across the C / Pascal / Modula-2 / Oberon / Ada / calculator families, plus `Other Formats/` with 6 ANTLR Modula-2 grammars) as reference material. ## 2. Simplified grammar — `Test1/SimpleMod2.atg` Modula-2 subset **without procedures/functions**: program module only, `CONST` / `TYPE` / `VAR`, full expression hierarchy, assignment and `IF CASE WHILE REPEAT LOOP/EXIT FOR WITH` statements. Removed: procedure declarations and calls, formal parameters, `RETURN`, `DEFINITION` / `IMPLEMENTATION` modules, local modules, `EXPORT`, `PRIORITY`. LL(1)-clean (subrange rule factored for Coco/R). ## 3. Test infrastructure — `Test1/` - Parser / scanner / driver generated with `CR -m -C SimpleMod2.atg` (`-C` = emit compiler main module, `-m` = FORWARD declarations commented out), `CRFRAMES` pointing at `Test1/` for the frame files. - Built with `gm2 -fiso` (`FileIO SymTab CodeGen SimpleMS SimpleMP SimpleM`, linked via generated module list) → `Test1/SimpleM`. - `Test1/tests/`: 30+ `.mod` sources with `.LST` listings — valid programs (`t_ok_*`, `ok`), syntax rejects (`t_bad_*`, `bad`), symbol-table rejects, type rejects, backend demos (`t_be_demo`, `t_be_full`). - `Test1/gen/`: backend output (`.mod` per successful parse). ## 4. Symbol table — `Test1/SymTab.def/.mod` Scopes with levels (globals at level 0) and kinds (`CONST` / `TYPE` / `VAR` / `IMPORT` / `MODULE` / `PREDEF` / `FIELD`): duplicate declarations (200), undeclared identifiers (201), `MODULE` / `END` name match (202). ## 5. Type checking (error codes 210–224) - Type descriptors: one alias per `TYPE` declaration (so self-references such as `POINTER TO Person` resolve; `A = A` is caught as cyclical), subranges, enumerations (literals typed), arrays, records **with field lists**, sets, pointers, predefined types, string literals. - Synthesized types through all expressions and designators; checks for assignment compatibility (incl. assignment to a constant), arithmetic vs boolean operators, comparisons, `BOOLEAN` conditions, array indexing, pointer dereference, `.field` selection, `FOR` integer-ness, `CASE` label matching, `IN` / set elements, ordinal index and bound types, type-position names. - `WITH` pushes the record's fields as an inner scope, so unqualified field access works in its body. - Rules: declare-before-use (single pass); INTEGER, CARDINAL and subranges form one integer family; no mixed INTEGER/REAL arithmetic; INTEGER assigns to REAL; 1-character literal is `CHAR`; unknown types (`InvalidType`) suppress follow-on errors to avoid cascades. - 15 `t_bad_*` type tests, each producing exactly its intended code (e.g. `x := 3.14` → 210, `b + 1` → 211, `x AND y` → 212, `x = r` → 213, `WHILE x` → 214, `x.y` → 215, `p.b` → 216, `x[1]` → 217, `v[r]` → 218, `x^` → 219, `FOR r :=` → 220, `v : x` → 221, `{1, 'a'}` → 222, `A = A` → 223). ## 6. Backend — `Test1/CodeGen.def/.mod` Syntax-directed pretty-printer: grammar actions re-emit every token with regenerated layout (`Emit` / `Brk` / `Ind` / `Ded`) into `gen/.mod`. Output is complete, ready-to-compile Modula-2 (comments dropped). Proven end to end: `BeDemo` / `BeFull` outputs compile (`gm2 -fiso -c`), link and run (exit 0); all other valid-test outputs compile too, except two whose **original sources** fail identically under gm2 (strict set typing, missing `MathLib` library) — i.e. the backend is faithful to its input. ## 7. Current state - Full suite: **32/32** correct verdicts with exact error codes and no cascades. - Rebuild from `Test1/`: `CRFRAMES=$(pwd) ../CR -m -C SimpleMod2.atg`, then `gm2 -fiso -c` on `FileIO SymTab CodeGen SimpleMS SimpleMP SimpleM` and link with `-fgen-module-list` / `-fuse-list`. - Run: `./SimpleM tests/.mod` (listing next to the source, generated code in `gen/`, symbol table dumped on stdout). - Known limits: no constant folding, no `NIL` literal in the language, multi-dimensional arrays check every index but track a single element type, backend output is only meaningful when the verdict is `Parsed correctly`.