# m2compiler-V3 โ€” language report Status at tag `v3-fwdvars-resultsfx` (2026-10-01). Suite **175/175**, self-hosting fixpoint **OK**. This is a reader-facing report: what the compiler accepts today, what it deliberately does not, and what is missing. It complements `docs/features.md` (feature-by-feature) and `docs/analysis_gaps.md` (gap taxonomy). Legend: โœ… done ยท ๐Ÿ”„ partial ยท โธ not implemented ยท ๐Ÿšซ deliberately out ## 1. What it is A from-scratch Modula-2 compiler: a Coco/R-generated frontend (`compiler/src/M2.atg`, 1,7xx lines, ~75 productions) lowered to QBE SSA (`QbeGen.mod`), assembled and linked to a small C runtime shim (`runtime/syslib/shim.c`). Classic identifiers (no `_`), `#` for "not equal", `0x` hex, `//` comments; the whole image is buffered and written in one pass, and the compiler **self-hosts byte-identically**. ## 2. Lexis and syntax โœ… - Identifiers `letter { letter | digit }`, no underscores. - Integers (decimal, `0x`/`0X` hex, char codes `NN C`), reals with `E` exponents, `'โ€ฆ'`/`"โ€ฆ"` strings, `U'โ€ฆ'`/`U"โ€ฆ"` codepoint literals. - `#`, `<`, `<=`, `>`, `>=`, `=`; `NOT`/`AND`/`OR` only. - `//` line comments and nested `(* โ€ฆ *)` block comments. ## 3. Types โœ… - `INTEGER`, `CARDINAL`, `SHORTINT`, `LONGINT`, `SHORTCARD`, `REAL`, `LONGREAL`, `CHAR`, `BOOLEAN`, `NIL`, `BITSET`. - gm2 sized names: `LONGCARD`, `SHORTREAL`, `INTEGER8/16/32/64`, `CARDINAL8/16/32/64`, and SYSTEM storage names `BYTE`, `SBYTE`, `WORD`, `SWORD`, `LONGWORD`, `SHORTADDR`, `LONGADDR`, `PROC`, `PROCESS`, `LOC`, `ADDRESS`. - Named types and aliases; integer/char/`BOOLEAN`/enum subranges (bounds folded, anchored `T[lo..hi]`); enumerations. - `ARRAY [lo..hi, โ€ฆ] OF T` (multi-dimensional), open `ARRAY OF T` formals, index-type arrays `ARRAY OF T`. - `RECORD`, including **variant records** (`CASE tag : T OF โ€ฆ END`); whole-record assignment is a flat byte blit. - `SET OF` bool/char/subrange/enum (multi-word, span โ‰ค 65536). - `POINTER TO`, opaque `TYPE T;` + completion, `ADDRESS` โ†” pointer. - `PROCEDURE โ€ฆ : T` types and procedure-typed values. - `UCHAR` (32-bit codepoint) and `UString` (`U"โ€ฆ"`). ## 4. Expressions and statements โœ… - Full precedence; `+ - * / DIV MOD`, comparisons, eager `AND`/`OR`/ `NOT`, `IN`, set union/diff/inter/symdiff, pointer `=`/`#`, indexing, field access, `^` deref, qualified `L.x` / `L.P`. - String `=`/`#` (content), `+` (concat), assignment (content copy, NUL-terminated), `LEN`/`LENGTH`; UString `+`/`LEN` likewise. - `IF/ELSIF/ELSE`, `CASE` (labels, ranges, `ELSE`), `WHILE`, `REPEAT/UNTIL`, `LOOP/EXIT`, `FOR/TO/BY` (static sign), `WITH`, `RETURN`, `HALT`, `NEW`/`DISPOSE`. - Builtins `VAL`, `ADR`, `TSIZE`, `SIZE`, `HIGH`, `LEN`, `INC`, `DEC`, `INCL`/`EXCL`, `SHIFT`/`ROTATE`, `MIN`/`MAX` (any ordinal type, array or set). - **Result suffixes** (expression context): `F()^`, `F()[i]`, `F().field`. - **`FROM libc IMPORT โ€ฆ`** โ€” permissive external C procedures. - Array/record constructors `T{โ€ฆ}` (static and runtime), `expr BY n`. - **Forward module-level variables**: a procedure body may reference a global declared further down the module. ## 5. Modules and procedures โœ… - Program modules, `DEFINITION`/`IMPLEMENTATION` modules, `IMPORT` / `FROM โ€ฆ IMPORT`, `EXPORT` (incl. `QUALIFIED`), nested local modules. - Separate compilation of a whole session into one image with module init bodies; opaque completion; strict 235 signature checks. - Value and `VAR` parameters, function results, recursion, mutual recursion (`FORWARD`), nested procedures (static-link display), open-array `VAR` formals. - Clarion-form `CLASS`: fields, methods (value/`VAR`, results), single inheritance, `VIRTUAL` dynamic dispatch via vtables, `WITH`, hidden `THIS`, class `BEGIN โ€ฆ END` init bodies. ## 6. Coroutines โœ… PIM `SYSTEM.PROCESS`, `NEWPROCESS`, `TRANSFER`, `IOTRANSFER` (ucontext-backed). `IOTRANSFER` degrades to a plain transfer. ## 7. Backend โœ… Length-prefixed arrays (count + elements), deep record copy, count-checked whole-array assign, runtime bounds/span traps (`$abort`, rc 134), multi-word sets, `alloc8` heap (`malloc`/`free`), deterministic `%tN`/`@LN`, whole-image buffering, REAL const flush, string literals as descriptors, vtables. ## 8. Library **runtime/syslib** (always linked): `SysShim`, `FileIO`, `Utf8`. **stdlib** (opt-in): `SysIO`, `TextIO` (+ UTF-8), `WholeIO`, `Math`, `Strings`, `CharClass`, `Files`, `Conversions`, `RealIO`, `ProgramArgs`, `SysClock`, `IOChan`, `Storage`, plus the gm2/ISO set added this session: | Area | Modules | | --- | --- | | conversion | `ConvTypes`, `WholeStr`, `RealStr`, `LongStr`, `LongMath`, `LongIO`, `LongWholeIO` | | text IO | `StrIO`, `InOut`, `StdIO`, `STextIO`, `SWholeIO`, `SRealIO`, `SIOResult`, `IOConsts` | | runtime | `DynamicStrings` (core), `SysStorage`, `TERMINATION` | ## 9. Missing ### 9.1 Language - **`GOTO` and labels** โ€” parse error. โธ - **Generics** โ€” not started. โธ (`docs/analysis_generics.md`). - **Statement-context result suffixes** โ€” `F()[i] := x` and `F()^.f := x` are **not accepted** (expression suffixes are). โธ - **Chained post-call calls** `F().M()` โ€” not accepted. โธ - **Multiple inheritance** โ€” ๐Ÿšซ out of scope (`docs/OOP.txt`). - **Full forward variables** โ€” supported at module scope; forward references from a procedure to a *procedure* declared later relies on the DEFINITION being present (as before). ๐Ÿ”„ - **`GOTO`-free** result suffixes only; no `EXIT` from a nested named loop etc. ### 9.2 Library - Channel/device framework: `ChanConsts`, `GenDevIF`, `DeviceTablePtr`, `StdChans`, `StreamFile`, `FIO`. โธ - C wrappers `wrapclock`/`wraptime`/`wrapc`, `TimeString`. โธ - `DynamicStrings` is the **core subset** (no `*DB` debug variants, no `InitStringCharStar`). ๐Ÿ”„ - ISO read-result bookkeeping is minimal (a single default-channel result via `SIOResult`). ๐Ÿ”„ ### 9.3 Architecture / robustness - **No AST, single pass** โ€” declaration-before-use is enforced, so forward references beyond the two supported kinds fail. - **Single image only** โ€” no per-module object emission, no import cycles. - **Fixed-size tables** โ€” 64 formals/locals, 64 call args, 4096 string literals, 256 pooled constructors, 128 session source files, 4 MiB image buffer. - **Weak error recovery** โ€” one bad token can cascade. - **Traps** are `$abort` (rc 134), not a catchable `Trap`; `DISPOSE` is shallow. ## 10. Reproduce ```sh cd .../m2compiler-V3 ./bootstrap/fixpoint.sh # FIXPOINT OK cd compiler && ./build.sh && ./run_tests.sh # 175/175 G=$HOME/bin/Modula2/Gm2/lib/gcc/x86_64-pc-linux-gnu/16.0.1/m2 V3_LIBS="$G/m2pim:$G/m2iso:$G/m2log:$G/m2cor:$G/m2min" \ tools/v3-corpus/corpus.sh ```