From cee71787f4ee978a74635e9a3213f6edcf175e17 Mon Sep 17 00:00:00 2001 From: Nikolaj Gade Date: Wed, 21 Feb 2024 16:00:09 +0100 Subject: [PATCH] :sparkles: --- documentation/plthy.pdf | Bin 22309 -> 22597 bytes documentation/plthy.tex | 3 ++- examples/guessing_game.plthy | 12 ++++++------ plthy | 6 +++++- plthy_impl/ast_nodes.py | 20 ++++++++++++++++++++ plthy_impl/lexer.py | 4 +++- plthy_impl/parser.py | 8 ++++++++ tests/17_skip.expected | 0 tests/17_skip.plthy | 3 +++ tests/18_if-else.expected | 1 + tests/18_if-else.plthy | 3 +++ 11 files changed, 51 insertions(+), 9 deletions(-) create mode 100644 tests/17_skip.expected create mode 100644 tests/17_skip.plthy create mode 100644 tests/18_if-else.expected create mode 100644 tests/18_if-else.plthy diff --git a/documentation/plthy.pdf b/documentation/plthy.pdf index 09e5149117620a74816d56b46aa955853ef59d57..18f97b3010f4681b15c6af8327d6a09f2a3adf54 100644 GIT binary patch delta 11937 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 diff --git a/documentation/plthy.tex b/documentation/plthy.tex index 8228aff..7ddf0cc 100644 --- a/documentation/plthy.tex +++ b/documentation/plthy.tex @@ -14,7 +14,7 @@ \textit{program} & $\rightarrow$ & \texttt{hello} \texttt{|} \textit{statements} \texttt{goodbye} \texttt{|} \\ \hline \hline \textit{statements} & $\rightarrow$ & \\ \hline \textit{statements} & $\rightarrow$ & \textit{statement} \texttt{|} \textit{statements} \\ \hline\hline - \textit{statement} & $\rightarrow$ & \\ \hline + \textit{statement} & $\rightarrow$ & \texttt{skip} \\ \hline \textit{statement} & $\rightarrow$ & \texttt{maybe} \textit{statement}\\ \hline \textit{statement} & $\rightarrow$ & \texttt{do} \textit{command}\\ \hline \textit{statement} & $\rightarrow$ & \texttt{[} \textit{statements} \texttt{]}\\ \hline @@ -22,6 +22,7 @@ \textit{statement} & $\rightarrow$ & \texttt{define} \textbf{function} \texttt{<} \textbf{int} \texttt{>} \texttt{as} \textit{statement} \\ \hline \textit{statement} & $\rightarrow$ & \texttt{return} \textit{expression} \\ \hline\hline \textit{command} & $\rightarrow$ & \textit{statement} \texttt{if} \textit{expression} \\ \hline + \textit{command} & $\rightarrow$ & \textit{statement} \texttt{if} \textit{expression} \textit{else} \textit{statement} \\ \hline \textit{command} & $\rightarrow$ & \textit{statement} \texttt{because} \textit{expression} \\ \hline \textit{command} & $\rightarrow$ & \textit{statement} \texttt{until} \textit{expression} \\ \hline \textit{command} & $\rightarrow$ & \textbf{builtin} \texttt{<} \textit{expressions} \texttt{>} \\ \hline diff --git a/examples/guessing_game.plthy b/examples/guessing_game.plthy index c6798ca..68853e6 100644 --- a/examples/guessing_game.plthy +++ b/examples/guessing_game.plthy @@ -1,10 +1,10 @@ hello| -set do random<1;128;> -> n| +set do random<1;128;> -> r| set 0 -> guess| -until variable guess = variable n [ +do [ 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| -]| + do do print<'too high';> if variable guess > variable r| + do do print<'too low';> if variable guess < variable r| + do do print<'correct!';> if variable guess = variable r| +] until variable guess = variable r| goodbye| \ No newline at end of file diff --git a/plthy b/plthy index 89afb42..aeb860a 100755 --- a/plthy +++ b/plthy @@ -2,12 +2,13 @@ """ Usage: plthy (-h| --help) - plthy (-i| -c) FILE + plthy (-i| -c) [-p] FILE Options: -h --help Print this help screen -i Run the interpreter -c Run the compiler + -p Print the program structure FILE The file to compile/interpret """ from docopt import docopt @@ -30,6 +31,9 @@ def main(): program = parser.parse(tokens) if isinstance(program, Program): + if args["-p"]: + print(program) + if args["-i"]: program.eval() else: diff --git a/plthy_impl/ast_nodes.py b/plthy_impl/ast_nodes.py index c849bab..a6955bd 100644 --- a/plthy_impl/ast_nodes.py +++ b/plthy_impl/ast_nodes.py @@ -211,6 +211,10 @@ class Statement(BaseBox): def __repr__(self) -> str: return f"statement()" +class StatementSkip(Statement): + def __repr__(self) -> str: + return f"skip()" + class StatementSet(Statement): def __init__(self, expression: Exp, variable: str): self.expression = expression @@ -316,6 +320,22 @@ class CommandIf(Command): else: return vtable, ftable, result +class CommandIfElse(Command): + def __init__(self, statement: Statement, else_statement: Statement, condition): + self.statement = statement + self.else_statement = else_statement + self.condition = condition + + def __repr__(self) -> str: + return f"ifelse({self.statement}, {self.condition}, {self.else_statement})" + + def eval(self, vtable, ftable): + vtable, ftable, result = self.condition.eval(vtable, ftable) + if result: + return self.statement.eval(vtable, ftable) + else: + return self.else_statement.eval(vtable, ftable) + class CommandBecause(Command): def __init__(self, statement: Statement, condition): self.statement = statement diff --git a/plthy_impl/lexer.py b/plthy_impl/lexer.py index 25aded3..d5a5ddc 100644 --- a/plthy_impl/lexer.py +++ b/plthy_impl/lexer.py @@ -16,7 +16,9 @@ KEYWORD_TOKENS = [("KEYWORD_"+i.upper(), i) for i in [ "variable", "return", "argument", - "set" + "set", + "skip", + "else" ]] BUILTIN_TOKENS = [("BUILTIN", i) for i in [ diff --git a/plthy_impl/parser.py b/plthy_impl/parser.py index 34f49c2..2d4f7d5 100644 --- a/plthy_impl/parser.py +++ b/plthy_impl/parser.py @@ -33,6 +33,10 @@ class Parser(): return [tokens[0]] + tokens[2] ## statement ## + @self.pg.production('statement : KEYWORD_SKIP') + def statement_skip(tokens): + return ast_nodes.StatementSkip() + @self.pg.production('statement : KEYWORD_SET expression SYMBOL_SET ID') def statement_set(tokens): return ast_nodes.StatementSet(tokens[1], tokens[3].value) @@ -70,6 +74,10 @@ class Parser(): def command_if(tokens): return ast_nodes.CommandIf(tokens[0], tokens[2]) + @self.pg.production('command : statement KEYWORD_ELSE statement KEYWORD_IF expression') + def command_ifelse(tokens): + return ast_nodes.CommandIfElse(tokens[0],tokens[2],tokens[4]) + @self.pg.production('command : statement KEYWORD_BECAUSE expression') def command_because(tokens): return ast_nodes.CommandBecause(tokens[0], tokens[2]) diff --git a/tests/17_skip.expected b/tests/17_skip.expected new file mode 100644 index 0000000..e69de29 diff --git a/tests/17_skip.plthy b/tests/17_skip.plthy new file mode 100644 index 0000000..518261f --- /dev/null +++ b/tests/17_skip.plthy @@ -0,0 +1,3 @@ +hello| +skip| +goodbye| \ No newline at end of file diff --git a/tests/18_if-else.expected b/tests/18_if-else.expected new file mode 100644 index 0000000..0cfbf08 --- /dev/null +++ b/tests/18_if-else.expected @@ -0,0 +1 @@ +2 diff --git a/tests/18_if-else.plthy b/tests/18_if-else.plthy new file mode 100644 index 0000000..cf5315c --- /dev/null +++ b/tests/18_if-else.plthy @@ -0,0 +1,3 @@ +hello| +do do do print<1;> else do print<3;> if 1=1 else do print<2;> if 1=2| +goodbye| \ No newline at end of file