✨
This commit is contained in:
@ -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')
|
||||
|
Reference in New Issue
Block a user