DIAGNOSTICS.md 2.8 KB

Modula-2 diagnostics — step 1

This first diagnostics layer is deliberately lightweight. It does not replace Coco/R. It provides immediate editor feedback for a small set of structural errors while the real parser/LSP is being prepared.

It currently checks:

  • unterminated (* ... *) comments;
  • unterminated string literals;
  • presence of the module header;
  • ; after the module header;
  • presence of the final END <ModuleName>.;
  • module-name consistency between the header and final END;
  • the final period after END <ModuleName>.

The diagnostics are published through the VS Code-compatible DiagnosticCollection, which Theia displays directly in the editor.

The next stage will replace the structural checks with diagnostics generated by the Coco/R parser, while keeping the same editor diagnostic mechanism.

Server-side semantic layer (src/m2/analyse.ts, source modula2)

In parallel, the language server runs its own checks on every open document — always on, merged with Coco/R output when a validator is configured:

  • duplicate declarations in one scope (error, with first-declared line);
  • unknown identifiers (error), with conservative skips: qualified names, import clauses, WITH regions, unverifiable FROM-imports, predefined identifiers, closing END Name;
  • enumeration literals (A, B, ...) are treated as declared constants, so they resolve, complete, and appear in the outline.

Not covered (needs statement/expression parsing): assignment type compatibility, call arity, use-before-declaration order, FROM-list membership against the defining .def.

Statement checker (src/m2/checker.ts + src/m2/types.ts, source modula2)

Bodies (BEGIN..END, recorded by the parser) are walked with a recursive statement/expression analyser. Operator and compatibility rules were calibrated case-by-case against gm2:

  • assignment compatibility, including whole-number family, REAL↔LONGREAL, CHAR/string rules with ARRAY OF CHAR length checks, sets, pointers, enumerations, NIL;
  • call arity (GNU optional parameters supported) and argument types, including open-array formals; ignored function results and void procedures used as values;
  • BOOLEAN conditions (IF, WHILE, ELSIF, UNTIL), ordinal CASE selectors and FOR variables/bounds/BY steps;
  • illegal targets (CONST, procedure, type, module), illegal operands (NOT/AND/OR, mixed arithmetic, DIV/MOD on reals, indexing, dereferencing, comparisons of arrays/records, CARDINAL vs INTEGER comparisons);
  • RETURN without a value, value-returning RETURNs, RETURN outside procedures and values returned from void procedures.

Still out of scope: use-before-declaration order, range checking, builtin-procedure signatures, record-field types, WITH-block internals.