|
|
1 gün önce | |
|---|---|---|
| .. | ||
| README.md | 1 gün önce | |
| gap01_fwd_type_const_conv.mod | 2 gün önce | |
| gap02_fwd_type_var.mod | 2 gün önce | |
| gap03_fwd_type_heading.mod | 2 gün önce | |
| gap04_fwd_const_bound.mod | 2 gün önce | |
| gap05_fwd_type_size.mod | 2 gün önce | |
| gap06_fwd_setconst.mod | 2 gün önce | |
| gap09_scalar_to_bytearray.mod | 2 gün önce | |
| gap10_var_param_type.mod | 2 gün önce | |
| gap11_bare_proc_stmt.mod | 2 gün önce | |
| gap12_variant_empty_arms.mod | 2 gün önce | |
| gap14_builtin_pragma.def | 2 gün önce | |
| gap16_wide_set.mod | 2 gün önce | |
| gap17_set_of_cardinal.mod | 2 gün önce | |
| gap18_set_case_labels.mod | 2 gün önce | |
| gap19_fwd_array_index.mod | 2 gün önce | |
| gap20_fwd_set_of_type.mod | 2 gün önce | |
| gap21_fwd_record_field.mod | 2 gün önce | |
| gap22_file_line.mod | 2 gün önce | |
One minimal source per known V3 gap (2026-10-18). Each file's header comment carries its tag, its Modula-2 status, and the gm2 corpus file(s) it stands for. These are not part of the test suite (they are expected to fail); they exist so each case has a runnable example.
Verify one with:
cd compiler && ./build.sh
./M2 ../docs/gaps/gap07_convert.mod # prints the diagnostic on stdout
The corpus is gcc's gm2 testsuite, so "compiles on the corpus" mixes conforming Modula-2 with gm2 leniencies and extensions. This project follows the language:
Standard Modula-2 (PIM and ISO) requires declaration before use; the declaration part is ordered
CONST,TYPE,VAR. The only forward reference the language allows is aPOINTER's base type (for recursive/self-referential types).
V3 therefore intentionally rejects use-before-declaration; that is conforming behaviour, not a gap. gm2 accepts such programs because it resolves the whole declaration part before checking — a leniency.
Since 2026-10-19 the rule is also enforced inside deferred procedure bodies for module-level data (variables, constants, types): a body may not use one declared after its procedure. Forward procedure calls from a body remain allowed (the generated parser relies on it).
The class column says what a change would mean:
decl-order — not legal Modula-2; gm2 leniency. V3 rejects it
correctly. Not a target.gm2-ext — not standard; a gm2/PIM extension or leniency.
Not a target unless we choose gm2 compatibility.iso/system — a standard ISO Modula-2 / SYSTEM facility V3 lacks.
A genuine gap.v3-deviation — V3 is stricter than the standard (a V3 bug to
fix).impl-limit — the language allows it; V3 has a fixed implementation
limit.| tag | file | class | diagnostic | corpus exemplars |
|---|---|---|---|---|
gap01-fwd-type-const-conv |
gap01_fwd_type_const_conv.mod |
decl-order |
undeclared identifier |
subrange4, subrange7 |
gap02-fwd-type-var |
gap02_fwd_type_var.mod |
decl-order |
undeclared identifier |
subrange11, arrayptr, arrayptr6, constructor1, constructor3, param3 |
gap03-fwd-type-heading |
gap03_fwd_type_heading.mod |
decl-order |
undeclared identifier |
shift3, shift4 |
gap04-fwd-const-bound |
gap04_fwd_const_bound.mod |
decl-order |
undeclared identifier |
setconst3 |
gap05-fwd-type-size |
gap05_fwd_type_size.mod |
decl-order |
undeclared identifier |
constsize2 |
gap06-fwd-setconst |
gap06_fwd_setconst.mod |
decl-order |
undeclared identifier |
setoverflow |
gap09-scalar-to-bytearray |
gap09_scalar_to_bytearray.mod |
gm2-ext (accepted) |
— | aochar, arrayofbyte, bytearray |
gap10-var-param-type |
gap10_var_param_type.mod |
gm2-ext (accepted) |
— | testparam2 |
gap11-bare-proc-stmt |
gap11_bare_proc_stmt.mod |
gm2-ext (accepted) |
— | tinyproc2, tinyproc4 |
gap12-variant-empty-arms |
gap12_variant_empty_arms.mod |
gm2-ext (accepted) |
— | varient2, varient3, varient8, tsize, tsize2 |
gap14-builtin-pragma |
gap14_builtin_pragma.def |
gm2-ext (accepted) |
— | builtin.def, builtin.mod |
gap16-wide-set |
gap16_wide_set.mod |
impl-limit |
not supported yet |
settest1 |
gap17-set-of-cardinal |
gap17_set_of_cardinal.mod |
impl-limit |
not supported yet |
settest3 |
gap18-set-case-labels |
gap18_set_case_labels.mod |
gm2-ext (accepted) |
— | bitset5 |
gap19-fwd-array-index |
gap19_fwd_array_index.mod |
decl-order |
not supported yet |
record7, complextypes |
gap20-fwd-set-of-type |
gap20_fwd_set_of_type.mod |
decl-order |
undeclared identifier |
tinyset6, tinyset7 |
gap21-fwd-record-field |
gap21_fwd_record_field.mod |
decl-order |
undeclared identifier |
record14.def, record15.def, record16.def |
gap22-file-line |
gap22_file_line.mod |
gm2-ext (accepted) |
— | packed |
First diagnostic (message) per file at commit time (line:col varies as comments change):
gap01_fwd_type_const_conv.mod undeclared identifier (ind0)
gap02_fwd_type_var.mod undeclared identifier (arr)
gap03_fwd_type_heading.mod undeclared identifier (large)
gap04_fwd_const_bound.mod undeclared identifier (n)
gap05_fwd_type_size.mod undeclared identifier (t)
gap06_fwd_setconst.mod undeclared identifier (CharSet / tab)
gap09_scalar_to_bytearray.mod invalid call (scalar -> ARRAY OF BYTE)
gap10_var_param_type.mod invalid call (VAR actual type)
gap11_bare_proc_stmt.mod invalid call (bare proc value)
gap12_variant_empty_arms.mod invalid VarLabel
gap14_builtin_pragma.def ident expected (__BUILTIN__)
gap16_wide_set.mod not supported yet (span > 65536)
gap17_set_of_cardinal.mod not supported yet (unbounded base)
gap18_set_case_labels.mod not supported yet (set as CASE selector)
gap19_fwd_array_index.mod not supported yet (array index declared later)
gap20_fwd_set_of_type.mod undeclared identifier (SET OF base declared later)
gap21_fwd_record_field.mod undeclared identifier (record field type declared later)
gap22_file_line.mod invalid Fact (__LINE__)
gap07 CONVERT — fixed (2026-10-18): CONVERT(T, x) is accepted as
a VAL sibling (procconv2 passes).gap08 set↔word CAST/VAL — fixed (2026-10-18): VAL/CAST
between a set and its machine word (constset, constset2,
constset3 pass). packed still needs gap22 (__FILE__/__LINE__).gap13 builtins as identifiers — corpus case fixed; remainder
deferred (2026-10-18 / confirmed 2026-10-19): ORDL (a gm2/FileIO
helper, not a Modula-2 built-in) is no longer reserved, so
PROCEDURE ORDL is accepted (fileio.def/mod, baseimport pass; the
scanner frame imports FileIO.ORDL). The standard built-ins
(ORD, CHR, VAL, SIZE, ABS, … ~24 words) are still reserved
keywords. De-reserving them is a contextual-keyword rewrite of
Fact/ArgList/the statement builtins (Coco/R is LL(1), so it cannot
branch on an identifier's text; the dedicated builtin alternatives
would have to merge into the general Design+ArgList path). There
is no corpus exemplar in the scanned dirs (no file declares a
builtin as a name), so the payoff is conformance-only; a declaration-
site-only half-measure would bind calls to the builtin (silently
wrong), so it is deliberately not shipped. Tracked as a known
v3-deviation.gap15 enumeration literals with an imported type — fixed
(2026-10-18): literals now travel with the type through re-export,
FROM-import and qualified access; also fixed the qualified-const value
(LoadDesignator returned 0 for enum consts). imp* pass.FOR "C" / EXPORT UNQUALIFIED — already fixed
(§ STATUS).gap16/gap17 are implementation limits (raising the set span cap).
These are not standard Modula-2; V3 accepts them for gm2 compatibility (they do not relax any conforming rule).
gap22 __FILE__ / __LINE__ — supported (2026-10-19). The
scanner now allows a leading _ in identifiers, the two names are
reserved literals, and the parser folds them to the current file-name
string and line-number integer (scanner.frm records the file with
SetFileName). Corpus: packed (+2 more __LINE__ users) now pass.gap09 scalar actual → ARRAY OF BYTE — accepted (2026-10-19).
SYSTEM.BYTE is V3's 32-bit CARDINAL, so ARRAY OF BYTE cannot be
byte-granular; the ARRAY OF BYTE open formal is marked at parse time
and a scalar/pointer/string actual is accepted. For a scalar the
caller builds a stack descriptor [count = SIZE(actual)][copy of the
value], so HIGH matches gm2's SIZE-1, but writes reach the
copy, not the actual, and a string actual is passed as-is (its
HIGH is the NUL index, so one less than gm2's). A genuine 8-bit
BYTE (and byte-exact buffers) remains out of scope.
Corpus: aochar, arrayofbyte, bytearray (×2) now compile.gap10 scalar VAR actual, same size — accepted (2026-10-19).
VarParamOk accepts a scalar VAR actual of a different type when
ObjectSize matches (e.g. INTEGER for VAR WORD). testparam3
(SHORTREAL for VAR WORD) still fails: V3 models every real as
8 bytes, so there is no 4-byte SHORTREAL.gap11 bare procedure value as a statement — accepted (2026-10-19).
The PIM PROC type keyword is now recognised, and a proc-typed
designator with no parameter list is an implicit zero-argument call
(named or indirect).gap12 variant records — extended (2026-10-19). Empty arms,
ELSE arms, comma-separated labels, tolerated extra | separators,
untagged inner CASE : T OF, and nested variant CASEs inside an
arm. (An untagged variant falls back to sequential layout, since
there is no tag slot to overlay from.)gap18 set-typed CASE labels — accepted (2026-10-19). A set
selector takes set labels; the compare-chain uses word-wise set
equality (QbeGen.CmpSet).gap14 __BUILTIN__ / __ATTRIBUTE__ pragmas — accepted
(2026-10-19). An optional declaration pragma after PROCEDURE
(__BUILTIN__, or __ATTRIBUTE__ __BUILTIN__ (( name ))) is parsed
and ignored; the procedure is compiled normally. Corpus:
builtin.def, builtin.mod.The gap13 remainder (standard builtins as identifiers) and gap14
(__BUILTIN__) remain; gap19/gap21 are decl-order.
Record array field passed as an open array — a record's inline
array field loses its length word when the record sits in static
array-of-record data, so passing the field as an ARRAY OF … actual
reads length 0 and traps. Worked around by flattening Lower's tables;
the general fix and docs/wip/nested-array-field-bug.mod remain open
(see docs/summary_l3_selfhost_fix.md).
Size-sensitive V3 miscompile — root-caused 2026-10-19: not
size-sensitive, and not a codegen bug at all. The ASTDUMP debug dump
printed the literal "Parsed correctly", which satisfied the
fixpoint's grep -q Parsed gate while the compiler session was
reporting Incorrect source; removing the dump simply unmasked the
real errors (Lower's forward procedure calls). Fixed in a3ef897.