diff --git a/documentation/plthy.pdf b/documentation/plthy.pdf index e1b4856..c0ac042 100644 Binary files a/documentation/plthy.pdf and b/documentation/plthy.pdf differ diff --git a/documentation/plthy.tex b/documentation/plthy.tex index 556dfcb..e446aee 100644 --- a/documentation/plthy.tex +++ b/documentation/plthy.tex @@ -7,7 +7,10 @@ \ifnum#1<10 0\fi \number#1} +\pagestyle{empty} + \begin{document} + \section{Grammar} \begin{center} \begin{tabular}{|lcl|} \hline diff --git a/plthy_impl/ast_nodes.py b/plthy_impl/ast_nodes.py index a6955bd..4dd155a 100644 --- a/plthy_impl/ast_nodes.py +++ b/plthy_impl/ast_nodes.py @@ -6,7 +6,8 @@ from rply.token import BaseBox BUILTIN_ARGS = { "print": "*", "input" : "*", - "random": 2 + "random": 2, + "len": 1 } def rep_join(l): @@ -70,13 +71,19 @@ class ExpABinop(Exp): if r1.isdigit(): r1 = int(r1) else: - r1 = float(r1) + try: + r1 = float(r1) + except ValueError: + pass vtable, ftable, r2 = self.exp2.eval(vtable, ftable) if isinstance(r2,str): if r2.isdigit(): r2 = int(r2) else: - r2 = float(r2) + try: + r2 = float(r2) + except ValueError: + pass if self.op == "+": return vtable, ftable, r1+r2 elif self.op == "-": @@ -91,6 +98,8 @@ class ExpABinop(Exp): return vtable, ftable, r1 > r2 elif self.op == "<": return vtable, ftable, r1 < r2 + elif self.op == "mod": + return vtable, ftable, r1 % r2 else: raise Exception(f"Unknown binop {self.op}") @@ -149,7 +158,7 @@ class Command(BaseBox): class Builtin(Command): def __init__(self, builtin, args: list[Exp]): - self.builtin = builtin.value + self.builtin = builtin.value[:-1] self.args = args self.position = builtin.source_pos.lineno expected_args = BUILTIN_ARGS[self.builtin] @@ -191,6 +200,10 @@ class Builtin(Command): r = random.randint(r1, r2) return vtable, ftable, r + elif self.builtin == "len": + vtable, ftable, result = self.args[0].eval(vtable,ftable) + + return vtable, ftable, len(result) else: raise Exception(f"Unknown builtin {self.builtin}") diff --git a/plthy_impl/lexer.py b/plthy_impl/lexer.py index d5a5ddc..6774483 100644 --- a/plthy_impl/lexer.py +++ b/plthy_impl/lexer.py @@ -21,10 +21,11 @@ KEYWORD_TOKENS = [("KEYWORD_"+i.upper(), i) for i in [ "else" ]] -BUILTIN_TOKENS = [("BUILTIN", i) for i in [ +BUILTIN_TOKENS = [("BUILTIN", i+"<") for i in [ "print", "input", - "random" + "random", + "len" ]] DATA_TOKENS = [ @@ -56,6 +57,7 @@ SYMBOL_TOKENS = [ ("SYMBOL_LT", r"\<"), ("SYMBOL_GT", r"\>"), ("SYMBOL_EQUALS", r"\="), + ("SYMBOL_MOD", r"mod") # ("SYMBOL_DOLLAR", r"\$") ] diff --git a/plthy_impl/parser.py b/plthy_impl/parser.py index 14826ae..12c771c 100644 --- a/plthy_impl/parser.py +++ b/plthy_impl/parser.py @@ -8,12 +8,12 @@ class Parser(): self.pg = ParserGenerator( [i[0] for i in ALL_TOKENS], precedence=[ - ('left', ["KEYWORD_SET", "SYMBOL_SET", "KEYWORD_IF", "KEYWORD_MAYBE", "KEYWORD_RETURN"]), + ('left', ["KEYWORD_SET","KEYWORD_IF", "KEYWORD_MAYBE", "KEYWORD_RETURN"]), ('left', [ "KEYWORD_BECAUSE", "KEYWORD_UNTIL", "KEYWORD_DEFINE", "KEYWORD_AS"]), ('left', ["KEYWORD_DO", "BUILTIN"]), ('left', ["SYMBOL_EQUALS", "SYMBOL_LT","SYMBOL_GT"]), ('left', ["SYMBOL_PLUS", "SYMBOL_MINUS", "SYMBOL_OR", "SYMBOL_AND"]), - ('left', ["SYMBOL_TIMES", "SYMBOL_DIVIDE", "SYMBOL_TILDE"]) + ('left', ["SYMBOL_LCURL", "SYMBOL_TIMES", "SYMBOL_DIVIDE", "SYMBOL_TILDE", "SYMBOL_MOD", "ID"]) ] ) @@ -78,9 +78,9 @@ class Parser(): def command_until(tokens): return ast_nodes.CommandUntil(tokens[0],tokens[2]) - @self.pg.production('command : BUILTIN SYMBOL_LT expressions SYMBOL_GT') + @self.pg.production('command : BUILTIN expressions SYMBOL_GT') def command_builtin(tokens): - return ast_nodes.Builtin(tokens[0], tokens[2]) + return ast_nodes.Builtin(tokens[0], tokens[1]) @self.pg.production('command : SYMBOL_QUOTE ID SYMBOL_QUOTE SYMBOL_LT expressions SYMBOL_GT') def command_call(tokens): @@ -129,6 +129,7 @@ class Parser(): @self.pg.production('expression : expression SYMBOL_EQUALS expression') @self.pg.production('expression : expression SYMBOL_LT expression') @self.pg.production('expression : expression SYMBOL_GT expression') + @self.pg.production('expression : expression SYMBOL_MOD expression') def exp_a_binop(tokens): return ast_nodes.ExpABinop(tokens[1].value,tokens[0],tokens[2]) diff --git a/tests/20_highest-integer.expected b/tests/20_highest-integer.expected new file mode 100644 index 0000000..871727d --- /dev/null +++ b/tests/20_highest-integer.expected @@ -0,0 +1 @@ +84 diff --git a/tests/20_highest-integer.plthy b/tests/20_highest-integer.plthy new file mode 100644 index 0000000..2aa1da4 --- /dev/null +++ b/tests/20_highest-integer.plthy @@ -0,0 +1,11 @@ +hello| +set {5;3;8;9;55;1;34;84;6;} -> list| +set 0 -> i| +set 0 -> highest| +skip| +do [ + do set variable list{variable i} -> highest if variable list{variable i} > variable highest| + set variable i+1 -> i| +] until variable i = do len| +do print| +goodbye| \ No newline at end of file diff --git a/tests/21_fizzbuzz.expected b/tests/21_fizzbuzz.expected new file mode 100644 index 0000000..956e30e --- /dev/null +++ b/tests/21_fizzbuzz.expected @@ -0,0 +1,50 @@ +1 +2 +fizz +4 +buzz +fizz +7 +8 +fizz +buzz +11 +fizz +13 +14 +fizzbuzz +16 +17 +fizz +19 +buzz +fizz +22 +23 +fizz +buzz +26 +fizz +28 +29 +fizzbuzz +31 +32 +fizz +34 +buzz +fizz +37 +38 +fizz +buzz +41 +fizz +43 +44 +fizzbuzz +46 +47 +fizz +49 +buzz diff --git a/tests/21_fizzbuzz.plthy b/tests/21_fizzbuzz.plthy new file mode 100644 index 0000000..b4a92cd --- /dev/null +++ b/tests/21_fizzbuzz.plthy @@ -0,0 +1,23 @@ +hello| +set 3 -> f| +set 5 -> b| +set 50 -> max| +set 0 -> i| +do [ + set variable i + 1 -> i| + set '' -> print_string| + do + set variable print_string + 'fizz' -> print_string + if variable i mod variable f = 0| + + do + set variable print_string + 'buzz' -> print_string + if variable i mod variable b = 0| + + do + do print + else + do print + if variable print_string = ''| +] until variable i = variable max| +goodbye| \ No newline at end of file