package token

const (
	ILLEGAL = "ILLEGAL"
	EOF     = "EOF"

	// Identifiers + literals
	IDENT  = "IDENT" // add, foobar, x, y, ...
	INT    = "INT"   // 1343456
	STRING = "STRING"
	FLOAT  = "FLOAT"

	// Operators
	ASSIGN   = "="
	PLUS     = "+"
	MINUS    = "-"
	BANG     = "!"
	ASTERISK = "*"
	SLASH    = "/"

	LT    = "<"
	GT    = ">"
	GT_EQ = ">="
	LT_EQ = "<="

	EQ             = "=="
	NOT_EQ         = "!="
	ADD_PLUS       = "+="
	REMOVE_PLUS    = "+="
	SCOPE_IDENTIFY = "->"

	// Delimiters
	COMMA     = ","
	SEMICOLON = ";"
	LPAREN    = "("
	RPAREN    = ")"
	LBRACE    = "{"
	RBRACE    = "}"
	LBRAKET   = "["
	RBRAKET   = "]"
	COLON     = ":"
	COMMENT   = "#"
	DOT       = "."

	// Keywords
	FUNCTION = "FUNCTION"
	LET      = "LET"
	TRUE     = "TRUE"
	FALSE    = "FALSE"
	IF       = "IF"
	ELSE     = "ELSE"
	RETURN   = "RETURN"
	PRINT    = "PRINT"
	LOAD     = "LOAD"
	LOOP     = "LOOP"
	SCOPE    = "SCOPE"
	PROC     = "PROC"
	ENV      = "ENV"
	SOCK     = "SOCK"
	FOR      = "FOR"
	IN       = "IN"
	SELF     = "SELF"
	LITERAL  = "LITERAL"
	BEGIN    = "BEGIN"
	EXCEPT   = "EXCEPT"
	RECOVER  = "RECOVER"
	FINAL    = "FINAL"
	ROUTE    = "ROUTE"
	SET      = "SET"
	IMPL     = "IMPL"
	SIGNAL   = "SIGNAL"
	ASM      = "ASM"
	EVAL     = "EVAL"
	ASYNC    = "ASYNC"
	WAIT     = "WAIT"
	WHILE    = "WHILE"
)

type TokenType string

type Token struct {
	Type    TokenType
	Literal string
}

var keywords = map[string]TokenType{
	"fn":      FUNCTION,
	"def":     LET,
	"true":    TRUE,
	"false":   FALSE,
	"if":      IF,
	"else":    ELSE,
	"return":  RETURN,
	"print":   PRINT,
	"load":    LOAD,
	"loop":    LOOP,
	"scope":   SCOPE,
	"proc":    PROC,
	"env":     ENV,
	"sock":    SOCK,
	"for":     FOR,
	"in":      IN,
	"self":    SELF,
	"literal": LITERAL,
	"begin":   BEGIN,
	"except":  EXCEPT,
	"recover": RECOVER,
	"final":   FINAL,
	"float":   FLOAT,
	"route":   ROUTE,
	"set":     SET,
	"impl":    IMPL,
	"signal":  SIGNAL,
	"eval":    EVAL,
	"async":   ASYNC,
	"wait":    WAIT,
	"while":   WHILE,
}

func LookupIdent(ident string) TokenType {
	if tok, ok := keywords[ident]; ok {
		return tok
	}

	return IDENT
}


var PreBuiltTokens = keywords