✨
This commit is contained in:
Binary file not shown.
@ -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}
|
@ -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|
|
||||
|
@ -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
|
||||
|
@ -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 = (
|
||||
|
@ -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')
|
||||
|
@ -1,4 +1,4 @@
|
||||
hello|
|
||||
$2 -> x|
|
||||
set 2 -> x|
|
||||
do print<variable x;>|
|
||||
goodbye|
|
@ -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<variable x;variable y;variable z;>|
|
||||
goodbye|
|
@ -1,6 +1,6 @@
|
||||
hello|
|
||||
[
|
||||
$5 -> x|
|
||||
set 5 -> x|
|
||||
do print<variable x;>|
|
||||
]|
|
||||
goodbye|
|
@ -1,5 +1,5 @@
|
||||
hello|
|
||||
$1 -> x|
|
||||
maybe $variable x + 1 -> x|
|
||||
set 1 -> x|
|
||||
maybe set variable x + 1 -> x|
|
||||
do print<variable x;>|
|
||||
goodbye|
|
@ -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|
|
@ -1,8 +1,8 @@
|
||||
hello|
|
||||
$ 1 + 2 * 3 -> x|
|
||||
set 1 + 2 * 3 -> x|
|
||||
do print<variable x;>|
|
||||
$ 5 -> y if variable x = 7|
|
||||
set 5 -> y if variable x = 7|
|
||||
do print<variable y;>|
|
||||
$$5 -> z + 1 -> a|
|
||||
set set 5 -> z + 1 -> a|
|
||||
do print<variable z; variable a;>|
|
||||
goodbye|
|
@ -1,2 +1,2 @@
|
||||
$2 -> x|
|
||||
set 2 -> x|
|
||||
goodbye|
|
@ -1,2 +1,2 @@
|
||||
hello|
|
||||
$2 -> x|
|
||||
set 2 -> x|
|
@ -1,6 +1,6 @@
|
||||
hello|
|
||||
${1;2;3;} -> x|
|
||||
set {1;2;3;} -> x|
|
||||
do print<variable x;>|
|
||||
${1;1+1;do print<3;>;} -> y|
|
||||
set {1;1+1;do print<3;>;} -> y|
|
||||
do print<variable y{5 - 4};>|
|
||||
goodbye|
|
1
tests/13_because.expected
Normal file
1
tests/13_because.expected
Normal file
@ -0,0 +1 @@
|
||||
3
|
5
tests/13_because.plthy
Normal file
5
tests/13_because.plthy
Normal file
@ -0,0 +1,5 @@
|
||||
hello|
|
||||
set 2 -> x|
|
||||
set 3 -> x because variable x = 2|
|
||||
do print<variable x;>|
|
||||
goodbye|
|
1
tests/14_E005-random.expected
Normal file
1
tests/14_E005-random.expected
Normal file
@ -0,0 +1 @@
|
||||
E005: Wrong number of arguments for builtin 'random' (1) at line 2
|
3
tests/14_E005-random.plthy
Normal file
3
tests/14_E005-random.plthy
Normal file
@ -0,0 +1,3 @@
|
||||
hello|
|
||||
do random<2;>|
|
||||
goodbye|
|
1
tests/15_C001.expected
Normal file
1
tests/15_C001.expected
Normal file
@ -0,0 +1 @@
|
||||
C001: Because assertion incorrect
|
5
tests/15_C001.plthy
Normal file
5
tests/15_C001.plthy
Normal file
@ -0,0 +1,5 @@
|
||||
hello|
|
||||
set 2 -> x|
|
||||
set 3 -> x because variable x = 3|
|
||||
do print<variable x;>|
|
||||
goodbye|
|
Reference in New Issue
Block a user