From f6a276953f67c979add0577d301735789576120e Mon Sep 17 00:00:00 2001 From: ahmedsamyh Date: Sat, 16 Nov 2024 22:53:09 +0500 Subject: [PATCH] Can parse Some Single Character Symbols... Eg: (), {}, ->, -+, /, *, %, =, !, etc --- main.momo | 8 +- main.py | 109 +++++++++++++++++++++++-- tests/06-single-char-symbols.momo | 4 + tests/06-single-char-symbols.momo.test | 19 +++++ 4 files changed, 129 insertions(+), 11 deletions(-) create mode 100644 tests/06-single-char-symbols.momo create mode 100644 tests/06-single-char-symbols.momo.test diff --git a/main.momo b/main.momo index 516690c..0d54893 100644 --- a/main.momo +++ b/main.momo @@ -1,4 +1,4 @@ - -fun main() -> int { - return 0; -} +( ) {} -> +- + / * % += ! +>= > < <= != == diff --git a/main.py b/main.py index e7d6c0c..b53ec07 100644 --- a/main.py +++ b/main.py @@ -37,13 +37,50 @@ class Loc: class TokenType(IntEnum): IDENT = auto() STRING = auto() + LEFT_PAREN = auto() + RIGHT_PAREN = auto() + MINUS = auto() + RETURNER = auto() + LEFT_BRACE = auto() + RIGHT_BRACE = auto() + PLUS = auto() + DIVIDE = auto() + MULTIPLY = auto() + MODULUS = auto() + EQUAL = auto() + NOT = auto() + NOT_EQUAL = auto() + EQUAL_EQUAL = auto() + GT = auto() + LT = auto() + GTE = auto() + LTE = auto() COUNT = auto() token_type_as_str_map: { TokenType : str } = { - TokenType.IDENT : "Ident", - TokenType.STRING : "String", - TokenType.COUNT : "Count", + TokenType.IDENT : "Ident", + TokenType.STRING : "String", + TokenType.LEFT_PAREN : "Left paren", + TokenType.RIGHT_PAREN : "Right paren", + TokenType.MINUS : "Minus", + TokenType.LEFT_BRACE : "Left brace", + TokenType.RIGHT_BRACE : "Right brace", + TokenType.RETURNER : "Returner", + TokenType.PLUS : "Plus", + TokenType.DIVIDE : "Divide", + TokenType.MULTIPLY : "Multiply", + TokenType.MODULUS : "Modulus", + TokenType.EQUAL : "Equal", + TokenType.NOT : "Not", + TokenType.NOT_EQUAL : "Not Equal", + TokenType.EQUAL_EQUAL : "Equal Equal", + TokenType.GT : "Greater Than", + TokenType.LT : "Less Than", + TokenType.GTE : "Greater Than or Equal", + TokenType.LTE : "Less Than or Equal", } +# NOTE: TokenType.COUNT - 1 because auto() starts from 1 +assert len(token_type_as_str_map) == TokenType.COUNT-1 class Token: def __init__(self, typ: TokenType, value: str, loc: Loc): @@ -80,6 +117,10 @@ class Parser: assert self.cur < len(self.src), f"cur: {self.cur}, src_len: {len(self.src)}" return self.src[self.cur] + def peek_next_char(self) -> str | int: + if self.cur + 1 >= len(self.src): return -1 + return self.src[self.cur + 1] + def consume_char(self) -> str: c = self.current_char() self.cur += 1 @@ -134,17 +175,71 @@ class Parser: c = self.current_char() - t: Token | None = None if c == '"': value, loc = self.consume_string() - t = Token(TokenType.STRING, value, loc) + return Token(TokenType.STRING, value, loc) elif c.isalpha() or c == '_': ident, loc = self.consume_identifier() - t = Token(TokenType.IDENT, ident, loc) + return Token(TokenType.IDENT, ident, loc) + elif c == '(': + loc = Loc(self.filename, self.line, self.row()) + return Token(TokenType.LEFT_PAREN, self.consume_char(), loc) + elif c == ')': + loc = Loc(self.filename, self.line, self.row()) + return Token(TokenType.RIGHT_PAREN, self.consume_char(), loc) + elif c == '-': + loc = Loc(self.filename, self.line, self.row()) + # Check if its a returner '->' + if self.peek_next_char() == '>': + return Token(TokenType.RETURNER, self.consume_char() + self.consume_char(), loc) + + return Token(TokenType.MINUS, self.consume_char(), loc) + elif c == '{': + loc = Loc(self.filename, self.line, self.row()) + return Token(TokenType.LEFT_BRACE, self.consume_char(), loc) + elif c == '}': + loc = Loc(self.filename, self.line, self.row()) + return Token(TokenType.RIGHT_BRACE, self.consume_char(), loc) + elif c == '+': + loc = Loc(self.filename, self.line, self.row()) + return Token(TokenType.PLUS, self.consume_char(), loc) + elif c == '/': + loc = Loc(self.filename, self.line, self.row()) + return Token(TokenType.DIVIDE, self.consume_char(), loc) + elif c == '*': + loc = Loc(self.filename, self.line, self.row()) + return Token(TokenType.MULTIPLY, self.consume_char(), loc) + elif c == '%': + loc = Loc(self.filename, self.line, self.row()) + return Token(TokenType.MODULUS, self.consume_char(), loc) + elif c == '=': + loc = Loc(self.filename, self.line, self.row()) + # Check if '==' + if self.peek_next_char() == '=': + return Token(TokenType.EQUAL_EQUAL, self.consume_char() + self.consume_char(), loc) + return Token(TokenType.EQUAL, self.consume_char(), loc) + elif c == '!': + loc = Loc(self.filename, self.line, self.row()) + # Check if '!=' + if self.peek_next_char() == '=': + return Token(TokenType.NOT_EQUAL, self.consume_char() + self.consume_char(), loc) + return Token(TokenType.NOT, self.consume_char(), loc) + elif c == '>': + loc = Loc(self.filename, self.line, self.row()) + # Check if '>=' + if self.peek_next_char() == '=': + return Token(TokenType.GTE, self.consume_char() + self.consume_char(), loc) + return Token(TokenType.GT, self.consume_char(), loc) + elif c == '<': + loc = Loc(self.filename, self.line, self.row()) + # Check if '<=' + if self.peek_next_char() == '=': + return Token(TokenType.LTE, self.consume_char() + self.consume_char(), loc) + return Token(TokenType.LT, self.consume_char(), loc) else: fatal(f"Unrecognized character '{c}'") - return t + return None def main(): program: str = sys.argv.pop(0) diff --git a/tests/06-single-char-symbols.momo b/tests/06-single-char-symbols.momo new file mode 100644 index 0000000..0d54893 --- /dev/null +++ b/tests/06-single-char-symbols.momo @@ -0,0 +1,4 @@ +( ) {} -> +- + / * % += ! +>= > < <= != == diff --git a/tests/06-single-char-symbols.momo.test b/tests/06-single-char-symbols.momo.test new file mode 100644 index 0000000..bf87c03 --- /dev/null +++ b/tests/06-single-char-symbols.momo.test @@ -0,0 +1,19 @@ +"Token (Left paren, '(', ./tests/06-single-char-symbols.momo:1:0)" +"Token (Right paren, ')', ./tests/06-single-char-symbols.momo:1:2)" +"Token (Left brace, '{', ./tests/06-single-char-symbols.momo:1:4)" +"Token (Right brace, '}', ./tests/06-single-char-symbols.momo:1:5)" +"Token (Returner, '->', ./tests/06-single-char-symbols.momo:1:7)" +"Token (Minus, '-', ./tests/06-single-char-symbols.momo:2:0)" +"Token (Plus, '+', ./tests/06-single-char-symbols.momo:2:2)" +"Token (Divide, '/', ./tests/06-single-char-symbols.momo:2:4)" +"Token (Multiply, '*', ./tests/06-single-char-symbols.momo:2:6)" +"Token (Modulus, '%', ./tests/06-single-char-symbols.momo:2:8)" +"Token (Equal, '=', ./tests/06-single-char-symbols.momo:3:0)" +"Token (Not, '!', ./tests/06-single-char-symbols.momo:3:2)" +"Token (Greater Than or Equal, '>=', ./tests/06-single-char-symbols.momo:4:0)" +"Token (Greater Than, '>', ./tests/06-single-char-symbols.momo:4:3)" +"Token (Less Than, '<', ./tests/06-single-char-symbols.momo:4:5)" +"Token (Less Than or Equal, '<=', ./tests/06-single-char-symbols.momo:4:7)" +"Token (Not Equal, '!=', ./tests/06-single-char-symbols.momo:4:10)" +"Token (Equal Equal, '==', ./tests/06-single-char-symbols.momo:4:13)" +'None' -- 2.39.5