func lexOperand(x *lex8.Lexer) *lex8.Token { if !isOperandChar(x.Rune()) { panic("incorrect operand start") } for { x.Next() if x.Ended() || !isOperandChar(x.Rune()) { break } } ret := x.MakeToken(Operand) if isKeyword(ret.Lit) { ret.Type = Keyword } return ret }
func lexNumber(x *lex8.Lexer) *lex8.Token { // TODO: lex floating point as well r := x.Rune() if !isDigit(r) { panic("not starting with a number") } for { x.Next() r := x.Rune() if !isDigit(r) { 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) && !isDigit(r) { break } } ret := x.MakeToken(Ident) if isKeyword(ret.Lit) { ret.Type = Keyword } return ret }
func lexAsm8(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 '{': x.Next() return x.MakeToken(Lbrace) case '}': x.Next() return x.MakeToken(Rbrace) case '/': x.Next() return lex8.LexComment(x) case '"': return lex8.LexString(x, String, '"') } if isOperandChar(r) { return lexOperand(x) } x.Errorf("illegal char %q", r) x.Next() return x.MakeToken(lex8.Illegal) }
func lexC8(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 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) }