var dotlist [10]Dlist // size is max depth of embeddeds
+// lexlineno is the line number _after_ the most recently read rune.
+// In particular, it's advanced (or rewound) as newlines are read (or unread).
var lexlineno int32
+// lineno is the line number at the start of the most recently lexed token.
var lineno int32
-var prevlineno int32
-
var pragcgobuf string
var infile string
)
func (l *lexer) next() {
- prevlineno = lineno
-
nlsemi := l.nlsemi
l.nlsemi = false
c := l.getr()
for isSpace(c) {
if c == '\n' && nlsemi {
- // TODO(gri) we may be able avoid the ungetr and simply use lexlineno-1 below
- l.ungetr(c) // for correct line number
if Debug['x'] != 0 {
fmt.Printf("lex: implicit semi\n")
}
- lineno = lexlineno
+ // Insert implicit semicolon on previous line,
+ // before the newline character.
+ lineno = lexlineno - 1
l.tok = ';'
return
}
lx:
if Debug['x'] != 0 {
if c > 0xff {
- fmt.Printf("%v lex: TOKEN %s\n", Ctxt.Line(int(lexlineno)), lexname(c))
+ fmt.Printf("%v lex: TOKEN %s\n", Ctxt.Line(int(lineno)), lexname(c))
} else {
- fmt.Printf("%v lex: TOKEN '%c'\n", Ctxt.Line(int(lexlineno)), c)
+ fmt.Printf("%v lex: TOKEN '%c'\n", Ctxt.Line(int(lineno)), c)
}
}
c := obj.Bgetc(l.bin)
if c < utf8.RuneSelf {
if c == 0 {
- // TODO(gri) do we need lineno = lexlineno here? Why not?
- Yyerror("illegal NUL byte")
+ yyerrorl(int(lexlineno), "illegal NUL byte")
return 0
}
if c == '\n' && importpkg == nil {
r, w := utf8.DecodeRune(buf[:i])
if r == utf8.RuneError && w == 1 {
- lineno = lexlineno
// The string conversion here makes a copy for passing
// to fmt.Printf, so that buf itself does not escape and
// can be allocated on the stack.
- Yyerror("illegal UTF-8 sequence % x", string(buf[:i]))
+ yyerrorl(int(lexlineno), "illegal UTF-8 sequence % x", string(buf[:i]))
}
if r == BOM {
- // TODO(gri) can we use Yyerror here? Why not?
yyerrorl(int(lexlineno), "Unicode (UTF-8) BOM in middle of file")
goto redo
}
}
// Like syntax_error, but reports error at given line rather than current lexer line.
-func (p *parser) syntax_error_at(lineno int32, msg string) {
- defer func(lineno int32) {
- lexlineno = lineno
- }(lexlineno)
- lexlineno = lineno
+func (p *parser) syntax_error_at(lno int32, msg string) {
+ defer func(lno int32) {
+ lineno = lno
+ }(lineno)
+ lineno = lno
p.syntax_error(msg)
}
ls = p.stmt()
if ls == missing_stmt {
// report error at line of ':' token
- p.syntax_error_at(prevlineno, "missing statement after label")
+ p.syntax_error_at(label.Lineno, "missing statement after label")
// we are already at the end of the labeled statement - no need to advance
return missing_stmt
}
return nil
}
-func (p *parser) dcl_name(sym *Sym) *Node {
+func (p *parser) dcl_name() *Node {
if trace && Debug['x'] != 0 {
defer p.trace("dcl_name")()
}
+ symlineno := lineno
+ sym := p.sym()
if sym == nil {
- yyerrorl(int(prevlineno), "invalid declaration")
+ yyerrorl(int(symlineno), "invalid declaration")
return nil
}
return dclname(sym)
defer p.trace("dcl_name_list")()
}
- l := list1(p.dcl_name(p.sym()))
+ l := list1(p.dcl_name())
for p.got(',') {
- l = list(l, p.dcl_name(p.sym()))
+ l = list(l, p.dcl_name())
}
return l
}
}
}
-var yyerror_lastsyntax int
+var yyerror_lastsyntax int32
func Yyerror(format string, args ...interface{}) {
msg := fmt.Sprintf(format, args...)
nsyntaxerrors++
// only one syntax error per line
- if int32(yyerror_lastsyntax) == lexlineno {
+ if yyerror_lastsyntax == lineno {
return
}
- yyerror_lastsyntax = int(lexlineno)
+ yyerror_lastsyntax = lineno
- // plain "syntax error" gets "near foo" added
- if msg == "syntax error" {
- yyerrorl(int(lexlineno), "syntax error near %s", lexbuf.String())
- return
- }
-
- yyerrorl(int(lexlineno), "%s", msg)
+ yyerrorl(int(lineno), "%s", msg)
return
}