type lexer struct {
// TODO(gri) move other lexer state here and out of global variables
// (source, current line number, etc.)
+ nlsemi bool // if set, '\n' and EOF translate to ';'
// current token
tok int32
LRSH
)
-func (yylval *lexer) _yylex() int32 {
+func (l *lexer) next() {
var c1 int
var op Op
var escflag int
prevlineno = lineno
+ nlsemi := l.nlsemi
+ l.nlsemi = false
+
l0:
+ // skip white space
c := getc()
- if isSpace(c) {
- if c == '\n' && curio.nlsemi {
+ for isSpace(c) {
+ if c == '\n' && nlsemi {
ungetc(c)
if Debug['x'] != 0 {
fmt.Printf("lex: implicit semi\n")
}
- return ';'
+ l.tok = ';'
+ return
}
-
- goto l0
+ c = getc()
}
- lineno = lexlineno // start of token
+ // start of token
+ lineno = lexlineno
if c >= utf8.RuneSelf {
// all multibyte runes are alpha
cp = &lexbuf
cp.Reset()
-
goto talph
}
case EOF:
lineno = prevlineno
ungetc(EOF)
- return -1
+ // Treat EOF as "end of line" for the purposes
+ // of inserting a semicolon.
+ if nlsemi {
+ if Debug['x'] != 0 {
+ fmt.Printf("lex: implicit semi\n")
+ }
+ l.tok = ';'
+ return
+ }
+ l.tok = -1
+ return
case '_':
cp = &lexbuf
}
x := new(Mpint)
- yylval.val.U = x
+ l.val.U = x
Mpmovecfix(x, v)
x.Rune = true
if Debug['x'] != 0 {
fmt.Printf("lex: codepoint literal\n")
}
litbuf = "string literal"
- return LLITERAL
+ l.nlsemi = true
+ l.tok = LLITERAL
+ return
case '/':
c1 = getc()
case '+':
c1 = getc()
if c1 == '+' {
+ l.nlsemi = true
c = int(LINC)
goto lx
}
case '-':
c1 = getc()
if c1 == '-' {
+ l.nlsemi = true
c = int(LDEC)
goto lx
}
goto asop
}
+ case ')', ']', '}':
+ l.nlsemi = true
+ goto lx
+
default:
goto lx
}
goto l0
}
- return int32(c)
+ l.tok = int32(c)
+ return
asop:
- yylval.op = op
+ l.op = op
if Debug['x'] != 0 {
fmt.Printf("lex: TOKEN ASOP %s=\n", goopnames[op])
}
- return LASOP
+ l.tok = LASOP
+ return
// cp is set to lexbuf and some
// prefix has been stored
if Debug['x'] != 0 {
fmt.Printf("lex: %s %s\n", s, lexname(int(s.Lexical)))
}
- yylval.sym_ = s
- return int32(s.Lexical)
+ l.sym_ = s
+ switch s.Lexical {
+ case LNAME, LRETURN, LBREAK, LCONTINUE, LFALL:
+ l.nlsemi = true
+ }
+ l.tok = int32(s.Lexical)
+ return
ncu:
cp = nil
ungetc(c)
str = lexbuf.String()
- yylval.val.U = new(Mpint)
- mpatofix(yylval.val.U.(*Mpint), str)
- if yylval.val.U.(*Mpint).Ovf {
+ l.val.U = new(Mpint)
+ mpatofix(l.val.U.(*Mpint), str)
+ if l.val.U.(*Mpint).Ovf {
Yyerror("overflow in constant")
- Mpmovecfix(yylval.val.U.(*Mpint), 0)
+ Mpmovecfix(l.val.U.(*Mpint), 0)
}
if Debug['x'] != 0 {
fmt.Printf("lex: integer literal\n")
}
litbuf = "literal " + str
- return LLITERAL
+ l.nlsemi = true
+ l.tok = LLITERAL
+ return
casedot:
for {
cp = nil
str = lexbuf.String()
- yylval.val.U = new(Mpcplx)
- Mpmovecflt(&yylval.val.U.(*Mpcplx).Real, 0.0)
- mpatoflt(&yylval.val.U.(*Mpcplx).Imag, str)
- if yylval.val.U.(*Mpcplx).Imag.Val.IsInf() {
+ l.val.U = new(Mpcplx)
+ Mpmovecflt(&l.val.U.(*Mpcplx).Real, 0.0)
+ mpatoflt(&l.val.U.(*Mpcplx).Imag, str)
+ if l.val.U.(*Mpcplx).Imag.Val.IsInf() {
Yyerror("overflow in imaginary constant")
- Mpmovecflt(&yylval.val.U.(*Mpcplx).Imag, 0.0)
+ Mpmovecflt(&l.val.U.(*Mpcplx).Imag, 0.0)
}
if Debug['x'] != 0 {
fmt.Printf("lex: imaginary literal\n")
}
litbuf = "literal " + str
- return LLITERAL
+ l.nlsemi = true
+ l.tok = LLITERAL
+ return
caseout:
cp = nil
ungetc(c)
str = lexbuf.String()
- yylval.val.U = newMpflt()
- mpatoflt(yylval.val.U.(*Mpflt), str)
- if yylval.val.U.(*Mpflt).Val.IsInf() {
+ l.val.U = newMpflt()
+ mpatoflt(l.val.U.(*Mpflt), str)
+ if l.val.U.(*Mpflt).Val.IsInf() {
Yyerror("overflow in float constant")
- Mpmovecflt(yylval.val.U.(*Mpflt), 0.0)
+ Mpmovecflt(l.val.U.(*Mpflt), 0.0)
}
if Debug['x'] != 0 {
fmt.Printf("lex: floating literal\n")
}
litbuf = "literal " + str
- return LLITERAL
+ l.nlsemi = true
+ l.tok = LLITERAL
+ return
strlit:
- yylval.val.U = internString(cp.Bytes())
+ l.val.U = internString(cp.Bytes())
if Debug['x'] != 0 {
fmt.Printf("lex: string literal\n")
}
litbuf = "string literal"
- return LLITERAL
+ l.nlsemi = true
+ l.tok = LLITERAL
}
var internedStrings = map[string]string{}
}
}
-func (l *lexer) next() {
- tok := l._yylex()
-
- if curio.nlsemi && tok == EOF {
- // Treat EOF as "end of line" for the purposes
- // of inserting a semicolon.
- tok = ';'
- }
-
- switch tok {
- case LNAME,
- LLITERAL,
- LBREAK,
- LCONTINUE,
- LFALL,
- LRETURN,
- LINC,
- LDEC,
- ')',
- '}',
- ']':
- curio.nlsemi = true
-
- default:
- curio.nlsemi = false
- }
-
- l.tok = tok
-}
-
func getc() int {
c := curio.peekc
if c != 0 {