diff --git a/documentation/plthy.pdf b/documentation/plthy.pdf index 46b1109..e71e68b 100644 Binary files a/documentation/plthy.pdf and b/documentation/plthy.pdf differ diff --git a/documentation/plthy.tex b/documentation/plthy.tex index a6da828..c93611a 100644 --- a/documentation/plthy.tex +++ b/documentation/plthy.tex @@ -47,8 +47,9 @@ \item No valediction \item Unexpected token \item Random compiler error - \item Unknown builtin \item Wrong number of arguments for builtin - \item Unknown binop + \end{enumerate} + \begin{enumerate}[label={\textbf{C\protect\threedigits{\theenumi}:}}, leftmargin = *] + \item Because assertion incorrect \end{enumerate} \end{document} \ No newline at end of file diff --git a/examples/guessing_game.plthy b/examples/guessing_game.plthy index 687cd9d..c6798ca 100644 --- a/examples/guessing_game.plthy +++ b/examples/guessing_game.plthy @@ -1,8 +1,8 @@ hello| -$do random<1;128;> -> n| -$0 -> guess| +set do random<1;128;> -> n| +set 0 -> guess| until variable guess = variable n [ - $do input<'guess: ';> -> guess| + set do input<'guess: ';> -> guess| do print<'too high';> if variable guess > variable n| do print<'too low';> if variable guess < variable n| do print<'correct!';> if variable guess = variable n| diff --git a/plthy_impl/ast_nodes.py b/plthy_impl/ast_nodes.py index aaf28c6..cbfa3d7 100644 --- a/plthy_impl/ast_nodes.py +++ b/plthy_impl/ast_nodes.py @@ -2,6 +2,13 @@ import random from rply.token import BaseBox + +BUILTIN_ARGS = { + "print": "*", + "input" : "*", + "random": 2 +} + def rep_join(l): format_string = ',\n'.join( [repr(i) if not isinstance(i, str) else i for i in l] @@ -11,7 +18,6 @@ def rep_join(l): format_string = f"\n {format_string}\n" return format_string - class Exp(BaseBox): def eval(self, vtable, ftable): return vtable, ftable, None @@ -86,8 +92,7 @@ class ExpABinop(Exp): elif self.op == "<": return vtable, ftable, r1 < r2 else: - print(f"E007: Unknown binop {self.op}") - exit() + raise Exception(f"Unknown binop {self.op}") class ExpList(Exp): def __init__(self, expressions: list[Exp]): @@ -143,9 +148,15 @@ class Command(BaseBox): return f"command()" class Builtin(Command): - def __init__(self, builtin: str, args: list[Exp]): - self.builtin = builtin + def __init__(self, builtin, args: list[Exp]): + self.builtin = builtin.value self.args = args + self.position = builtin.source_pos.lineno + expected_args = BUILTIN_ARGS[self.builtin] + + if not (expected_args == "*" or expected_args == len(self.args)): + print(f"E005: Wrong number of arguments for builtin '{self.builtin}' ({len(self.args)}) at line {self.position}") + exit() def __repr__(self) -> str: return f"builtin({self.builtin}, {self.args})" @@ -174,10 +185,6 @@ class Builtin(Command): result = input() return vtable, ftable, result elif self.builtin == "random": - if not len(self.args) == 2: - print(f"E006: Wrong number of arguments for builtin '{self.builtin}' ({len(self.args)})") - exit() - vtable, ftable, r1 = self.args[0].eval(vtable, ftable) vtable, ftable, r2 = self.args[1].eval(vtable, ftable) @@ -185,7 +192,7 @@ class Builtin(Command): return vtable, ftable, r else: - raise Exception(f"E005: Unknown builtin {self.builtin}") + raise Exception(f"Unknown builtin {self.builtin}") class Do(BaseBox): def __init__(self, command: Command): @@ -309,6 +316,22 @@ class StatementIf(Statement): else: return vtable, ftable, result +class StatementBecause(Statement): + def __init__(self, statement: Statement, condition): + self.statement = statement + self.condition = condition + + def __repr__(self) -> str: + return f"if({self.statement}, {self.condition})" + + def eval(self, vtable, ftable): + vtable, ftable, result = self.condition.eval(vtable, ftable) + if result: + return self.statement.eval(vtable, ftable) + else: + print("C001: Because assertion incorrect") + exit() + class StatementUntil(Statement): def __init__(self, statement: Statement, condition): self.statement = statement diff --git a/plthy_impl/lexer.py b/plthy_impl/lexer.py index f2d2a98..d8bdd38 100644 --- a/plthy_impl/lexer.py +++ b/plthy_impl/lexer.py @@ -9,13 +9,14 @@ KEYWORD_TOKENS = [("KEYWORD_"+i.upper(), i) for i in [ "maybe", "do", "if", -# "because", + "because", "until", "define", "as", "variable", "return", - "argument" + "argument", + "set" ]] BUILTIN_TOKENS = [("BUILTIN", i) for i in [ @@ -50,7 +51,7 @@ SYMBOL_TOKENS = [ ("SYMBOL_LT", r"\<"), ("SYMBOL_GT", r"\>"), ("SYMBOL_EQUALS", r"\="), - ("SYMBOL_DOLLAR", r"\$") +# ("SYMBOL_DOLLAR", r"\$") ] ALL_TOKENS = ( diff --git a/plthy_impl/parser.py b/plthy_impl/parser.py index 9674cd2..c48ef8f 100644 --- a/plthy_impl/parser.py +++ b/plthy_impl/parser.py @@ -9,9 +9,9 @@ class Parser(): [i[0] for i in ALL_TOKENS], precedence=[ ('left', ["KEYWORD_MAYBE", "KEYWORD_RETURN"]), - ('left', ["KEYWORD_IF", "KEYWORD_UNTIL", "KEYWORD_DEFINE", "KEYWORD_AS"]), - ('left', ["KEYWORD_DO", "BUILTIN"]), - ('left', ["SYMBOL_EQUALS", "SYMBOL_SET"]), + ('left', ["KEYWORD_IF", "KEYWORD_BECAUSE", "KEYWORD_UNTIL", "KEYWORD_DEFINE", "KEYWORD_AS"]), + ('left', ["KEYWORD_DO", "BUILTIN", "SYMBOL_SET"]), + ('left', ["SYMBOL_EQUALS"]), ('left', ["SYMBOL_PLUS", "SYMBOL_MINUS"]), ('left', ["SYMBOL_TIMES", "SYMBOL_DIVIDE", "SYMBOL_LT","SYMBOL_GT"]) ] @@ -33,7 +33,7 @@ class Parser(): return [tokens[0]] + tokens[2] ## statement ## - @self.pg.production('statement : SYMBOL_DOLLAR expression SYMBOL_SET ID', precedence="SYMBOL_SET") + @self.pg.production('statement : KEYWORD_SET expression SYMBOL_SET ID', precedence="SYMBOL_SET") def statement_set(tokens): return ast_nodes.StatementSet(tokens[1], tokens[3].value) @@ -49,6 +49,10 @@ class Parser(): def statement_if(tokens): return ast_nodes.StatementIf(tokens[0], tokens[2]) + @self.pg.production('statement : statement KEYWORD_BECAUSE expression') + def statement_because(tokens): + return ast_nodes.StatementBecause(tokens[0], tokens[2]) + @self.pg.production('statement : KEYWORD_UNTIL expression statement') def statement_until(tokens): return ast_nodes.StatementUntil(tokens[2],tokens[1]) @@ -68,7 +72,7 @@ class Parser(): ## command ## @self.pg.production('command : BUILTIN SYMBOL_LT expressions SYMBOL_GT') def command_builtin(tokens): - return ast_nodes.Builtin(tokens[0].value, tokens[2]) + return ast_nodes.Builtin(tokens[0], tokens[2]) @self.pg.production('command : SYMBOL_QUOTE ID SYMBOL_QUOTE SYMBOL_LT expressions SYMBOL_GT') def command_call(tokens): @@ -89,7 +93,7 @@ class Parser(): return ast_nodes.ExpInt(int(tokens[0].value)) @self.pg.production('expression : DATA_FLOAT') - def exp_int(tokens): + def exp_float(tokens): return ast_nodes.ExpInt(float(tokens[0].value)) @self.pg.production('expression : DATA_STRING') diff --git a/test.sh b/test.sh old mode 100644 new mode 100755 diff --git a/tests/02_variable.plthy b/tests/02_variable.plthy index b4e1676..fb6fe5b 100644 --- a/tests/02_variable.plthy +++ b/tests/02_variable.plthy @@ -1,4 +1,4 @@ hello| -$2 -> x| +set 2 -> x| do print| goodbye| \ No newline at end of file diff --git a/tests/03_math.plthy b/tests/03_math.plthy index 2e1cd5a..92898b2 100644 --- a/tests/03_math.plthy +++ b/tests/03_math.plthy @@ -1,10 +1,10 @@ hello| -$1 -> x| -$2 -> y| -$5 -> z| -$variable x+variable y -> z| // 3 -$5-variable z -> z| // 2 -$2*variable z -> x| // 4 -$variable x/variable y -> y| // 2 +set 1 -> x| +set 2 -> y| +set 5 -> z| +set variable x+variable y -> z| // 3 +set 5-variable z -> z| // 2 +set 2*variable z -> x| // 4 +set variable x/variable y -> y| // 2 do print| goodbye| \ No newline at end of file diff --git a/tests/04_scope.plthy b/tests/04_scope.plthy index a17f1a2..346168d 100644 --- a/tests/04_scope.plthy +++ b/tests/04_scope.plthy @@ -1,6 +1,6 @@ hello| [ - $5 -> x| + set 5 -> x| do print| ]| goodbye| \ No newline at end of file diff --git a/tests/05_maybe.plthy b/tests/05_maybe.plthy index ab547bd..8ceea39 100644 --- a/tests/05_maybe.plthy +++ b/tests/05_maybe.plthy @@ -1,5 +1,5 @@ hello| -$1 -> x| -maybe $variable x + 1 -> x| +set 1 -> x| +maybe set variable x + 1 -> x| do print| goodbye| \ No newline at end of file diff --git a/tests/06_if.plthy b/tests/06_if.plthy index b826fe4..98bcfae 100644 --- a/tests/06_if.plthy +++ b/tests/06_if.plthy @@ -1,5 +1,5 @@ hello| -$2 -> x| +set 2 -> x| do print<'a';> if variable x = 1| do print<'b';> if variable x = 2| goodbye| \ No newline at end of file diff --git a/tests/08_precedence.plthy b/tests/08_precedence.plthy index 203cca0..1fb801c 100644 --- a/tests/08_precedence.plthy +++ b/tests/08_precedence.plthy @@ -1,8 +1,8 @@ hello| -$ 1 + 2 * 3 -> x| +set 1 + 2 * 3 -> x| do print| -$ 5 -> y if variable x = 7| +set 5 -> y if variable x = 7| do print| -$$5 -> z + 1 -> a| +set set 5 -> z + 1 -> a| do print| goodbye| \ No newline at end of file diff --git a/tests/10_E001.plthy b/tests/10_E001.plthy index 15bcb54..29b2ef4 100644 --- a/tests/10_E001.plthy +++ b/tests/10_E001.plthy @@ -1,2 +1,2 @@ -$2 -> x| +set 2 -> x| goodbye| \ No newline at end of file diff --git a/tests/11_E002.plthy b/tests/11_E002.plthy index 7a71af5..3d74007 100644 --- a/tests/11_E002.plthy +++ b/tests/11_E002.plthy @@ -1,2 +1,2 @@ hello| -$2 -> x| \ No newline at end of file +set 2 -> x| \ No newline at end of file diff --git a/tests/12_list.plthy b/tests/12_list.plthy index e491c73..03ee620 100644 --- a/tests/12_list.plthy +++ b/tests/12_list.plthy @@ -1,6 +1,6 @@ hello| -${1;2;3;} -> x| +set {1;2;3;} -> x| do print| -${1;1+1;do print<3;>;} -> y| +set {1;1+1;do print<3;>;} -> y| do print| goodbye| \ No newline at end of file diff --git a/tests/13_because.expected b/tests/13_because.expected new file mode 100644 index 0000000..00750ed --- /dev/null +++ b/tests/13_because.expected @@ -0,0 +1 @@ +3 diff --git a/tests/13_because.plthy b/tests/13_because.plthy new file mode 100644 index 0000000..1e105c4 --- /dev/null +++ b/tests/13_because.plthy @@ -0,0 +1,5 @@ +hello| +set 2 -> x| +set 3 -> x because variable x = 2| +do print| +goodbye| \ No newline at end of file diff --git a/tests/14_E005-random.expected b/tests/14_E005-random.expected new file mode 100644 index 0000000..a44a167 --- /dev/null +++ b/tests/14_E005-random.expected @@ -0,0 +1 @@ +E005: Wrong number of arguments for builtin 'random' (1) at line 2 diff --git a/tests/14_E005-random.plthy b/tests/14_E005-random.plthy new file mode 100644 index 0000000..1e2dc2e --- /dev/null +++ b/tests/14_E005-random.plthy @@ -0,0 +1,3 @@ +hello| +do random<2;>| +goodbye| \ No newline at end of file diff --git a/tests/15_C001.expected b/tests/15_C001.expected new file mode 100644 index 0000000..37d9401 --- /dev/null +++ b/tests/15_C001.expected @@ -0,0 +1 @@ +C001: Because assertion incorrect diff --git a/tests/15_C001.plthy b/tests/15_C001.plthy new file mode 100644 index 0000000..f5cba89 --- /dev/null +++ b/tests/15_C001.plthy @@ -0,0 +1,5 @@ +hello| +set 2 -> x| +set 3 -> x because variable x = 3| +do print| +goodbye| \ No newline at end of file