]> Cypherpunks repositories - gostls13.git/commitdiff
- filed a bug against 6g (bug065.go)
authorRobert Griesemer <gri@golang.org>
Thu, 10 Jul 2008 20:45:02 +0000 (13:45 -0700)
committerRobert Griesemer <gri@golang.org>
Thu, 10 Jul 2008 20:45:02 +0000 (13:45 -0700)
- improved scanner.go error handling

SVN=126706

test/bugs/bug065.go [new file with mode: 0644]
test/golden.out
usr/gri/src/scanner.go

diff --git a/test/bugs/bug065.go b/test/bugs/bug065.go
new file mode 100644 (file)
index 0000000..d7d5f74
--- /dev/null
@@ -0,0 +1,17 @@
+// $G $D/$F.go && $L $F.$A && ./$A.out
+
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+const c = '\'';  // this works
+const s = "\'";  // this doesn't
+
+/*
+There is no reason why the escapes need to be different inside strings and chars.
+
+uetli:~/go/test/bugs gri$ 6g bug065.go
+bug065.go:6: unknown escape sequence: '
+*/
index 33a60da35d89ba56ee3c765ad63f72193b7f067f..1e6283efcae52c8b094ff6bec8c77bc8a77a1a0f 100644 (file)
@@ -33,7 +33,7 @@ hello, world
 =========== ./readfile.go
 
 =========== ./sieve.go
-sieve.go:8: fatal error: walktype: switch 1 unknown op SEND l(201)
+sieve.go:8: fatal error: walktype: switch 1 unknown op SEND l(212)
 BUG: known to fail incorrectly
 
 =========== ./simassign.go
@@ -49,8 +49,6 @@ BUG: known to fail incorrectly
 =========== ./turing.go
 Hello World!
 
-=========== ./utf.go
-
 =========== ken/for.go
 
 =========== ken/interfun.go
@@ -180,8 +178,8 @@ Faulting address: 0x1
 pc: 0x1349
 
 0x1349?zi
-       main·main(1, 0, 1606416464, ...)
-       main·main(0x1, 0x7fff5fbff850, 0x1, ...)
+       main·main(1, 0, 1606416456, ...)
+       main·main(0x1, 0x7fff5fbff848, 0x1, ...)
 
 BUG: incorrect code for division
 
@@ -191,16 +189,16 @@ BUG: len should not be a keyword
 
 =========== bugs/bug054.go
 xxx
-.   CALL u(100) l(218) <Element>I{}
-.   .   NAME-Vector_At G0 a(1) l(205) 111({},{}){}
-.   .   AS u(1) l(218)
-.   .   .   INDREG a(1) l(218) v G0 *<Vector>{}
-.   .   .   DOTPTR u(1) l(218) *<Vector>{}
-.   .   .   .   NAME-s G264 a(1) g(264) l(214) *<TStruct>{}
-.   .   .   .   NAME-fields G0 a(1) l(211)
-.   .   AS u(1) l(218)
-.   .   .   INDREG a(1) l(218) i G265 <int32>INT32
-.   .   .   NAME-i G265 a(1) g(265) l(214) <int32>INT32
+.   CALL u(100) l(229) <Element>I{}
+.   .   NAME-Vector_At G0 a(1) l(216) 111({},{}){}
+.   .   AS u(1) l(229)
+.   .   .   INDREG a(1) l(229) v G0 *<Vector>{}
+.   .   .   DOTPTR u(1) l(229) *<Vector>{}
+.   .   .   .   NAME-s G279 a(1) g(279) l(225) *<TStruct>{}
+.   .   .   .   NAME-fields G0 a(1) l(222)
+.   .   AS u(1) l(229)
+.   .   .   INDREG a(1) l(229) i G280 <int32>INT32
+.   .   .   NAME-i G280 a(1) g(280) l(225) <int32>INT32
 bugs/bug054.go:25: fatal error: agen_inter i2s
 BUG: known to fail incorrectly
 
@@ -235,6 +233,10 @@ bugs/bug064.go:15: illegal types for operand: CALL
        ({<u><int32>INT32;<v><int32>INT32;})
 BUG: compilation should succeed
 
+=========== bugs/bug065.go
+bugs/bug065.go:6: unknown escape sequence: '
+BUG: compilation should succeed
+
 =========== fixedbugs/bug000.go
 
 =========== fixedbugs/bug001.go
@@ -293,7 +295,7 @@ fixedbugs/bug035.go:7: var f redeclared in this block
 
 =========== fixedbugs/bug037.go
 fixedbugs/bug037.go:6: vlong: undefined
-fixedbugs/bug037.go:6: fatal error: addvar: n=NAME-s G0 a(1) l(199) t=<T> nil
+fixedbugs/bug037.go:6: fatal error: addvar: n=NAME-s G0 a(1) l(210) t=<T> nil
 
 =========== fixedbugs/bug038.go
 
index 37778033e41ae67b9daafcd20c1422d90f8292bf..7389cdac3fd40af466998909571f04e4eea4242c 100644 (file)
@@ -250,26 +250,12 @@ func digit_val (ch int) int {
 export Scanner
 type Scanner struct {
        src string;
-       pos int;
+       pos int;  // current reading position
        ch int;  // one char look-ahead
+       chpos int;  // position of ch
 }
 
 
-/*
-export Token
-type Token struct {
-       val int;
-       beg, end int;
-       txt string;
-}
-
-
-func (T *Token) Print () {
-       print TokenName(T.val), " [", T.beg, ", ", T.end, "[ ", T.txt, "\n";
-}
-*/
-
-
 // Read the next Unicode char into S.ch.
 // S.ch < 0 means end-of-file.
 //
@@ -306,12 +292,14 @@ func (S *Scanner) Next () {
        // 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;
        }
@@ -335,6 +323,7 @@ func (S *Scanner) Next () {
                        goto bad;
                }
                S.ch = r;
+               S.chpos = S.pos;
                S.pos = pos;
                return;
        }
@@ -355,6 +344,7 @@ func (S *Scanner) Next () {
                        goto bad;
                }
                S.ch = r;
+               S.chpos = S.pos;
                S.pos = pos;
                return;
        }
@@ -362,6 +352,7 @@ func (S *Scanner) Next () {
        // bad encoding
 bad:
        S.ch = Bad;
+       S.chpos = S.pos;
        S.pos += 1;
        return;
 }
@@ -415,9 +406,59 @@ func (S *Scanner) Open (src string) {
 }
 
 
+// TODO this needs to go elsewhere
+func IntString(x, base int) string {
+       neg := false;
+       if x < 0 {
+               x = -x;
+               if x < 0 {
+                       panic "smallest int not handled";
+               }
+               neg = true;
+       }
+
+       hex := "0123456789ABCDEF";
+       var buf [16] byte;
+       i := 0;
+       for x > 0 || i == 0 {
+               buf[i] = hex[x % base];
+               x /= base;
+               i++;
+       }
+       
+       s := "";
+       if neg {
+               s = "-";
+       }
+       for i > 0 {
+               i--;
+               s = s + string(int(buf[i]));
+       }
+       return s;
+}
+
+
+
+func CharString(ch int) string {
+       s := string(ch);
+       switch ch {
+       case '\a': s = "\\a";
+       case '\b': s = "\\b";
+       case '\f': s = "\\f";
+       case '\n': s = "\\n";
+       case '\r': s = "\\r";
+       case '\t': s = "\\t";
+       case '\v': s = "\\v";
+       case '\\': s = "\\";
+       case '\'': s = "\\'";
+       }
+       return "'" + s + "' (U+" + IntString(ch, 16) + ")";
+}
+
+
 func (S *Scanner) Expect (ch int) {
        if S.ch != ch {
-               S.Error(S.pos, "expected " + string(ch) + ", found " + string(S.ch));
+               S.Error(S.chpos, "expected " + CharString(ch) + ", found " + CharString(S.ch));
        }
        S.Next();  // make always progress
 }
@@ -431,6 +472,7 @@ func (S *Scanner) SkipWhitespace () {
 
 
 func (S *Scanner) SkipComment () {
+       // '/' already consumed
        if S.ch == '/' {
                // comment
                S.Next();
@@ -440,8 +482,8 @@ func (S *Scanner) SkipComment () {
                
        } else {
                /* comment */
-               pos := S.pos;
-               S.Next();
+               pos := S.chpos - 1;
+               S.Expect('*');
                for S.ch >= 0 {
                        ch := S.ch;
                        S.Next();
@@ -534,7 +576,7 @@ func (S *Scanner) ScanDigits(n int, base int) {
                n--;
        }
        if n > 0 {
-               S.Error(S.pos, "illegal char escape");
+               S.Error(S.chpos, "illegal char escape");
        }
 }
 
@@ -543,6 +585,7 @@ func (S *Scanner) ScanEscape () string {
        // TODO: fix this routine
        
        ch := S.ch;
+       pos := S.chpos;
        S.Next();
        switch (ch) {
        case 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', '\'', '"':
@@ -565,7 +608,7 @@ func (S *Scanner) ScanEscape () string {
                return "";  // TODO fix this
 
        default:
-               S.Error(S.pos, "illegal char escape");
+               S.Error(pos, "illegal char escape");
        }
 }
 
@@ -587,12 +630,13 @@ func (S *Scanner) ScanChar () int {
 func (S *Scanner) ScanString () int {
        // '"' already consumed
 
-       pos := S.pos - 1;  // TODO maybe incorrect (Unicode)
+       pos := S.chpos - 1;
        for S.ch != '"' {
                ch := S.ch;
                S.Next();
                if ch == '\n' || ch < 0 {
                        S.Error(pos, "string not terminated");
+                       break;
                }
                if ch == '\\' {
                        S.ScanEscape();
@@ -607,12 +651,13 @@ func (S *Scanner) ScanString () int {
 func (S *Scanner) ScanRawString () int {
        // '`' already consumed
 
-       pos := S.pos - 1;  // TODO maybe incorrect (Unicode)
+       pos := S.chpos - 1;
        for S.ch != '`' {
                ch := S.ch;
                S.Next();
                if ch == '\n' || ch < 0 {
                        S.Error(pos, "string not terminated");
+                       break;
                }
        }
 
@@ -672,7 +717,7 @@ func (S *Scanner) Scan () (tok, beg, end int) {
        case is_letter(ch): tok = S.ScanIdentifier();
        case digit_val(ch) < 10: tok = S.ScanNumber(false);
        default:
-               S.Next();
+               S.Next();  // always make progress
                switch ch {
                case -1: tok = EOF;
                case '"': tok = S.ScanString();
@@ -712,18 +757,10 @@ func (S *Scanner) Scan () (tok, beg, end int) {
                case '!': tok = S.Select2(NOT, NEQ);
                case '&': tok = S.Select3(AND, AND_ASSIGN, '&', CAND);
                case '|': tok = S.Select3(OR, OR_ASSIGN, '|', COR);
-               default: tok = ILLEGAL;
                }
        }
        
-       end = S.pos - 1;
-       
-       /*
-       t.val = tok;
-       t.beg = beg;
-       t.end = end;
-       t.txt = S.src[beg : end];
-       */
+       end = S.pos - 1;  // TODO correct? (Unicode)
        
        return tok, beg, end;
 }