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(":")))