58 lines
2.6 KiB
Python
58 lines
2.6 KiB
Python
import os, sys; sys.path.append(os.path.dirname(os.path.realpath(__file__)))
|
|
|
|
from lexer import Lexer
|
|
from parser import Parser
|
|
from ast_nodes import Exp, ExpInt, ExpBinop, ExpLet, ExpVar, ExpRoll, Roll, RollKeepHighest, RollKeepLowest, RollMin, RollMax, ExpMin, ExpMax
|
|
|
|
|
|
class DieRoller():
|
|
def __init__(self) -> None:
|
|
self.lexer = Lexer().get_lexer()
|
|
self.parser = Parser()
|
|
|
|
def parse(self, string: str) -> Exp:
|
|
tokens = self.lexer.lex(string)
|
|
expression = self.parser.parse(tokens)
|
|
return expression
|
|
|
|
def roll(self, string: str):
|
|
exp = self.parse(string)
|
|
# print(exp)
|
|
# exit()
|
|
show = exp.show({})
|
|
eval = exp.eval({})
|
|
if show is None or eval is None or isinstance(eval,tuple):
|
|
raise Exception("Something went wrong")
|
|
return f"**Result**: {show}\n**Total**: {eval}"
|
|
|
|
if __name__ == "__main__":
|
|
d = DieRoller()
|
|
test_strings = [
|
|
("4", ExpInt(4)),
|
|
("1 + 1", ExpBinop("+",ExpInt(1),ExpInt(1))),
|
|
("5*5", ExpBinop("*",ExpInt(5),ExpInt(5))),
|
|
("1+5/5", ExpBinop("+",ExpInt(1),ExpBinop("/",ExpInt(5),ExpInt(5)))),
|
|
("(1+5)/6", ExpBinop("/",ExpBinop("+",ExpInt(1),ExpInt(5)),ExpInt(6))),
|
|
("let x=5 in x*2", ExpLet("x",ExpInt(5),ExpBinop("*",ExpVar("x"),ExpInt(2)))),
|
|
("let x= let y = 2 in y in let z = 5 in x*z", ExpLet("x",ExpLet("y",ExpInt(2),ExpVar("y")),ExpLet("z",ExpInt(5),ExpBinop("*",ExpVar("x"),ExpVar("z"))))),
|
|
("4d6", ExpRoll(Roll(ExpInt(4),ExpInt(6)))),
|
|
("d6", ExpRoll(Roll(ExpInt(1),ExpInt(6)))),
|
|
("(2+2)d(3*2)", ExpRoll(Roll(ExpBinop("+",ExpInt(2),ExpInt(2)),ExpBinop("*",ExpInt(3),ExpInt(2))))),
|
|
("4d3*2", ExpBinop("*",ExpRoll(Roll(ExpInt(4),ExpInt(3))),ExpInt(2))),
|
|
("4d6kh3", ExpRoll(RollKeepHighest(Roll(ExpInt(4),ExpInt(6)),ExpInt(3)))),
|
|
("2d20kl1", ExpRoll(RollKeepLowest(Roll(ExpInt(2),ExpInt(20)),ExpInt(1)))),
|
|
("11d10kh6kl1", ExpRoll(RollKeepLowest(RollKeepHighest(Roll(ExpInt(11),ExpInt(10)),ExpInt(6)),ExpInt(1)))),
|
|
("3d6min6", ExpRoll(RollMin(Roll(ExpInt(3),ExpInt(6)),ExpInt(6)))),
|
|
("3d6max1", ExpRoll(RollMax(Roll(ExpInt(3),ExpInt(6)),ExpInt(1)))),
|
|
("let x = 1d4 in (x)min3", ExpLet("x",ExpRoll(Roll(ExpInt(1),ExpInt(4))),ExpMin(ExpVar("x"),ExpInt(3)))),
|
|
("10max(2d10)",ExpMax(ExpInt(10),ExpRoll(Roll(ExpInt(2),ExpInt(10)))))
|
|
]
|
|
for s, t in test_strings:
|
|
r = d.parse(s)
|
|
correct = r == t
|
|
print(f"{str(s) : <20}: {'✅' if correct else '❌'} ({r.eval({})})")
|
|
if not correct:
|
|
print(f"Expected: {t}")
|
|
print(f"Actual: {r}\n")
|
|
|
|
print(d.roll(input(":"))) |