237 lines
6.6 KiB
Plaintext
237 lines
6.6 KiB
Plaintext
|
enum Keyword {
|
||
|
Enum,
|
||
|
Struct,
|
||
|
Func,
|
||
|
If,
|
||
|
Else,
|
||
|
While,
|
||
|
Break,
|
||
|
Continue,
|
||
|
Do,
|
||
|
For,
|
||
|
To,
|
||
|
In,
|
||
|
Match,
|
||
|
Case,
|
||
|
Assert,
|
||
|
Return,
|
||
|
Lambda,
|
||
|
Import,
|
||
|
Type
|
||
|
}
|
||
|
|
||
|
enum OptionalKeyword {
|
||
|
Some(Keyword),
|
||
|
None
|
||
|
}
|
||
|
|
||
|
func keyword_from_str(keyword: str) -> OptionalKeyword {
|
||
|
if keyword == "enum" return OptionalKeyword.Some(Keyword.Enum);
|
||
|
if keyword == "struct" return OptionalKeyword.Some(Keyword.Struct);
|
||
|
if keyword == "func" return OptionalKeyword.Some(Keyword.Func);
|
||
|
if keyword == "if" return OptionalKeyword.Some(Keyword.If);
|
||
|
if keyword == "else" return OptionalKeyword.Some(Keyword.Else);
|
||
|
if keyword == "while" return OptionalKeyword.Some(Keyword.While);
|
||
|
if keyword == "break" return OptionalKeyword.Some(Keyword.Break);
|
||
|
if keyword == "continue" return OptionalKeyword.Some(Keyword.Continue);
|
||
|
if keyword == "do" return OptionalKeyword.Some(Keyword.Do);
|
||
|
if keyword == "for" return OptionalKeyword.Some(Keyword.For);
|
||
|
if keyword == "to" return OptionalKeyword.Some(Keyword.To);
|
||
|
if keyword == "in" return OptionalKeyword.Some(Keyword.In);
|
||
|
if keyword == "match" return OptionalKeyword.Some(Keyword.Match);
|
||
|
if keyword == "case" return OptionalKeyword.Some(Keyword.Case);
|
||
|
if keyword == "assert" return OptionalKeyword.Some(Keyword.Assert);
|
||
|
if keyword == "return" return OptionalKeyword.Some(Keyword.Return);
|
||
|
if keyword == "lambda" return OptionalKeyword.Some(Keyword.Lambda);
|
||
|
if keyword == "import" return OptionalKeyword.Some(Keyword.Import);
|
||
|
if keyword == "type" return OptionalKeyword.Some(Keyword.Type);
|
||
|
return OptionalKeyword.None;
|
||
|
}
|
||
|
|
||
|
func keyword_to_str(keyword: Keyword) -> str {
|
||
|
match keyword in {
|
||
|
case Enum return "enum";
|
||
|
case Struct return "struct";
|
||
|
case Func return "func";
|
||
|
case If return "if";
|
||
|
case Else return "else";
|
||
|
case While return "while";
|
||
|
case Break return "break";
|
||
|
case Continue return "continue";
|
||
|
case Do return "do";
|
||
|
case For return "for";
|
||
|
case To return "to";
|
||
|
case In return "in";
|
||
|
case Match return "match";
|
||
|
case Case return "case";
|
||
|
case Assert return "assert";
|
||
|
case Return return "return";
|
||
|
case Lambda return "lambda";
|
||
|
case Import return "import";
|
||
|
case Type return "type";
|
||
|
}
|
||
|
assert false, "Invalid keyword";
|
||
|
}
|
||
|
|
||
|
enum Symbol {
|
||
|
Open,
|
||
|
Close,
|
||
|
OpenCurly,
|
||
|
CloseCurly,
|
||
|
Comma,
|
||
|
OpenSquare,
|
||
|
CloseSquare,
|
||
|
Colon,
|
||
|
Left,
|
||
|
Right,
|
||
|
Arrow,
|
||
|
Semicolon,
|
||
|
Equal,
|
||
|
Dequal,
|
||
|
Exclamation,
|
||
|
NotEqual,
|
||
|
Dot,
|
||
|
Plus,
|
||
|
Dash,
|
||
|
Asterisk,
|
||
|
Dasterisk,
|
||
|
Slash,
|
||
|
QuestionMark,
|
||
|
Ampersand,
|
||
|
Dampersand,
|
||
|
Pipe,
|
||
|
Dpipe,
|
||
|
Dleft,
|
||
|
Dright,
|
||
|
GreaterEqual,
|
||
|
LesserEqual,
|
||
|
Percent,
|
||
|
Tilde,
|
||
|
Carot
|
||
|
}
|
||
|
|
||
|
enum OptionalSymbol {
|
||
|
Some(Symbol),
|
||
|
None
|
||
|
}
|
||
|
|
||
|
func symbol_from_str(symbol: str) -> OptionalSymbol {
|
||
|
if symbol == "(" return OptionalSymbol.Some(Symbol.Open);
|
||
|
if symbol == ")" return OptionalSymbol.Some(Symbol.Close);
|
||
|
if symbol == "{" return OptionalSymbol.Some(Symbol.OpenCurly);
|
||
|
if symbol == "}" return OptionalSymbol.Some(Symbol.CloseCurly);
|
||
|
if symbol == "," return OptionalSymbol.Some(Symbol.Comma);
|
||
|
if symbol == "[" return OptionalSymbol.Some(Symbol.OpenSquare);
|
||
|
if symbol == "]" return OptionalSymbol.Some(Symbol.CloseSquare);
|
||
|
if symbol == ":" return OptionalSymbol.Some(Symbol.Colon);
|
||
|
if symbol == "<" return OptionalSymbol.Some(Symbol.Left);
|
||
|
if symbol == ">" return OptionalSymbol.Some(Symbol.Right);
|
||
|
if symbol == "->" return OptionalSymbol.Some(Symbol.Arrow);
|
||
|
if symbol == ";" return OptionalSymbol.Some(Symbol.Semicolon);
|
||
|
if symbol == "=" return OptionalSymbol.Some(Symbol.Equal);
|
||
|
if symbol == "==" return OptionalSymbol.Some(Symbol.Dequal);
|
||
|
if symbol == "!" return OptionalSymbol.Some(Symbol.Exclamation);
|
||
|
if symbol == "!=" return OptionalSymbol.Some(Symbol.NotEqual);
|
||
|
if symbol == "." return OptionalSymbol.Some(Symbol.Dot);
|
||
|
if symbol == "+" return OptionalSymbol.Some(Symbol.Plus);
|
||
|
if symbol == "-" return OptionalSymbol.Some(Symbol.Dash);
|
||
|
if symbol == "*" return OptionalSymbol.Some(Symbol.Asterisk);
|
||
|
if symbol == "**" return OptionalSymbol.Some(Symbol.Dasterisk);
|
||
|
if symbol == "/" return OptionalSymbol.Some(Symbol.Slash);
|
||
|
if symbol == "?" return OptionalSymbol.Some(Symbol.QuestionMark);
|
||
|
if symbol == "&" return OptionalSymbol.Some(Symbol.Ampersand);
|
||
|
if symbol == "&&" return OptionalSymbol.Some(Symbol.Dampersand);
|
||
|
if symbol == "|" return OptionalSymbol.Some(Symbol.Pipe);
|
||
|
if symbol == "||" return OptionalSymbol.Some(Symbol.Dpipe);
|
||
|
if symbol == "<<" return OptionalSymbol.Some(Symbol.Dleft);
|
||
|
if symbol == ">>" return OptionalSymbol.Some(Symbol.Dright);
|
||
|
if symbol == ">=" return OptionalSymbol.Some(Symbol.GreaterEqual);
|
||
|
if symbol == "<=" return OptionalSymbol.Some(Symbol.LesserEqual);
|
||
|
if symbol == "%" return OptionalSymbol.Some(Symbol.Percent);
|
||
|
if symbol == "~" return OptionalSymbol.Some(Symbol.Tilde);
|
||
|
if symbol == "^" return OptionalSymbol.Some(Symbol.Carot);
|
||
|
assert false, "Unimplemented symbol '%s'" % symbol;
|
||
|
}
|
||
|
|
||
|
func symbol_to_str(symbol: Symbol) -> str {
|
||
|
match symbol in {
|
||
|
case Open return "(";
|
||
|
case Close return ")";
|
||
|
case OpenCurly return "{";
|
||
|
case CloseCurly return "}";
|
||
|
case Comma return ",";
|
||
|
case OpenSquare return "[";
|
||
|
case CloseSquare return "]";
|
||
|
case Colon return ":";
|
||
|
case Left return "<";
|
||
|
case Right return ">";
|
||
|
case Arrow return "->";
|
||
|
case Semicolon return ";";
|
||
|
case Equal return "=";
|
||
|
case Dequal return "==";
|
||
|
case Exclamation return "!";
|
||
|
case NotEqual return "!=";
|
||
|
case Dot return ".";
|
||
|
case Plus return "+";
|
||
|
case Dash return "-";
|
||
|
case Asterisk return "*";
|
||
|
case Dasterisk return "**";
|
||
|
case Slash return "/";
|
||
|
case QuestionMark return "?";
|
||
|
case Ampersand return "&";
|
||
|
case Dampersand return "&&";
|
||
|
case Pipe return "|";
|
||
|
case Dpipe return "||";
|
||
|
case Dleft return "<<";
|
||
|
case Dright return ">>";
|
||
|
case GreaterEqual return ">=";
|
||
|
case LesserEqual return "<=";
|
||
|
case Percent return "%";
|
||
|
case Tilde return "~";
|
||
|
case Carot return "^";
|
||
|
}
|
||
|
assert false, "Invalid symbol";
|
||
|
}
|
||
|
|
||
|
enum TokenContents {
|
||
|
Keyword(Keyword),
|
||
|
Identifier(str),
|
||
|
Number(int),
|
||
|
String(str),
|
||
|
Symbol(Symbol),
|
||
|
Eof
|
||
|
}
|
||
|
|
||
|
func token_contents_to_str(token: TokenContents) -> str {
|
||
|
match token in {
|
||
|
case Keyword(keyword) return "Keyword(%s)" % keyword_to_str(keyword);
|
||
|
case Identifier(string) return "Identifier(%s)" % string;
|
||
|
case Number(number) return "Number(%d)" % number;
|
||
|
case String(string) return "String(\"%s\")" % string;
|
||
|
case Symbol(symbol) return "Symbol('%s')" % symbol_to_str(symbol);
|
||
|
case Eof return "Eof";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
struct Token {
|
||
|
line: int,
|
||
|
col: int,
|
||
|
value: str,
|
||
|
contents: TokenContents
|
||
|
}
|
||
|
|
||
|
func token_to_str(token: Token) -> str {
|
||
|
return token_contents_to_str(token.contents)+":"+int_to_str(token.line)+":"+int_to_str(token.col);
|
||
|
}
|
||
|
|
||
|
enum OptionalToken {
|
||
|
Some(Token),
|
||
|
None
|
||
|
}
|
||
|
|
||
|
func is_some_token(maybe_token: OptionalToken) -> bool {
|
||
|
match maybe_token in {
|
||
|
case Some(_) return true;
|
||
|
case None return false;
|
||
|
}
|
||
|
}
|