2025-09-01 20:41:41 +10:00
|
|
|
from enum import Enum
|
|
|
|
|
|
|
|
class TokenType(Enum):
|
|
|
|
INTEGER = 1
|
|
|
|
DOUBLE = 2
|
|
|
|
STRING = 3
|
|
|
|
CHAR = 4
|
|
|
|
BOOLEAN = 5
|
|
|
|
|
2025-09-02 20:41:17 +10:00
|
|
|
VARIABLE = 8
|
|
|
|
IF = 9
|
|
|
|
ELSE = 10
|
|
|
|
WHILE = 11
|
|
|
|
LET = 12
|
|
|
|
END = 13
|
2025-09-01 20:41:41 +10:00
|
|
|
|
2025-09-02 20:41:17 +10:00
|
|
|
ADD = 14
|
|
|
|
SUBTRACT = 15
|
|
|
|
MULTIPLY = 16
|
|
|
|
DIVIDE = 17
|
2025-09-01 20:41:41 +10:00
|
|
|
|
2025-09-02 20:41:17 +10:00
|
|
|
SET = 18
|
2025-09-01 20:41:41 +10:00
|
|
|
|
2025-09-02 20:41:17 +10:00
|
|
|
EQUAL = 19
|
|
|
|
GREATER = 20
|
|
|
|
LESSER = 21
|
|
|
|
|
|
|
|
PARAMOPEN = 22
|
|
|
|
PARAMCLOSE = 23
|
|
|
|
|
|
|
|
ROOT = 24
|
2025-09-01 20:41:41 +10:00
|
|
|
|
|
|
|
UNKNOWN = 0
|
|
|
|
|
|
|
|
class Token:
|
2025-09-02 20:41:17 +10:00
|
|
|
def __init__(self, tok: str, isroot = False):
|
2025-09-01 20:41:41 +10:00
|
|
|
self.value = tok
|
2025-09-02 20:41:17 +10:00
|
|
|
if isroot:
|
|
|
|
self.type = TokenType.ROOT
|
|
|
|
else:
|
|
|
|
self.type = get_type(tok)
|
2025-09-01 20:41:41 +10:00
|
|
|
|
|
|
|
def __repr__(self) -> str:
|
|
|
|
return f"Token(type={self.type.name}, value='{self.value}')"
|
|
|
|
|
|
|
|
type tokenlist = list[Token]
|
|
|
|
|
|
|
|
def get_type(process: str) -> TokenType:
|
|
|
|
# Keywords
|
|
|
|
match process:
|
|
|
|
case "let":
|
|
|
|
return TokenType.LET
|
|
|
|
case "if":
|
|
|
|
return TokenType.IF
|
|
|
|
case "else":
|
|
|
|
return TokenType.ELSE
|
|
|
|
case "while":
|
|
|
|
return TokenType.WHILE
|
|
|
|
case "true" | "false":
|
|
|
|
return TokenType.BOOLEAN
|
2025-09-01 21:06:05 +10:00
|
|
|
case "end":
|
|
|
|
return TokenType.END
|
2025-09-01 20:41:41 +10:00
|
|
|
case "+":
|
|
|
|
return TokenType.ADD
|
|
|
|
case "-":
|
|
|
|
return TokenType.SUBTRACT
|
|
|
|
case "*":
|
|
|
|
return TokenType.MULTIPLY
|
|
|
|
case "/":
|
|
|
|
return TokenType.DIVIDE
|
|
|
|
case "=":
|
|
|
|
return TokenType.SET
|
|
|
|
case "==":
|
|
|
|
return TokenType.EQUAL
|
|
|
|
case ">":
|
|
|
|
return TokenType.GREATER
|
|
|
|
case "<":
|
|
|
|
return TokenType.LESSER
|
2025-09-02 20:41:17 +10:00
|
|
|
case "(":
|
|
|
|
return TokenType.PARAMOPEN
|
|
|
|
case ")":
|
|
|
|
return TokenType.PARAMCLOSE
|
2025-09-01 20:41:41 +10:00
|
|
|
|
|
|
|
# String/Char Literals
|
|
|
|
if len(process) >= 2:
|
|
|
|
if process.startswith('"') and process.endswith('"'):
|
|
|
|
return TokenType.STRING
|
|
|
|
if process.startswith("'") and process.endswith("'") and len(process) == 3:
|
|
|
|
return TokenType.CHAR
|
|
|
|
|
|
|
|
# Numeric Literals
|
|
|
|
if '.' in process:
|
|
|
|
try:
|
|
|
|
float(process)
|
|
|
|
return TokenType.DOUBLE
|
|
|
|
except ValueError:
|
|
|
|
pass
|
|
|
|
else:
|
|
|
|
try:
|
|
|
|
int(process)
|
|
|
|
return TokenType.INTEGER
|
|
|
|
except ValueError:
|
|
|
|
pass
|
|
|
|
|
|
|
|
# Identifiers (Variables/Functions)
|
|
|
|
if process and (process[0].isalpha() or process[0] == '_') and all(c.isalnum() or c == '_' for c in process):
|
|
|
|
return TokenType.VARIABLE
|
|
|
|
|
|
|
|
return TokenType.UNKNOWN
|