Commit 9ec76279 authored by Robert Griesemer's avatar Robert Griesemer

- filed a bug against 6g (bug065.go)

- improved scanner.go error handling

SVN=126706
parent 2d7eecbb
// $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: '
*/
...@@ -33,7 +33,7 @@ hello, world ...@@ -33,7 +33,7 @@ hello, world
=========== ./readfile.go =========== ./readfile.go
=========== ./sieve.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 BUG: known to fail incorrectly
=========== ./simassign.go =========== ./simassign.go
...@@ -49,8 +49,6 @@ BUG: known to fail incorrectly ...@@ -49,8 +49,6 @@ BUG: known to fail incorrectly
=========== ./turing.go =========== ./turing.go
Hello World! Hello World!
=========== ./utf.go
=========== ken/for.go =========== ken/for.go
=========== ken/interfun.go =========== ken/interfun.go
...@@ -180,8 +178,8 @@ Faulting address: 0x1 ...@@ -180,8 +178,8 @@ Faulting address: 0x1
pc: 0x1349 pc: 0x1349
0x1349?zi 0x1349?zi
main·main(1, 0, 1606416464, ...) main·main(1, 0, 1606416456, ...)
main·main(0x1, 0x7fff5fbff850, 0x1, ...) main·main(0x1, 0x7fff5fbff848, 0x1, ...)
BUG: incorrect code for division BUG: incorrect code for division
...@@ -191,16 +189,16 @@ BUG: len should not be a keyword ...@@ -191,16 +189,16 @@ BUG: len should not be a keyword
=========== bugs/bug054.go =========== bugs/bug054.go
xxx xxx
. CALL u(100) l(218) <Element>I{} . CALL u(100) l(229) <Element>I{}
. . NAME-Vector_At G0 a(1) l(205) 111({},{}){} . . NAME-Vector_At G0 a(1) l(216) 111({},{}){}
. . AS u(1) l(218) . . AS u(1) l(229)
. . . INDREG a(1) l(218) v G0 *<Vector>{} . . . INDREG a(1) l(229) v G0 *<Vector>{}
. . . DOTPTR u(1) l(218) *<Vector>{} . . . DOTPTR u(1) l(229) *<Vector>{}
. . . . NAME-s G264 a(1) g(264) l(214) *<TStruct>{} . . . . NAME-s G279 a(1) g(279) l(225) *<TStruct>{}
. . . . NAME-fields G0 a(1) l(211) . . . . NAME-fields G0 a(1) l(222)
. . AS u(1) l(218) . . AS u(1) l(229)
. . . INDREG a(1) l(218) i G265 <int32>INT32 . . . INDREG a(1) l(229) i G280 <int32>INT32
. . . NAME-i G265 a(1) g(265) l(214) <int32>INT32 . . . NAME-i G280 a(1) g(280) l(225) <int32>INT32
bugs/bug054.go:25: fatal error: agen_inter i2s bugs/bug054.go:25: fatal error: agen_inter i2s
BUG: known to fail incorrectly BUG: known to fail incorrectly
...@@ -235,6 +233,10 @@ bugs/bug064.go:15: illegal types for operand: CALL ...@@ -235,6 +233,10 @@ bugs/bug064.go:15: illegal types for operand: CALL
({<u><int32>INT32;<v><int32>INT32;}) ({<u><int32>INT32;<v><int32>INT32;})
BUG: compilation should succeed BUG: compilation should succeed
=========== bugs/bug065.go
bugs/bug065.go:6: unknown escape sequence: '
BUG: compilation should succeed
=========== fixedbugs/bug000.go =========== fixedbugs/bug000.go
=========== fixedbugs/bug001.go =========== fixedbugs/bug001.go
...@@ -293,7 +295,7 @@ fixedbugs/bug035.go:7: var f redeclared in this block ...@@ -293,7 +295,7 @@ fixedbugs/bug035.go:7: var f redeclared in this block
=========== fixedbugs/bug037.go =========== fixedbugs/bug037.go
fixedbugs/bug037.go:6: vlong: undefined 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 =========== fixedbugs/bug038.go
......
...@@ -250,26 +250,12 @@ func digit_val (ch int) int { ...@@ -250,26 +250,12 @@ func digit_val (ch int) int {
export Scanner export Scanner
type Scanner struct { type Scanner struct {
src string; src string;
pos int; pos int; // current reading position
ch int; // one char look-ahead 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. // Read the next Unicode char into S.ch.
// S.ch < 0 means end-of-file. // S.ch < 0 means end-of-file.
// //
...@@ -306,12 +292,14 @@ func (S *Scanner) Next () { ...@@ -306,12 +292,14 @@ func (S *Scanner) Next () {
// 0000-007F => T1 // 0000-007F => T1
if pos >= lim { if pos >= lim {
S.ch = -1; // end of file S.ch = -1; // end of file
S.chpos = lim;
return; return;
} }
c0 := int(src[pos]); c0 := int(src[pos]);
pos++; pos++;
if c0 < Tx { if c0 < Tx {
S.ch = c0; S.ch = c0;
S.chpos = S.pos;
S.pos = pos; S.pos = pos;
return; return;
} }
...@@ -335,6 +323,7 @@ func (S *Scanner) Next () { ...@@ -335,6 +323,7 @@ func (S *Scanner) Next () {
goto bad; goto bad;
} }
S.ch = r; S.ch = r;
S.chpos = S.pos;
S.pos = pos; S.pos = pos;
return; return;
} }
...@@ -355,6 +344,7 @@ func (S *Scanner) Next () { ...@@ -355,6 +344,7 @@ func (S *Scanner) Next () {
goto bad; goto bad;
} }
S.ch = r; S.ch = r;
S.chpos = S.pos;
S.pos = pos; S.pos = pos;
return; return;
} }
...@@ -362,6 +352,7 @@ func (S *Scanner) Next () { ...@@ -362,6 +352,7 @@ func (S *Scanner) Next () {
// bad encoding // bad encoding
bad: bad:
S.ch = Bad; S.ch = Bad;
S.chpos = S.pos;
S.pos += 1; S.pos += 1;
return; return;
} }
...@@ -415,9 +406,59 @@ func (S *Scanner) Open (src string) { ...@@ -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) { func (S *Scanner) Expect (ch int) {
if S.ch != ch { 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 S.Next(); // make always progress
} }
...@@ -431,6 +472,7 @@ func (S *Scanner) SkipWhitespace () { ...@@ -431,6 +472,7 @@ func (S *Scanner) SkipWhitespace () {
func (S *Scanner) SkipComment () { func (S *Scanner) SkipComment () {
// '/' already consumed
if S.ch == '/' { if S.ch == '/' {
// comment // comment
S.Next(); S.Next();
...@@ -440,8 +482,8 @@ func (S *Scanner) SkipComment () { ...@@ -440,8 +482,8 @@ func (S *Scanner) SkipComment () {
} else { } else {
/* comment */ /* comment */
pos := S.pos; pos := S.chpos - 1;
S.Next(); S.Expect('*');
for S.ch >= 0 { for S.ch >= 0 {
ch := S.ch; ch := S.ch;
S.Next(); S.Next();
...@@ -534,7 +576,7 @@ func (S *Scanner) ScanDigits(n int, base int) { ...@@ -534,7 +576,7 @@ func (S *Scanner) ScanDigits(n int, base int) {
n--; n--;
} }
if n > 0 { 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 { ...@@ -543,6 +585,7 @@ func (S *Scanner) ScanEscape () string {
// TODO: fix this routine // TODO: fix this routine
ch := S.ch; ch := S.ch;
pos := S.chpos;
S.Next(); S.Next();
switch (ch) { switch (ch) {
case 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', '\'', '"': case 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', '\'', '"':
...@@ -565,7 +608,7 @@ func (S *Scanner) ScanEscape () string { ...@@ -565,7 +608,7 @@ func (S *Scanner) ScanEscape () string {
return ""; // TODO fix this return ""; // TODO fix this
default: default:
S.Error(S.pos, "illegal char escape"); S.Error(pos, "illegal char escape");
} }
} }
...@@ -587,12 +630,13 @@ func (S *Scanner) ScanChar () int { ...@@ -587,12 +630,13 @@ func (S *Scanner) ScanChar () int {
func (S *Scanner) ScanString () int { func (S *Scanner) ScanString () int {
// '"' already consumed // '"' already consumed
pos := S.pos - 1; // TODO maybe incorrect (Unicode) pos := S.chpos - 1;
for S.ch != '"' { for S.ch != '"' {
ch := S.ch; ch := S.ch;
S.Next(); S.Next();
if ch == '\n' || ch < 0 { if ch == '\n' || ch < 0 {
S.Error(pos, "string not terminated"); S.Error(pos, "string not terminated");
break;
} }
if ch == '\\' { if ch == '\\' {
S.ScanEscape(); S.ScanEscape();
...@@ -607,12 +651,13 @@ func (S *Scanner) ScanString () int { ...@@ -607,12 +651,13 @@ func (S *Scanner) ScanString () int {
func (S *Scanner) ScanRawString () int { func (S *Scanner) ScanRawString () int {
// '`' already consumed // '`' already consumed
pos := S.pos - 1; // TODO maybe incorrect (Unicode) pos := S.chpos - 1;
for S.ch != '`' { for S.ch != '`' {
ch := S.ch; ch := S.ch;
S.Next(); S.Next();
if ch == '\n' || ch < 0 { if ch == '\n' || ch < 0 {
S.Error(pos, "string not terminated"); S.Error(pos, "string not terminated");
break;
} }
} }
...@@ -672,7 +717,7 @@ func (S *Scanner) Scan () (tok, beg, end int) { ...@@ -672,7 +717,7 @@ func (S *Scanner) Scan () (tok, beg, end int) {
case is_letter(ch): tok = S.ScanIdentifier(); case is_letter(ch): tok = S.ScanIdentifier();
case digit_val(ch) < 10: tok = S.ScanNumber(false); case digit_val(ch) < 10: tok = S.ScanNumber(false);
default: default:
S.Next(); S.Next(); // always make progress
switch ch { switch ch {
case -1: tok = EOF; case -1: tok = EOF;
case '"': tok = S.ScanString(); case '"': tok = S.ScanString();
...@@ -712,18 +757,10 @@ func (S *Scanner) Scan () (tok, beg, end int) { ...@@ -712,18 +757,10 @@ func (S *Scanner) Scan () (tok, beg, end int) {
case '!': tok = S.Select2(NOT, NEQ); case '!': tok = S.Select2(NOT, NEQ);
case '&': tok = S.Select3(AND, AND_ASSIGN, '&', CAND); case '&': tok = S.Select3(AND, AND_ASSIGN, '&', CAND);
case '|': tok = S.Select3(OR, OR_ASSIGN, '|', COR); case '|': tok = S.Select3(OR, OR_ASSIGN, '|', COR);
default: tok = ILLEGAL;
} }
} }
end = S.pos - 1; end = S.pos - 1; // TODO correct? (Unicode)
/*
t.val = tok;
t.beg = beg;
t.end = end;
t.txt = S.src[beg : end];
*/
return tok, beg, end; return tok, beg, end;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment