]> Cypherpunks repositories - gostls13.git/commitdiff
- move error handling out of scanner
authorRobert Griesemer <gri@golang.org>
Tue, 25 Nov 2008 02:24:21 +0000 (18:24 -0800)
committerRobert Griesemer <gri@golang.org>
Tue, 25 Nov 2008 02:24:21 +0000 (18:24 -0800)
- use more of the existing library code

R=r
OCL=19957
CL=19959

usr/gri/pretty/compilation.go
usr/gri/pretty/scanner.go

index d52953f4b010585d51a4964586b322c02c17a312..5c47d85f40d56bd3d4db5d9485c004b0d0dae972 100644 (file)
@@ -29,15 +29,100 @@ export type Flags struct {
 }
 
 
+type ErrorHandler struct {
+       filename string;
+       src string;
+       nerrors int;
+       nwarnings int;
+       errpos int;
+       columns bool;
+}
+
+
+func (h *ErrorHandler) Init(filename, src string, columns bool) {
+       h.filename = filename;
+       h.src = src;
+       h.nerrors = 0;
+       h.nwarnings = 0;
+       h.errpos = 0;
+       h.columns = columns;
+}
+
+
+// Compute (line, column) information for a given source position.
+func (h *ErrorHandler) LineCol(pos int) (line, col int) {
+       line = 1;
+       lpos := 0;
+       
+       src := h.src;
+       if pos > len(src) {
+               pos = len(src);
+       }
+
+       for i := 0; i < pos; i++ {
+               if src[i] == '\n' {
+                       line++;
+                       lpos = i;
+               }
+       }
+       
+       return line, pos - lpos;
+}
+
+
+func (h *ErrorHandler) ErrorMsg(pos int, msg string) {
+       print(h.filename, ":");
+       if pos >= 0 {
+               // print position
+               line, col := h.LineCol(pos);
+               print(line, ":");
+               if h.columns {
+                       print(col, ":");
+               }
+       }
+       print(" ", msg, "\n");
+       
+       h.nerrors++;
+       h.errpos = pos;
+
+       if h.nerrors >= 10 {
+               sys.exit(1);
+       }
+}
+
+
+func (h *ErrorHandler) Error(pos int, msg string) {
+       // only report errors that are sufficiently far away from the previous error
+       // in the hope to avoid most follow-up errors
+       const errdist = 20;
+       delta := pos - h.errpos;  // may be negative!
+       if delta < 0 {
+               delta = -delta;
+       }
+       
+       if delta > errdist || h.nerrors == 0 /* always report first error */ {
+               h.ErrorMsg(pos, msg);
+       }       
+}
+
+
+func (h *ErrorHandler) Warning(pos int, msg string) {
+       panic("UNIMPLEMENTED");
+}
+
+
 export func Compile(src_file string, flags *Flags) (*AST.Program, int) {
        src, ok := Platform.ReadSourceFile(src_file);
        if !ok {
                print("cannot open ", src_file, "\n");
                return nil, 1;
        }
+       
+       var err ErrorHandler;
+       err.Init(src_file, src, flags.columns);
 
        var scanner Scanner.Scanner;
-       scanner.Open(src_file, src, flags.columns, flags.testmode);
+       scanner.Init(&err, src, flags.testmode);
 
        var tstream *<-chan *Scanner.Token;
        if flags.tokenchan {
@@ -48,7 +133,7 @@ export func Compile(src_file string, flags *Flags) (*AST.Program, int) {
        parser.Open(flags.verbose, flags.sixg, flags.deps, &scanner, tstream);
 
        prog := parser.ParseProgram();
-       return prog, scanner.nerrors;
+       return prog, err.nerrors;
 }
 
 
index 6aca9beb0f3c65dc5489d26868b4e60965b5ac37..b4df03f7e54d55c6f2759752c8381258bf6ded13 100644 (file)
@@ -3,6 +3,8 @@
 // license that can be found in the LICENSE file.
 
 package Scanner
+
+import "utf8"
 import Utils "utils"
 
 
@@ -276,15 +278,17 @@ func digit_val(ch int) int {
 }
 
 
+export type ErrorHandler interface {
+       Error(pos int, msg string);
+       Warning(pos int, msg string);
+}
+
+
 export type Scanner struct {
-       // error handling
-       filename string;  // error reporting only
-       nerrors int;  // number of errors
-       errpos int;  // last error position
-       columns bool;  // if set, print columns in error messages
+       err ErrorHandler;
 
        // scanning
-       src string;  // scanned source
+       src string;  // source
        pos int;  // current reading position
        ch int;  // one char look-ahead
        chpos int;  // position of ch
@@ -304,7 +308,7 @@ func (S *Scanner) Next() {
                r, w := int(S.src[S.pos]), 1;
                if r >= 0x80 {
                        // not ascii
-                       r, w = sys.stringtorune(S.src, S.pos);
+                       r, w = utf8.DecodeRuneInString(S.src, S.pos);
                }
                S.ch = r;
                S.chpos = S.pos;
@@ -313,144 +317,6 @@ func (S *Scanner) Next() {
                S.ch = -1;  // eof
                S.chpos = len(S.src);
        }
-/*
-       const (
-               Bit1 = 7;
-               Bitx = 6;
-               Bit2 = 5;
-               Bit3 = 4;
-               Bit4 = 3;
-
-               T1 = (1 << (Bit1 + 1) - 1) ^ 0xFF;  // 0000 0000
-               Tx = (1 << (Bitx + 1) - 1) ^ 0xFF;  // 1000 0000
-               T2 = (1 << (Bit2 + 1) - 1) ^ 0xFF;  // 1100 0000
-               T3 = (1 << (Bit3 + 1) - 1) ^ 0xFF;  // 1110 0000
-               T4 = (1 << (Bit4 + 1) - 1) ^ 0xFF;  // 1111 0000
-
-               Rune1 = 1 << (Bit1 + 0*Bitx) - 1;  // 0000 0000 0111 1111
-               Rune2 = 1 << (Bit2 + 1*Bitx) - 1;  // 0000 0111 1111 1111
-               Rune3 = 1 << (Bit3 + 2*Bitx) - 1;  // 1111 1111 1111 1111
-
-               Maskx = 0x3F;  // 1 << Bitx - 1;  // 0011 1111
-               Testx = 0xC0;  // Maskx ^ 0xFF;  // 1100 0000
-
-               Bad     = 0xFFFD;  // Runeerror
-       );
-
-       src := S.src;
-       lim := len(src);
-       pos := S.pos;
-       
-       // 1-byte sequence
-       // 0000-007F => T1
-       if pos >= lim {
-               S.ch = -1;  // end of file
-               S.chpos = lim;
-               return;
-       }
-       c0 := int(src[pos]);
-       pos++;
-       if c0 < Tx {
-               S.ch = c0;
-               S.chpos = S.pos;
-               S.pos = pos;
-               return;
-       }
-
-       // 2-byte sequence
-       // 0080-07FF => T2 Tx
-       if pos >= lim {
-               goto bad;
-       }
-       c1 := int(src[pos]) ^ Tx;
-       pos++;
-       if c1 & Testx != 0 {
-               goto bad;
-       }
-       if c0 < T3 {
-               if c0 < T2 {
-                       goto bad;
-               }
-               r := (c0 << Bitx | c1) & Rune2;
-               if  r <= Rune1 {
-                       goto bad;
-               }
-               S.ch = r;
-               S.chpos = S.pos;
-               S.pos = pos;
-               return;
-       }
-
-       // 3-byte sequence
-       // 0800-FFFF => T3 Tx Tx
-       if pos >= lim {
-               goto bad;
-       }
-       c2 := int(src[pos]) ^ Tx;
-       pos++;
-       if c2 & Testx != 0 {
-               goto bad;
-       }
-       if c0 < T4 {
-               r := (((c0 << Bitx | c1) << Bitx) | c2) & Rune3;
-               if r <= Rune2 {
-                       goto bad;
-               }
-               S.ch = r;
-               S.chpos = S.pos;
-               S.pos = pos;
-               return;
-       }
-
-       // bad encoding
-bad:
-       S.ch = Bad;
-       S.chpos = S.pos;
-       S.pos += 1;
-       return;
-*/
-}
-
-
-// Compute (line, column) information for a given source position.
-func (S *Scanner) LineCol(pos int) (line, col int) {
-       line = 1;
-       lpos := 0;
-       
-       src := S.src;
-       if pos > len(src) {
-               pos = len(src);
-       }
-
-       for i := 0; i < pos; i++ {
-               if src[i] == '\n' {
-                       line++;
-                       lpos = i;
-               }
-       }
-       
-       return line, pos - lpos;
-}
-
-
-func (S *Scanner) ErrorMsg(pos int, msg string) {
-       print(S.filename, ":");
-       if pos >= 0 {
-               // print position
-               line, col := S.LineCol(pos);
-               print(line, ":");
-               if S.columns {
-                       print(col, ":");
-               }
-       }
-       print(" ", msg, "\n");
-       
-       S.nerrors++;
-       S.errpos = pos;
-
-       if S.nerrors >= 10 {
-               sys.exit(1);
-       }
 }
 
 
@@ -464,17 +330,7 @@ func (S *Scanner) Error(pos int, msg string) {
                return;
        }
        
-       // only report errors that are sufficiently far away from the previous error
-       // in the hope to avoid most follow-up errors
-       const errdist = 20;
-       delta := pos - S.errpos;  // may be negative!
-       if delta < 0 {
-               delta = -delta;
-       }
-       
-       if delta > errdist || S.nerrors == 0 /* always report first error */ {
-               S.ErrorMsg(pos, msg);
-       }       
+       S.err.Error(pos, msg);
 }
 
 
@@ -485,11 +341,8 @@ func (S *Scanner) ExpectNoErrors() {
 }
 
 
-func (S *Scanner) Open(filename, src string, columns, testmode bool) {
-       S.filename = filename;
-       S.nerrors = 0;
-       S.errpos = 0;
-       S.columns = columns;
+func (S *Scanner) Init(err ErrorHandler, src string, testmode bool) {
+       S.err = err;
        
        S.src = src;
        S.pos = 0;
@@ -600,7 +453,7 @@ exit:
        
                if 0 <= oldpos && oldpos <= len(S.src) {
                        // the previous error was not found
-                       S.ErrorMsg(oldpos, "ERROR not found");
+                       S.Error(oldpos, "ERROR not found");  // TODO this should call ErrorMsg
                }
        }