Jelajahi Sumber

v3 step 1.5 — file:line:col console errors via shared ErrText (9/9 tests green)

Eric Streit 3 minggu lalu
induk
melakukan
342bb966cc
1 mengubah file dengan 71 tambahan dan 24 penghapusan
  1. 71 24
      compiler/src/compiler.frm

+ 71 - 24
compiler/src/compiler.frm

@@ -16,11 +16,12 @@ MODULE -->Grammar;
 
   MODULE ListHandler;
   (* ------------------- Source Listing and Error handler -------------- *)
-    FROM FileIO IMPORT CR, LF, EOF, WriteString, Write, WriteLn, WriteInt, Long0;
+    FROM FileIO IMPORT CR, LF, EOF, File, StdOut,
+      WriteString, Write, WriteLn, WriteInt, Long0;
     FROM Storage IMPORT ALLOCATE;
     FROM SYSTEM IMPORT TSIZE;
     IMPORT lst, CharAt, errors, INT32;
-    EXPORT StoreError, PrintListing;
+    EXPORT StoreError, PrintListing, PrintConsoleErrors;
 
     TYPE
       Err = POINTER TO ErrDesc;
@@ -71,32 +72,15 @@ MODULE -->Grammar;
         END
       END GetLine;
 
-    PROCEDURE PrintErr (line: ARRAY OF CHAR; nr, col: INTEGER);
-    (* Print an error message *)
+    PROCEDURE ErrText (nr: INTEGER; f: File);
+    (* Error message text for nr on file f (listing and console share it) *)
 
       PROCEDURE Msg (s: ARRAY OF CHAR);
         BEGIN
-          WriteString(lst, s)
+          WriteString(f, s)
         END Msg;
 
-      PROCEDURE Pointer;
-        VAR
-          i: INTEGER;
-        BEGIN
-          WriteString(lst, "*****  ");
-          i := 0;
-          WHILE i < col + Extra - 2 DO
-            IF line[i] = tab
-              THEN Write(lst, tab)
-              ELSE Write(lst, ' ')
-            END;
-            INC(i)
-          END;
-          WriteString(lst, "^ ")
-        END Pointer;
-
       BEGIN
-        Pointer;
         CASE nr OF
         -->Errors
         (* add customized cases here *)
@@ -119,8 +103,32 @@ MODULE -->Grammar;
         | 223: Msg("cyclical type definition")
         | 224: Msg("ordinal type required")
         | 230: Msg("not supported yet")
-        ELSE         Msg("Error: "); WriteInt(lst, nr, 0);
-        END;
+        ELSE         Msg("Error: "); WriteInt(f, nr, 0);
+        END
+      END ErrText;
+
+    PROCEDURE PrintErr (line: ARRAY OF CHAR; nr, col: INTEGER);
+    (* Print an error message *)
+
+      PROCEDURE Pointer;
+        VAR
+          i: INTEGER;
+        BEGIN
+          WriteString(lst, "*****  ");
+          i := 0;
+          WHILE i < col + Extra - 2 DO
+            IF line[i] = tab
+              THEN Write(lst, tab)
+              ELSE Write(lst, ' ')
+            END;
+            INC(i)
+          END;
+          WriteString(lst, "^ ")
+        END Pointer;
+
+      BEGIN
+        Pointer;
+        ErrText(nr, lst);
         WriteLn(lst)
       END PrintErr;
 
@@ -159,6 +167,44 @@ MODULE -->Grammar;
         WriteLn(lst); WriteLn(lst); WriteLn(lst);
       END PrintListing;
 
+    PROCEDURE PrintConsoleErrors (fname: ARRAY OF CHAR);
+    (* "file:line:col: message" errors on StdOut, for editor
+       integration. Columns are 1-based token starts, matching the
+       listing carets (NOT the col-1 of CRQ.FRM). *)
+
+      PROCEDURE WriteNum (n: INTEGER);
+      (* FileIO.WriteInt pads a leading blank; editors want none. *)
+        VAR
+          buf: ARRAY [0 .. 15] OF CHAR;
+          i: CARDINAL;
+        BEGIN
+          IF n < 0 THEN Write(StdOut, "-"); n := -n END;
+          i := 0;
+          IF n = 0 THEN buf[0] := "0"; i := 1 END;
+          WHILE (n > 0) & (i <= HIGH(buf)) DO
+            buf[i] := CHR(ORD("0") + VAL(CARDINAL, n MOD 10));
+            n := n DIV 10; INC(i)
+          END;
+          WHILE i > 0 DO DEC(i); Write(StdOut, buf[i]) END
+        END WriteNum;
+
+      VAR
+        e: Err;
+      BEGIN
+        e := firstErr;
+        WHILE e # NIL DO
+          WriteString(StdOut, fname);
+          Write(StdOut, ":");
+          WriteNum(e^.line);
+          Write(StdOut, ":");
+          WriteNum(e^.col);
+          WriteString(StdOut, ": ");
+          ErrText(e^.nr, StdOut);
+          WriteLn(StdOut);
+          e := e^.next
+        END
+      END PrintConsoleErrors;
+
     BEGIN
       firstErr := NIL; Extra := 1;
     END ListHandler;
@@ -232,6 +278,7 @@ MODULE -->Grammar;
     (* examine the outcome *)
     IF NOT Successful()
       THEN
+        PrintConsoleErrors(sourceName);
         FileIO.WriteString(FileIO.StdOut, "Incorrect source");
       ELSE
         FileIO.WriteString(FileIO.StdOut, "Parsed correctly");