Mako/parser/token.go
2025-06-10 11:25:39 -05:00

121 lines
1.7 KiB
Go

package parser
// TokenType represents the type of a token
type TokenType int
const (
// Literals
IDENT TokenType = iota
NUMBER
STRING
TRUE
FALSE
NIL
// Operators
ASSIGN // =
PLUS // +
MINUS // -
STAR // *
SLASH // /
DOT // .
// Comparison operators
EQ // ==
NOT_EQ // !=
LT // <
GT // >
LT_EQ // <=
GT_EQ // >=
// Delimiters
LPAREN // (
RPAREN // )
LBRACE // {
RBRACE // }
LBRACKET // [
RBRACKET // ]
COMMA // ,
// Keywords
VAR
IF
THEN
ELSEIF
ELSE
END
ECHO
FOR
WHILE
IN
DO
// Special
EOF
ILLEGAL
)
// Token represents a single token
type Token struct {
Type TokenType
Literal string
Line int
Column int
}
// Precedence levels for Pratt parsing
type Precedence int
const (
_ Precedence = iota
LOWEST
EQUALS // ==, !=
LESSGREATER // >, <, >=, <=
SUM // +, -
PRODUCT // *, /
PREFIX // -x, !x
MEMBER // table[key], table.key
CALL // function()
)
// precedences maps token types to their precedence levels
var precedences = map[TokenType]Precedence{
EQ: EQUALS,
NOT_EQ: EQUALS,
LT: LESSGREATER,
GT: LESSGREATER,
LT_EQ: LESSGREATER,
GT_EQ: LESSGREATER,
PLUS: SUM,
MINUS: SUM,
SLASH: PRODUCT,
STAR: PRODUCT,
DOT: MEMBER,
LBRACKET: MEMBER,
}
// lookupIdent checks if an identifier is a keyword
func lookupIdent(ident string) TokenType {
keywords := map[string]TokenType{
"var": VAR,
"true": TRUE,
"false": FALSE,
"nil": NIL,
"if": IF,
"then": THEN,
"elseif": ELSEIF,
"else": ELSE,
"end": END,
"echo": ECHO,
"for": FOR,
"while": WHILE,
"in": IN,
"do": DO,
}
if tok, ok := keywords[ident]; ok {
return tok
}
return IDENT
}