Eric Streit 23761556eb Ulm-Oberon validator pilot (ulmo oracle, builds, tests) 3 giorni fa
..
tests 23761556eb Ulm-Oberon validator pilot (ulmo oracle, builds, tests) 3 giorni fa
README.md 23761556eb Ulm-Oberon validator pilot (ulmo oracle, builds, tests) 3 giorni fa
build.sh 23761556eb Ulm-Oberon validator pilot (ulmo oracle, builds, tests) 3 giorni fa
ulm_oberon.atg 23761556eb Ulm-Oberon validator pilot (ulmo oracle, builds, tests) 3 giorni fa

README.md

Ulm-Oberon validator pilot

ulm_oberon.atg describes classic Oberon as implemented by ulmo, ported from the reference (Grammars/Ulm/Ulml-Oberon.atg, extracted from ulmo's own OberonParser). The reference is written for a newer Coco/R generation (/* */ comments, implicit whitespace), so the port starts with: comment conversion, explicit IGNORE CASE, IGNORE CHR(9)..CHR(13), COMMENTS FROM "(*" TO "*)" NESTED, and a CHR(10) eol set. It then needed the same repair family as the Oberon-2 pilot, all diagnosed against ulmo (frontend verdicts only — its backend crashes with an assertion on valid code, exit still 0, so the harness reads ** markers, never exit codes):

  1. Duplicate CASE labels in statement: ident-led assignment vs ProcedureCall merged into IdentTail.
  2. The optional-prefix trap in qualident ([ident "."] committed on any identifier): ident { "." ident }.
  3. The designator guard "(" qualident ")" shadowed calls with non-identifier arguments: "(" [ ExpList ] ")".
  4. Missing ; after the module header ident (reference parses MODULE T then expects END).
  5. DEFINITION modules need bodyless procedures, but an optional body greedily eats the module's END: split into DefinitionModule (bodyless DefProcDecl) vs Module (body required) — disjoint DEFINITION/MODULE keywords, no greediness possible.
  6. Strings are "-quoted in Ulm Oberon ('hi' is "invalid string delimiter"); single-quote chars like 'a' do not exist (41X hex form does).

Ulm facts confirmed by probe: case-insensitive, CASE with | and ELSE, LOOP/EXIT, RETURN with value, &/~, IN, WITH guarded-pointer only, declaration order enforced (ulmo rejects VAR after procedures — the validator stays order-free, documented leniency), filenames must match module names, backend assertion crashes are ignored (frontend-only rule).

Build

./build.sh        # -> build/Ulm (build/ is git-ignored)

Needs CR (Coco/R), gm2 -fiso, the parser.frm/scanner.frm frames and FileIO.def/.mod — all resolved from the environment with sensible defaults (CRFRAMES, M2LIB, CR, GM2).

Differential results (Ulm vs ulmo, frontend)

Accept battery (15 cases: all statements, CASE/ELSE, LOOP/ EXIT, ORD, floats, RETURN) + tests/deep.mod (records, pointers, multi-dim arrays, nested routines, guarded WITH): 0 false positives. Broken mutants (8): 0 missed, positions close. (i := 1 without ; is accepted by ulmo too — separator leniency, correctly skipped.)