Parcourir la source

fix: accept '_' in identifiers (ISO Modula-2)

The scanner's ident rule was letter { letter | digit }, so identifiers
with underscores were rejected: a variable like my_var was a hard error
(":" expected), while a module name like local_array_bug was silently
truncated to local and its body dropped (empty main).

Add '_' to the rule: ident = letter { letter | digit | "_" }.

This also explains the documented "local-array bug": local arrays are
fine; the repro's module name simply contained underscores.  Regression
tests/t_under.mod; docs/wip/local-array-bug.mod updated.

Suite 193/193; FIXPOINT OK (stage2 == stage3, 3,323,241 bytes).
Eric Streit il y a 1 semaine
Parent
commit
1570367808

+ 1 - 0
compiler/run_tests.sh

@@ -93,6 +93,7 @@ expect_run t_charbounds.mod 3
 expect_run t_record.mod 160
 expect_run t_recarr.mod 42
 expect_run t_nestarr.mod 42
+expect_run t_under.mod 42
 expect_run t_with.mod 114
 expect_run t_set.mod 131
 expect_run t_setchar.mod 77

+ 1 - 1
compiler/src/M2.atg

@@ -229,7 +229,7 @@ COMMENTS FROM "(*" TO "*)" NESTED
 COMMENTS FROM "//" TO lf
 
 TOKENS
-  ident   = letter { letter | digit } .
+  ident   = letter { letter | digit | "_" } .
   integer = digit { digit }
           | digit { digit } CONTEXT("..")
           | "0x" hexDigit { hexDigit }

+ 2 - 2
compiler/src/M2.lst

@@ -247,7 +247,7 @@ Listing:
   229  COMMENTS FROM "//" TO lf
   230  
   231  TOKENS
-  232    ident   = letter { letter | digit } .
+  232    ident   = letter { letter | digit | "_" } .
   233    integer = digit { digit }
   234            | digit { digit } CONTEXT("..")
   235            | "0x" hexDigit { hexDigit }
@@ -3847,6 +3847,6 @@ Statistics:
   nr of symbolnodes:     189 (limit   500)
   nr of graphnodes:     1107 (limit  1500)
   nr of conditionsets:    11 (limit   100)
-  nr of charactersets:    15 (limit   250)
+  nr of charactersets:    16 (limit   250)
 
 

+ 15 - 0
compiler/tests/t_under.mod

@@ -0,0 +1,15 @@
+MODULE TUnder;
+(* ISO identifiers may contain underscores; the scanner must accept them
+   (previously `my_var` lexed as `my` then `_var`).  Exit 42. *)
+VAR
+  my_var, ExitCode : INTEGER;
+
+PROCEDURE add_two (x : INTEGER) : INTEGER;
+BEGIN
+  RETURN x + 2
+END add_two;
+
+BEGIN
+  my_var := add_two(40);
+  ExitCode := my_var
+END TUnder.

+ 15 - 5
docs/wip/local-array-bug.mod

@@ -1,9 +1,19 @@
 MODULE local_array_bug;
-(* Repro: a local ARRAY inside a PROCEDURE is miscompiled by V3.
-   Expected exit 60; observed 1 (as of v3-ast-slice5, 2026-10-03).
-   Found while self-hosting the two-phase statement AST (IfStat used a
-   local ARRAY OF AST.Node); moved to module scope to keep the fixpoint
-   green.  Module-level arrays work; local ones do not. *)
+(* MISDIAGNOSED (2026-10-05).  The original report said a local ARRAY
+   inside a PROCEDURE was miscompiled.  The actual cause was the module
+   *name*: this grammar's scanner did not accept `_` in identifiers
+   (`ident = letter { letter | digit }`), so `local_array_bug` lexed as
+   `local` + `_array_bug` and the module body was silently dropped
+   (empty `main`).
+
+   FIXED: `M2.atg`'s ident rule now includes "_"
+   (`ident = letter { letter | digit | "_" }`), per ISO Modula-2.
+   Regression: compiler/tests/t_under.mod.
+
+   Local arrays themselves compile correctly; e.g. with a camelCase
+   module name this same program exits 60.  See also
+   tests/t_lower5arr.mod for local arrays of records and open-array
+   arguments. *)
 
 VAR ExitCode : INTEGER;