Tag v3-m2s-clean. Main suite 110/110 (new t_compat).
With this, SymTab, QbeGen and M2S (the Coco/R scanner) all
compile clean under V3. M2P/M2 remain (see below).
The three known M2S items — and, once those parsed, a few more
GNU-isms in CR's generated scanner tables:
LENGTH — accepted as an alias of LEN.IF … THEN ELSIF/ELSE, WHILE … DO,
REPEAT, LOOP, FOR and CASE alternatives may now have empty
bodies (StatSeq optional), matching CR's generated code.& = AND, ~ = NOT — GNU/classic synonyms.charConst token
(0C, 03C, 012C) handled by NormLit → CHAR value
(0C = NUL).ORDL — alias of ORD.CAP — new builtin, branchless UPCASE
(q := a - 32*(a>='a' AND a<='z'), since QBE has no select).Also fixed a latent bug found via CAP: ABS (and now CAP) wrote
their result to a temp but Fact never copied it back to q, so
ABS silently returned its operand. Both now CopyOp(qa, q).
tests/t_compat.mod (exit 42) exercises &, ~, LENGTH, CAP,
ORDL, 0C, and empty THEN/ELSE.M2S.def + M2S.mod under V3: 0 errors.SymTab / QbeGen under V3: still 0 errors.tools/m2make unaffected; main suite 110/110.M2P.mod (the Coco/R parser) is 107 errors, dominated by 102
undeclared identifier — within-module forward procedure calls
in CR's generated recursive-descent parser (gm2 hoists these; ISO
wants declaration-before-use or FORWARD). Also BITSET{…}
constructors and symSet[0,0] nested-array assignment. This is the
next self-hosting chunk; the driver M2.mod additionally needs
nested procedure values (Error := StoreError, StoreError nested in
ListHandler) which the current proc-type support doesn't yet
provide (static link).
&, 0C, empty bodies and forward refs are all emitted by the CR
binary's built-in scanner/parser templates — not by our scanner.frm
(which has none of them). So V3 accepting them is the only way to
self-host CR's output short of patching the toolchain.
compiler/src/{M2.atg,QbeGen.def,QbeGen.mod},
compiler/tests/t_compat.mod, compiler/run_tests.sh.