This commit is contained in:
NikolajDanger
2022-06-07 21:59:46 +02:00
parent dece7eb03e
commit de697b121e
5 changed files with 119 additions and 21 deletions

View File

@@ -1,5 +1,18 @@
import random
import roman
from rply.token import BaseBox
NUMERALS = [
("I", 1),
("V", 5),
("X", 10),
("L", 50),
("C", 100),
("D", 500),
("M", 1000)
]
def rep_join(l):
format_string = ',\n'.join(
[repr(i) if not isinstance(i, str) else i for i in l]
@@ -10,6 +23,9 @@ def rep_join(l):
return format_string
def num_to_int(n):
return roman.fromRoman(n)
class ExpressionStatement(BaseBox):
def __init__(self, expression) -> None:
self.expression = expression
@@ -18,7 +34,7 @@ class ExpressionStatement(BaseBox):
return self.expression.__repr__()
def eval(self, vtable, ftable, modules):
self.expression.eval(vtable, ftable, modules)
self.expression.eval(vtable.copy(), ftable.copy(), modules)
return vtable, ftable
class String(BaseBox):
@@ -28,6 +44,9 @@ class String(BaseBox):
def __repr__(self):
return f"String({self.value})"
def eval(self, *_):
return self.value
class Numeral(BaseBox):
def __init__(self, value) -> None:
self.value = value
@@ -35,6 +54,9 @@ class Numeral(BaseBox):
def __repr__(self):
return f"Numeral({self.value})"
def eval(self, *_):
return num_to_int(self.value)
class Bool(BaseBox):
def __init__(self, value) -> None:
self.value = value
@@ -42,6 +64,9 @@ class Bool(BaseBox):
def __repr__(self):
return f"Bool({self.value})"
def eval(self, *_):
return self.value
class ModuleCall(BaseBox):
def __init__(self, module_name) -> None:
self.module_name = module_name
@@ -56,6 +81,9 @@ class ID(BaseBox):
def __repr__(self) -> str:
return f"ID({self.name})"
def eval(self, vtable, *_):
return vtable[self.name]
class Designa(BaseBox):
def __init__(self, variable: ID, value) -> None:
self.id = variable
@@ -67,7 +95,9 @@ class Designa(BaseBox):
return f"Designa(\n {id_string},\n {value_string}\n)"
def eval(self, vtable, ftable, modules):
vtable[self.id.name] = self.value.eval(vtable, ftable, modules)
vtable[self.id.name] = self.value.eval(
vtable.copy(), ftable.copy(), modules
)
return vtable, ftable
class Defini(BaseBox):
@@ -92,6 +122,14 @@ class Redi(BaseBox):
values_string = f"[{rep_join(self.values)}]"
return f"Redi({values_string})"
class Erumpe(BaseBox):
def __repr__(self) -> str:
return "Erumpe()"
def eval(self, vtable, ftable, _):
vtable["ERUMPE"] = True
return vtable, ftable
class Nullus(BaseBox):
def __repr__(self) -> str:
return "Nullus()"
@@ -109,6 +147,19 @@ class BinOp(BaseBox):
binop_string = rep_join([self.left, self.right, self.op])
return f"BinOp({binop_string})"
def eval(self, vtable, ftable, modules):
left = self.left.eval(vtable.copy(), ftable.copy(), modules)
right = self.right.eval(vtable.copy(), ftable.copy(), modules)
match self.op:
case "SYMBOL_PLUS":
return left + right
case "KEYWORD_MINUS":
return left < right
case "KEYWORD_PLUS":
return left > right
case _:
raise Exception(self.op)
class SiStatement(BaseBox):
def __init__(self, test, statements, else_part) -> None:
self.test = test
@@ -122,6 +173,20 @@ class SiStatement(BaseBox):
si_string = rep_join([test, statements, else_part])
return f"Si({si_string})"
def eval(self, vtable, ftable, modules):
if self.test.eval(vtable, ftable, modules):
for statement in self.statements:
vtable, ftable = statement.eval(
vtable, ftable, modules
)
else:
for statement in self.else_part:
vtable, ftable = statement.eval(
vtable, ftable, modules
)
return vtable, ftable
class DumStatement(BaseBox):
def __init__(self, test, statements) -> None:
self.test = test
@@ -135,7 +200,16 @@ class DumStatement(BaseBox):
def eval(self, vtable, ftable, modules):
while not self.test.eval(vtable, ftable, modules):
pass
for statement in self.statements:
vtable, ftable = statement.eval(
vtable, ftable, modules
)
if vtable["ERUMPE"]:
break
if vtable["ERUMPE"]:
vtable["ERUMPE"] = False
break
return vtable, ftable
@@ -159,8 +233,25 @@ class BuiltIn(BaseBox):
builtin_string = rep_join([self.builtin, parameter_string])
return f"Builtin({builtin_string})"
def eval(self, vtable, ftable, _):
return None
def eval(self, vtable, ftable, modules):
parameters = [
i.eval(vtable.copy(), ftable.copy(), modules)
for i in self.parameters
]
match self.builtin:
case "AUDI_NUMERUS":
return num_to_int(input())
case "DICE":
print(' '.join(parameters))
return None
case "ERUMPE":
vtable["ERUMPE"] = True
return None
case "FORTIS_NUMERUS":
return random.randint(parameters[0], parameters[1])
case _:
raise Exception(self.builtin)
class Program(BaseBox):
def __init__(self, module_calls: list[ModuleCall], statements) -> None:
@@ -173,7 +264,7 @@ class Program(BaseBox):
return f"{modules_string},\n{statements_string}"
def eval(self):
vtable = {}
vtable = {"ERUMPE": False}
ftable = {}
modules = [module.module_name for module in self.modules]