This commit is contained in:
2024-02-21 16:00:09 +01:00
parent ee2817afbb
commit cee71787f4
11 changed files with 51 additions and 9 deletions

Binary file not shown.

View File

@ -14,7 +14,7 @@
\textit{program} & $\rightarrow$ & \texttt{hello} \texttt{|} \textit{statements} \texttt{goodbye} \texttt{|} \\ \hline \hline \textit{program} & $\rightarrow$ & \texttt{hello} \texttt{|} \textit{statements} \texttt{goodbye} \texttt{|} \\ \hline \hline
\textit{statements} & $\rightarrow$ & \\ \hline \textit{statements} & $\rightarrow$ & \\ \hline
\textit{statements} & $\rightarrow$ & \textit{statement} \texttt{|} \textit{statements} \\ \hline\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{maybe} \textit{statement}\\ \hline
\textit{statement} & $\rightarrow$ & \texttt{do} \textit{command}\\ \hline \textit{statement} & $\rightarrow$ & \texttt{do} \textit{command}\\ \hline
\textit{statement} & $\rightarrow$ & \texttt{[} \textit{statements} \texttt{]}\\ \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{define} \textbf{function} \texttt{<} \textbf{int} \texttt{>} \texttt{as} \textit{statement} \\ \hline
\textit{statement} & $\rightarrow$ & \texttt{return} \textit{expression} \\ \hline\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} \\ \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{because} \textit{expression} \\ \hline
\textit{command} & $\rightarrow$ & \textit{statement} \texttt{until} \textit{expression} \\ \hline \textit{command} & $\rightarrow$ & \textit{statement} \texttt{until} \textit{expression} \\ \hline
\textit{command} & $\rightarrow$ & \textbf{builtin} \texttt{<} \textit{expressions} \texttt{>} \\ \hline \textit{command} & $\rightarrow$ & \textbf{builtin} \texttt{<} \textit{expressions} \texttt{>} \\ \hline

View File

@ -1,10 +1,10 @@
hello| hello|
set do random<1;128;> -> n| set do random<1;128;> -> r|
set 0 -> guess| set 0 -> guess|
until variable guess = variable n [ do [
set do input<'guess: ';> -> guess| set do input<'guess: ';> -> guess|
do print<'too high';> if variable guess > variable n| do do print<'too high';> if variable guess > variable r|
do print<'too low';> if variable guess < variable n| do do print<'too low';> if variable guess < variable r|
do print<'correct!';> if variable guess = variable n| do do print<'correct!';> if variable guess = variable r|
]| ] until variable guess = variable r|
goodbye| goodbye|

6
plthy
View File

@ -2,12 +2,13 @@
""" """
Usage: Usage:
plthy (-h| --help) plthy (-h| --help)
plthy (-i| -c) FILE plthy (-i| -c) [-p] FILE
Options: Options:
-h --help Print this help screen -h --help Print this help screen
-i Run the interpreter -i Run the interpreter
-c Run the compiler -c Run the compiler
-p Print the program structure
FILE The file to compile/interpret FILE The file to compile/interpret
""" """
from docopt import docopt from docopt import docopt
@ -30,6 +31,9 @@ def main():
program = parser.parse(tokens) program = parser.parse(tokens)
if isinstance(program, Program): if isinstance(program, Program):
if args["-p"]:
print(program)
if args["-i"]: if args["-i"]:
program.eval() program.eval()
else: else:

View File

@ -211,6 +211,10 @@ class Statement(BaseBox):
def __repr__(self) -> str: def __repr__(self) -> str:
return f"statement()" return f"statement()"
class StatementSkip(Statement):
def __repr__(self) -> str:
return f"skip()"
class StatementSet(Statement): class StatementSet(Statement):
def __init__(self, expression: Exp, variable: str): def __init__(self, expression: Exp, variable: str):
self.expression = expression self.expression = expression
@ -316,6 +320,22 @@ class CommandIf(Command):
else: else:
return vtable, ftable, result 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): class CommandBecause(Command):
def __init__(self, statement: Statement, condition): def __init__(self, statement: Statement, condition):
self.statement = statement self.statement = statement

View File

@ -16,7 +16,9 @@ KEYWORD_TOKENS = [("KEYWORD_"+i.upper(), i) for i in [
"variable", "variable",
"return", "return",
"argument", "argument",
"set" "set",
"skip",
"else"
]] ]]
BUILTIN_TOKENS = [("BUILTIN", i) for i in [ BUILTIN_TOKENS = [("BUILTIN", i) for i in [

View File

@ -33,6 +33,10 @@ class Parser():
return [tokens[0]] + tokens[2] return [tokens[0]] + tokens[2]
## statement ## ## 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') @self.pg.production('statement : KEYWORD_SET expression SYMBOL_SET ID')
def statement_set(tokens): def statement_set(tokens):
return ast_nodes.StatementSet(tokens[1], tokens[3].value) return ast_nodes.StatementSet(tokens[1], tokens[3].value)
@ -70,6 +74,10 @@ class Parser():
def command_if(tokens): def command_if(tokens):
return ast_nodes.CommandIf(tokens[0], tokens[2]) 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') @self.pg.production('command : statement KEYWORD_BECAUSE expression')
def command_because(tokens): def command_because(tokens):
return ast_nodes.CommandBecause(tokens[0], tokens[2]) return ast_nodes.CommandBecause(tokens[0], tokens[2])

0
tests/17_skip.expected Normal file
View File

3
tests/17_skip.plthy Normal file
View File

@ -0,0 +1,3 @@
hello|
skip|
goodbye|

View File

@ -0,0 +1 @@
2

3
tests/18_if-else.plthy Normal file
View File

@ -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|