diff --git a/documentation/plthy.pdf b/documentation/plthy.pdf index 09e5149..18f97b3 100644 Binary files a/documentation/plthy.pdf and b/documentation/plthy.pdf differ 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