]> www.git.momoyon.org Git - lang.git/commitdiff
Can parse Some Single Character Symbols...
authorahmedsamyh <ahmedsamyh10@gmail.com>
Sat, 16 Nov 2024 17:53:09 +0000 (22:53 +0500)
committerahmedsamyh <ahmedsamyh10@gmail.com>
Sat, 16 Nov 2024 17:53:09 +0000 (22:53 +0500)
Eg: (), {}, ->, -+, /, *, %, =, !, etc

main.momo
main.py
tests/06-single-char-symbols.momo [new file with mode: 0644]
tests/06-single-char-symbols.momo.test [new file with mode: 0644]

index 516690c397f5e695e66e7000a92aa3fc0688d3d2..0d54893525b24420a73258ddb3dbb02ee0f78963 100644 (file)
--- a/main.momo
+++ b/main.momo
@@ -1,4 +1,4 @@
-
-fun main() -> int {
-    return 0;
-}
+( ) {} ->
+- + / * %
+= !
+>= > < <= != ==
diff --git a/main.py b/main.py
index e7d6c0c467521523fac28e5ab95365f133564e26..b53ec07cc8b192b8cb114af4c5c657d689a330ac 100644 (file)
--- 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 (file)
index 0000000..0d54893
--- /dev/null
@@ -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 (file)
index 0000000..bf87c03
--- /dev/null
@@ -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'