Files
Gwendolyn/gwendolyn/funcs/other/roll/roll.py
Nikolaj 2f4e606fbf
2024-10-30 15:31:46 +01:00

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