func lexG8(x *lex8.Lexer) *lex8.Token { r := x.Rune() if x.IsWhite(r) { panic("incorrect token start") } switch r { case '\n': x.Next() return x.MakeToken(Endl) case '"': return lex8.LexString(x, String, '"') case '\'': return lex8.LexString(x, Char, '\'') } if lex8.IsDigit(r) { return lexNumber(x) } else if isLetter(r) { return lexIdent(x) } // always make progress at this point x.Next() t := lexOperator(x, r) if t != nil { return t } x.Errorf("illegal char %q", r) return x.MakeToken(lex8.Illegal) }
func lexNumber(x *lex8.Lexer) *lex8.Token { // TODO: lex floating point as well start := x.Rune() if !lex8.IsDigit(start) { panic("not starting with a number") } x.Next() r := x.Rune() if start == '0' && r == 'x' { x.Next() for lex8.IsHexDigit(x.Rune()) { x.Next() } } else { for lex8.IsDigit(x.Rune()) { x.Next() } } return x.MakeToken(Int) }
func lexIdent(x *lex8.Lexer) *lex8.Token { r := x.Rune() if !isLetter(r) { panic("must start with letter") } for { x.Next() r := x.Rune() if !isLetter(r) && !lex8.IsDigit(r) { break } } ret := x.MakeToken(Ident) return ret }