瀏覽代碼

driver: clean process exit codes (0 ok, 1 compile errors, 2 usage/IO)

M2 previously exited 0 on compile errors and aborted (SIGABRT, rc 134)
on no/missing input. The driver now imports libc exit and uses
exit(0)/exit(1)/exit(2); missing-file messages name the file. Adds a
suite gate for the contract. Suite 206/206; fixpoint OK; corpus
unchanged (365 OK, 0 crash).
Eric Streit 19 小時之前
父節點
當前提交
e6c9612e81
共有 3 個文件被更改,包括 30 次插入 和 6 次删除
  1. 2 0
      README.md
  2. 14 0
      compiler/run_tests.sh
  3. 14 6
      compiler/src/compiler.frm

+ 2 - 0
README.md

@@ -28,6 +28,8 @@ Pipeline per test: `./M2 tests/foo.mod` writes
 `gen_ssa/FOO.ssa`; a global `VAR ExitCode : INTEGER` selects the
 process exit code (else 0). Reject tests assert on `.LST` messages;
 every error also prints as `file:line:col: message` on stdout.
+`M2` itself exits **0** on success, **1** on compile errors and **2** on
+usage/IO problems (no input, unopenable file) — no aborts.
 
 ## Layout (Blaise-adapted)
 

+ 14 - 0
compiler/run_tests.sh

@@ -524,6 +524,20 @@ twophase_run t_fwdsel.mod 42
 twophase_run t_fwdprop.mod 42
 twophase_fail t_bad_fwd.mod "incompatible assignment"
 
+# --- M2 process exit codes: 0 = ok, 1 = compile errors, 2 = usage/IO ---
+check_exit() {
+  # $1 = description, $2 = expected rc, rest = args
+  desc="$1"; want="$2"; shift 2
+  ./M2 "$@" >/dev/null 2>&1; got=$?
+  if [ "$got" = "$want" ]; then pass=$((pass+1)); echo "PASS(exit): $desc -> $got"
+  else fail=$((fail+1)); echo "FAIL(exit): $desc got $got want $want"; fi
+}
+
+check_exit "ok"          0 tests/t_minimal.mod
+check_exit "errors"      1 tests/t_bad_undecl.mod
+check_exit "no input"    2
+check_exit "missing file" 2 /tmp/opencode/_m2_no_such_file_.mod
+
 # --- step 7 gate: compiler sources free of gm2-only imports.
 #     FileIO is the last module to port (see docs/summary_step7.md);
 #     it is excluded here so the gate guards everything else. ---

+ 14 - 6
compiler/src/compiler.frm

@@ -13,6 +13,7 @@ MODULE -->Grammar;
     RefineActualCount, RefineActualGet, SetTwoPhase;
   IMPORT
     Strings, Storage, SYSTEM, FileIO, SymTab, QbeGen, AST, Lower;
+  FROM libc IMPORT exit;
     (* and any others needed *)
 
   TYPE
@@ -430,7 +431,8 @@ MODULE -->Grammar;
     END;
     IF nFiles = 0 THEN
       FileIO.WriteString(FileIO.StdOut, "No input file specified");
-      HALT
+      FileIO.WriteLn(FileIO.StdOut);
+      exit(2)
     END;
 
     BaseName(files[nFiles - 1], progName);
@@ -445,9 +447,10 @@ MODULE -->Grammar;
       Strings.Assign(files[f], sourceName);
       FileIO.Open(src, sourceName, FALSE);
       IF NOT FileIO.Okay THEN
-        FileIO.WriteString(FileIO.StdOut, "Could not open input file");
+        FileIO.WriteString(FileIO.StdOut, "Could not open input file: ");
+        FileIO.WriteString(FileIO.StdOut, sourceName);
         FileIO.WriteLn(FileIO.StdOut);
-        HALT
+        exit(2)
       END;
       ChangeExtension(sourceName, ".LST", listName);
       FileIO.Open(lst, listName, TRUE);
@@ -487,8 +490,13 @@ MODULE -->Grammar;
 
     Lower.EndSession;
 
-    IF bad OR NOT SymTab.HaveProgram()
-      THEN FileIO.WriteString(FileIO.StdOut, "Incorrect source")
-      ELSE FileIO.WriteString(FileIO.StdOut, "Parsed correctly")
+    IF bad OR NOT SymTab.HaveProgram() THEN
+      FileIO.WriteString(FileIO.StdOut, "Incorrect source");
+      FileIO.WriteLn(FileIO.StdOut);
+      exit(1)
+    ELSE
+      FileIO.WriteString(FileIO.StdOut, "Parsed correctly");
+      FileIO.WriteLn(FileIO.StdOut);
+      exit(0)
     END
   END -->Grammar.