diff --git a/ast_nodes.py b/ast_nodes.py index f6a8d48..ba48f5e 100644 --- a/ast_nodes.py +++ b/ast_nodes.py @@ -26,6 +26,14 @@ def rep_join(l): def num_to_int(n): return roman.fromRoman(n) +def make_string(n): + if isinstance(n, str): + return n + elif isinstance(n, int): + return roman.toRoman(n) + else: + raise Exception(n) + class ExpressionStatement(BaseBox): def __init__(self, expression) -> None: self.expression = expression @@ -114,6 +122,12 @@ class Defini(BaseBox): ) return f"Defini({def_string})" + def eval(self, vtable, ftable, modules): + ftable[self.name.name] = ( + self.parameters, self.statements + ) + return vtable, ftable + class Redi(BaseBox): def __init__(self, values) -> None: self.values = values @@ -122,6 +136,17 @@ class Redi(BaseBox): values_string = f"[{rep_join(self.values)}]" return f"Redi({values_string})" + def eval(self, vtable, ftable, modules): + values = [ + i.eval(vtable.copy(), ftable.copy(), modules) + for i in self.values + ] + if len(values) == 1: + vtable["REDI"] = values[0] + else: + vtable["REDI"] = values + return vtable, ftable + class Erumpe(BaseBox): def __repr__(self) -> str: return "Erumpe()" @@ -153,10 +178,14 @@ class BinOp(BaseBox): match self.op: case "SYMBOL_PLUS": return left + right + case "SYMBOL_MINUS": + return left - right case "KEYWORD_MINUS": return left < right case "KEYWORD_PLUS": return left > right + case "KEYWORD_EST": + return left == right case _: raise Exception(self.op) @@ -223,6 +252,22 @@ class Invoca(BaseBox): invoca_string = rep_join([self.name, parameters_string]) return f"Invoca({invoca_string})" + def eval(self, vtable, ftable, modules): + parameters = [ + i.eval(vtable.copy(), ftable.copy(), modules) + for i in self.parameters + ] + vtable_copy = vtable.copy() + function = ftable[self.name.name] + for i, parameter in enumerate(function[0]): + vtable_copy[parameter.name] = parameters[i] + + vtable_copy["REDI"] = None + for statement in function[1]: + statement.eval(vtable_copy, ftable, modules) + if vtable_copy["REDI"] is not None: + return vtable_copy["REDI"] + class BuiltIn(BaseBox): def __init__(self, builtin, parameters) -> None: self.builtin = builtin @@ -243,7 +288,7 @@ class BuiltIn(BaseBox): case "AUDI_NUMERUS": return num_to_int(input()) case "DICE": - print(' '.join(parameters)) + print(' '.join(make_string(i) for i in parameters)) return None case "ERUMPE": vtable["ERUMPE"] = True diff --git a/main.py b/main.py index badc29c..398b1dc 100644 --- a/main.py +++ b/main.py @@ -2,23 +2,18 @@ from lexer import Lexer from parser import Parser text_input = """ -VOCA FORS - -DESIGNA correct UT FORTIS_NUMERUS I C -DESIGNA gvess UT NULLUS - -DUM FALSITAS FACE { - DESIGNA gvess UT AUDI_NUMERUS - SI gvess MINUS correct TUNC { - DICE "Too low!" - } ALUID SI gvess PLUS correct TUNC { - DICE "Too high!" +DEFINI fib x UT { + SI x EST NULLUS TUNC { + REDI NULLUS + } ALUID SI x EST I TUNC { + REDI I } ALUID { - ERUMPE + REDI ((INVOCA fib (x-II)) + (INVOCA fib (x-I))) } } -DICE "You guessed correctly!" +DICE "Input n:" +DICE (INVOCA fib AUDI_NUMERUS) """ lexer = Lexer().get_lexer()