|
|
@@ -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");
|