Sfoglia il codice sorgente

v1 sources to src/ (build with gm2 -I src, objects stay at root) plus real-comparison codegen fix (emit D5 before stack juggling, 158/158 tests green)

Eric Streit 3 settimane fa
parent
commit
ea1a294593

BIN
M2c


BIN
MC4/TRcmp.MC4


BIN
MC4/TReal.MC4


BIN
MGen.o


+ 14 - 7
build.sh

@@ -3,30 +3,37 @@
 # Builds the M2c compiler (step 2: scalars + MC64 backend).
 # Requires GNU Modula-2 (gm2) and the Coco/R CR binary.
 #
-# Usage: ./build.sh   (from the m2c directory)
+# Usage: ./build.sh   (from the project root)
 #
-# Pipeline: M2c.atg -> M2cS/M2cP/M2c (.mod) -> gm2 -fiso -> ./M2c
+# All sources live in src/ (grammar, frames, hand modules, generated
+# scanner/parser/driver). Build objects (.o) stay in the project root
+# (gm2 -I src drops them in the cwd); the binary links to ./M2c.
+#
+# Pipeline: src/M2c.atg -> src/M2cS/M2cP/M2c (.mod)
+#           -> gm2 -fiso -I src -> ./M2c
 #
 
 CRBIN="${CRBIN:-/home/eric/Projets/Projets-Modula2/MyWork/CocoGm2/CR}"
 
 echo "=== Regenerating M2cS / M2cP / M2c from M2c.atg ==="
+cd src || exit 1
 CRFRAMES="$(pwd)" "$CRBIN" -m -C M2c.atg || exit 1
+cd ..
 
 echo "=== Deleting all o files ==="
 rm -f ./*.o
 
 echo "=== Compiling the needed modules ==="
 for m in FileIO SymTab MGen M2cS M2cP M2c; do
-  gm2 -fiso -c "$m.mod" || exit 1
+  gm2 -fiso -I src -c "src/$m.mod" || exit 1
 done
 
 echo "=== Phase 1: generating the module list ==="
-gm2 -fiso -fgen-module-list=modules.lst -o /dev/null \
-    M2cS.o M2cP.o FileIO.o SymTab.o MGen.o M2c.mod || exit 1
+gm2 -fiso -I src -fgen-module-list=src/modules.lst -o /dev/null \
+    M2cS.o M2cP.o FileIO.o SymTab.o MGen.o src/M2c.mod || exit 1
 
 echo "=== Phase 2: compiling main module and linking using the module list ==="
-gm2 -fiso -fuse-list=modules.lst -o M2c \
-    M2cS.o M2cP.o FileIO.o SymTab.o MGen.o M2c.mod || exit 1
+gm2 -fiso -I src -fuse-list=src/modules.lst -o M2c \
+    M2cS.o M2cP.o FileIO.o SymTab.o MGen.o src/M2c.mod || exit 1
 
 echo "=== M2c built ==="

+ 15 - 0
docs/summary_step11.1.md

@@ -0,0 +1,15 @@
+# Step 11.1 — real-comparison codegen fix (tag: `step11.1`)
+
+Real `< > <= >=` never emitted `D5` (`0D5H`) — only `=` / `#`
+did. `RealLt/Le/Gt/Ge` (comments even said `[gt lt] -> ...`,
+inputs no caller provides) emitted bare stack juggling, leaving
+a raw operand bit-pattern as the boolean, so e.g. `-1.0 < 0.0`
+read back FALSE. The same recipe was shared with m2compiler-V2
+(found via its step-5.2 probe; full story in its
+`docs/summary_m2comp_step5.2.md`). `D5` itself was always
+correct — no VM change.
+
+Fix: one `OPrCmp` prepended per procedure (contracts now
+`[r1 r2]`). New regression `tests/t_rcmp.mod` (13 cases incl.
+negative-vs-zero and `-0.0`, ExitCode 31). Suite 158/158 with no
+other expectation touched (`t_real` passes genuinely now).

+ 1 - 0
run_tests.sh

@@ -189,6 +189,7 @@ expect_run t_repeat.mod 55
 expect_run t_loop.mod 7
 expect_run t_for.mod 85
 expect_run t_real.mod 31
+expect_run t_rcmp.mod 31
 expect_run t_char.mod 97
 expect_run t_enum.mod 1
 expect_run t_full.mod 74

+ 0 - 0
FileIO.def → src/FileIO.def


+ 0 - 0
FileIO.mod → src/FileIO.mod


+ 0 - 0
M2c.atg → src/M2c.atg


+ 0 - 0
M2c.err → src/M2c.err


+ 0 - 0
M2c.lst → src/M2c.lst


+ 0 - 0
M2c.mod → src/M2c.mod


+ 0 - 0
M2cP.def → src/M2cP.def


+ 0 - 0
M2cP.mod → src/M2cP.mod


+ 0 - 0
M2cS.def → src/M2cS.def


+ 0 - 0
M2cS.mod → src/M2cS.mod


+ 0 - 0
MGen.def → src/MGen.def


+ 13 - 8
MGen.mod → src/MGen.mod

@@ -1222,18 +1222,23 @@ PROCEDURE RealNe;
 (* [r1 r2] -> (r1 # r2): cmp, or. *)
   BEGIN EmitOp(OPrCmp); EmitOp(OPor) END RealNe;
 PROCEDURE RealLt;
-(* [gt lt] -> lt: swap, drop. *)
-  BEGIN EmitOp(OPswap); EmitOp(OPext); EmitOp(SUBdrop) END RealLt;
+(* [r1 r2] -> (r1 < r2): cmp, swap, drop. *)
+  BEGIN
+    EmitOp(OPrCmp); EmitOp(OPswap); EmitOp(OPext); EmitOp(SUBdrop)
+  END RealLt;
 PROCEDURE RealLe;
-(* [gt lt] -> NOT gt: drop, not. *)
-  BEGIN EmitOp(OPext); EmitOp(SUBdrop); EmitOp(OPnot) END RealLe;
+(* [r1 r2] -> (r1 <= r2): cmp, drop, not. *)
+  BEGIN
+    EmitOp(OPrCmp); EmitOp(OPext); EmitOp(SUBdrop); EmitOp(OPnot)
+  END RealLe;
 PROCEDURE RealGt;
-(* [gt lt] -> gt: drop. *)
-  BEGIN EmitOp(OPext); EmitOp(SUBdrop) END RealGt;
+(* [r1 r2] -> (r1 > r2): cmp, drop. *)
+  BEGIN EmitOp(OPrCmp); EmitOp(OPext); EmitOp(SUBdrop) END RealGt;
 PROCEDURE RealGe;
-(* [gt lt] -> NOT lt: swap, drop, not. *)
+(* [r1 r2] -> (r1 >= r2): cmp, swap, drop, not. *)
   BEGIN
-    EmitOp(OPswap); EmitOp(OPext); EmitOp(SUBdrop); EmitOp(OPnot)
+    EmitOp(OPrCmp); EmitOp(OPswap); EmitOp(OPext); EmitOp(SUBdrop);
+    EmitOp(OPnot)
   END RealGe;
 
 PROCEDURE NegInt;

+ 0 - 0
S4L.LST → src/S4L.LST


+ 0 - 0
S4L.def → src/S4L.def


+ 0 - 0
S4Limpl.LST → src/S4Limpl.LST


+ 0 - 0
S4Limpl.mod → src/S4Limpl.mod


+ 0 - 0
Showcase.LST → src/Showcase.LST


+ 0 - 0
Showcase.mod → src/Showcase.mod


+ 0 - 0
Showcase2.LST → src/Showcase2.LST


+ 0 - 0
Showcase2.mod → src/Showcase2.mod


+ 0 - 0
Showcase3.LST → src/Showcase3.LST


+ 0 - 0
Showcase3.mod → src/Showcase3.mod


+ 0 - 0
Showcase4.LST → src/Showcase4.LST


+ 0 - 0
Showcase4.mod → src/Showcase4.mod


+ 0 - 0
SymTab.def → src/SymTab.def


+ 0 - 0
SymTab.mod → src/SymTab.mod


+ 0 - 0
compiler.frm → src/compiler.frm


+ 0 - 0
modules.lst → src/modules.lst


+ 0 - 0
parser.frm → src/parser.frm


+ 0 - 0
scanner.frm → src/scanner.frm


+ 37 - 0
tests/t_rcmp.LST

@@ -0,0 +1,37 @@
+Listing:
+
+    1  MODULE TRcmp;
+    2  (* Real comparison regression test: < > <= >= must emit D5
+    3     (0D5H); they once emitted bare stack juggling, leaving operand
+    4     bits as the boolean (negative-vs-zero failures). ExitCode = 31:
+    5     bits 0-4 for the five true comparisons, none of the 64..4096
+    6     false-positive bits. *)
+    7  VAR ExitCode : INTEGER;
+    8      a, b, c, d, e, f, g, h, i, j, k, l : REAL;
+    9  BEGIN
+   10    a := -1.0; b := 0.0;
+   11    c := 0.0; d := -1.0;
+   12    e := -1.0; f := -1.0;
+   13    g := 0.0; h := 0.0;
+   14    i := -1.0; j := 0.0;
+   15    k := i * j;
+   16    l := 0.0;
+   17    ExitCode := 0;
+   18    IF a < b THEN ExitCode := ExitCode + 1 END;
+   19    IF c > d THEN ExitCode := ExitCode + 2 END;
+   20    IF e = f THEN ExitCode := ExitCode + 4 END;
+   21    IF g = h THEN ExitCode := ExitCode + 8 END;
+   22    IF k = l THEN ExitCode := ExitCode + 16 END;
+   23    IF a > b THEN ExitCode := ExitCode + 32 END;
+   24    IF a = b THEN ExitCode := ExitCode + 64 END;
+   25    IF c < d THEN ExitCode := ExitCode + 128 END;
+   26    IF c = d THEN ExitCode := ExitCode + 256 END;
+   27    IF e < f THEN ExitCode := ExitCode + 512 END;
+   28    IF e > f THEN ExitCode := ExitCode + 1024 END;
+   29    IF k < l THEN ExitCode := ExitCode + 2048 END;
+   30    IF k > l THEN ExitCode := ExitCode + 4096 END
+   31  END TRcmp.
+
+    0 errors
+
+

+ 31 - 0
tests/t_rcmp.mod

@@ -0,0 +1,31 @@
+MODULE TRcmp;
+(* Real comparison regression test: < > <= >= must emit D5
+   (0D5H); they once emitted bare stack juggling, leaving operand
+   bits as the boolean (negative-vs-zero failures). ExitCode = 31:
+   bits 0-4 for the five true comparisons, none of the 64..4096
+   false-positive bits. *)
+VAR ExitCode : INTEGER;
+    a, b, c, d, e, f, g, h, i, j, k, l : REAL;
+BEGIN
+  a := -1.0; b := 0.0;
+  c := 0.0; d := -1.0;
+  e := -1.0; f := -1.0;
+  g := 0.0; h := 0.0;
+  i := -1.0; j := 0.0;
+  k := i * j;
+  l := 0.0;
+  ExitCode := 0;
+  IF a < b THEN ExitCode := ExitCode + 1 END;
+  IF c > d THEN ExitCode := ExitCode + 2 END;
+  IF e = f THEN ExitCode := ExitCode + 4 END;
+  IF g = h THEN ExitCode := ExitCode + 8 END;
+  IF k = l THEN ExitCode := ExitCode + 16 END;
+  IF a > b THEN ExitCode := ExitCode + 32 END;
+  IF a = b THEN ExitCode := ExitCode + 64 END;
+  IF c < d THEN ExitCode := ExitCode + 128 END;
+  IF c = d THEN ExitCode := ExitCode + 256 END;
+  IF e < f THEN ExitCode := ExitCode + 512 END;
+  IF e > f THEN ExitCode := ExitCode + 1024 END;
+  IF k < l THEN ExitCode := ExitCode + 2048 END;
+  IF k > l THEN ExitCode := ExitCode + 4096 END
+END TRcmp.