✨
This commit is contained in:
0
centvrion/__init__.py
Normal file
0
centvrion/__init__.py
Normal file
386
centvrion/ast_nodes.py
Normal file
386
centvrion/ast_nodes.py
Normal file
@@ -0,0 +1,386 @@
|
||||
import random
|
||||
import roman
|
||||
|
||||
from rply.token import BaseBox as BB
|
||||
|
||||
NUMERALS = [
|
||||
("I", 1),
|
||||
("V", 5),
|
||||
("X", 10),
|
||||
("L", 50),
|
||||
("C", 100),
|
||||
("D", 500),
|
||||
("M", 1000)
|
||||
]
|
||||
|
||||
def rep_join(l):
|
||||
format_string = ',\n'.join(
|
||||
[repr(i) if not isinstance(i, str) else i for i in l]
|
||||
).replace('\n', '\n ')
|
||||
|
||||
if format_string != "":
|
||||
format_string = f"\n {format_string}\n"
|
||||
|
||||
return format_string
|
||||
|
||||
# TODO: Magnum
|
||||
def num_to_int(n):
|
||||
return roman.fromRoman(n)
|
||||
|
||||
def make_string(n):
|
||||
if isinstance(n, str):
|
||||
return n
|
||||
elif isinstance(n, int):
|
||||
return roman.toRoman(n)
|
||||
elif isinstance(n, list):
|
||||
return f"[{' '.join([make_string(i) for i in n])}]"
|
||||
else:
|
||||
raise Exception(n)
|
||||
|
||||
class BaseBox(BB):
|
||||
def eval(self, vtable, ftable, modules):
|
||||
return None
|
||||
|
||||
class ExpressionStatement(BaseBox):
|
||||
def __init__(self, expression) -> None:
|
||||
self.expression = expression
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return self.expression.__repr__()
|
||||
|
||||
def eval(self, vtable, ftable, modules):
|
||||
self.expression.eval(vtable.copy(), ftable.copy(), modules)
|
||||
return vtable, ftable
|
||||
|
||||
class DataArray(BaseBox):
|
||||
def __init__(self, content) -> None:
|
||||
self.content = content
|
||||
|
||||
def __repr__(self) -> str:
|
||||
content_string = rep_join(self.content)
|
||||
return f"Array([{content_string}])"
|
||||
|
||||
def eval(self, vtable, ftable, modules):
|
||||
content = [i.eval(vtable, ftable, modules) for i in self.content]
|
||||
return content
|
||||
|
||||
class DataRangeArray(BaseBox):
|
||||
def __init__(self, from_value, to_value) -> None:
|
||||
self.from_value = from_value
|
||||
self.to_value = to_value
|
||||
|
||||
def __repr__(self) -> str:
|
||||
content_string = rep_join([self.from_value, self.to_value])
|
||||
return f"RangeArray([{content_string}])"
|
||||
|
||||
def eval(self, *_):
|
||||
content = list(range(self.from_value.eval(), self.to_value.eval()))
|
||||
return content
|
||||
|
||||
class String(BaseBox):
|
||||
def __init__(self, value) -> None:
|
||||
self.value = value
|
||||
|
||||
def __repr__(self):
|
||||
return f"String({self.value})"
|
||||
|
||||
def eval(self, *_):
|
||||
return self.value
|
||||
|
||||
class Numeral(BaseBox):
|
||||
def __init__(self, value) -> None:
|
||||
self.value = value
|
||||
|
||||
def __repr__(self):
|
||||
return f"Numeral({self.value})"
|
||||
|
||||
def eval(self, *_):
|
||||
return num_to_int(self.value)
|
||||
|
||||
class Bool(BaseBox):
|
||||
def __init__(self, value) -> None:
|
||||
self.value = value
|
||||
|
||||
def __repr__(self):
|
||||
return f"Bool({self.value})"
|
||||
|
||||
def eval(self, *_):
|
||||
return self.value
|
||||
|
||||
class ModuleCall(BaseBox):
|
||||
def __init__(self, module_name) -> None:
|
||||
self.module_name = module_name
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"{self.module_name}"
|
||||
|
||||
class ID(BaseBox):
|
||||
def __init__(self, name: str) -> None:
|
||||
self.name = name
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"ID({self.name})"
|
||||
|
||||
def eval(self, vtable, *_):
|
||||
return vtable[self.name]
|
||||
|
||||
class Designa(BaseBox):
|
||||
def __init__(self, variable: ID, value) -> None:
|
||||
self.id = variable
|
||||
self.value = value
|
||||
|
||||
def __repr__(self) -> str:
|
||||
id_string = repr(self.id).replace('\n', '\n ')
|
||||
value_string = repr(self.value).replace('\n', '\n ')
|
||||
return f"Designa(\n {id_string},\n {value_string}\n)"
|
||||
|
||||
def eval(self, vtable, ftable, modules):
|
||||
vtable[self.id.name] = self.value.eval(
|
||||
vtable.copy(), ftable.copy(), modules
|
||||
)
|
||||
return vtable, ftable
|
||||
|
||||
class Defini(BaseBox):
|
||||
def __init__(self, name, parameters, statements) -> None:
|
||||
self.name = name
|
||||
self.parameters = parameters
|
||||
self.statements = statements
|
||||
|
||||
def __repr__(self) -> str:
|
||||
parameter_string = f"parameters([{rep_join(self.parameters)}])"
|
||||
statements_string = f"statements([{rep_join(self.statements)}])"
|
||||
def_string = rep_join(
|
||||
[f"{repr(self.name)}", parameter_string, statements_string]
|
||||
)
|
||||
return f"Defini({def_string})"
|
||||
|
||||
def eval(self, vtable, ftable, _):
|
||||
ftable[self.name.name] = (
|
||||
self.parameters, self.statements
|
||||
)
|
||||
return vtable, ftable
|
||||
|
||||
class Redi(BaseBox):
|
||||
def __init__(self, values) -> None:
|
||||
self.values = values
|
||||
|
||||
def __repr__(self) -> str:
|
||||
values_string = f"[{rep_join(self.values)}]"
|
||||
return f"Redi({values_string})"
|
||||
|
||||
def eval(self, vtable, ftable, modules):
|
||||
values = [
|
||||
i.eval(vtable.copy(), ftable.copy(), modules)
|
||||
for i in self.values
|
||||
]
|
||||
if len(values) == 1:
|
||||
vtable["REDI"] = values[0]
|
||||
else:
|
||||
vtable["REDI"] = values
|
||||
return vtable, ftable
|
||||
|
||||
class Erumpe(BaseBox):
|
||||
def __repr__(self) -> str:
|
||||
return "Erumpe()"
|
||||
|
||||
def eval(self, vtable, ftable, _):
|
||||
vtable["ERVMPE"] = True
|
||||
return vtable, ftable
|
||||
|
||||
class Nullus(BaseBox):
|
||||
def __repr__(self) -> str:
|
||||
return "Nullus()"
|
||||
|
||||
def eval(self, *_):
|
||||
return 0
|
||||
|
||||
class BinOp(BaseBox):
|
||||
def __init__(self, left, right, op) -> None:
|
||||
self.left = left
|
||||
self.right = right
|
||||
self.op = op
|
||||
|
||||
def __repr__(self) -> str:
|
||||
binop_string = rep_join([self.left, self.right, self.op])
|
||||
return f"BinOp({binop_string})"
|
||||
|
||||
def eval(self, vtable, ftable, modules):
|
||||
left = self.left.eval(vtable.copy(), ftable.copy(), modules)
|
||||
right = self.right.eval(vtable.copy(), ftable.copy(), modules)
|
||||
match self.op:
|
||||
case "SYMBOL_PLUS":
|
||||
return left + right
|
||||
case "SYMBOL_MINUS":
|
||||
return left - right
|
||||
case "SYMBOL_TIMES":
|
||||
return left * right
|
||||
case "SYMBOL_DIVIDE":
|
||||
# TODO: Fractio
|
||||
return left // right
|
||||
case "KEYWORD_MINVS":
|
||||
return left < right
|
||||
case "KEYWORD_PLVS":
|
||||
return left > right
|
||||
case "KEYWORD_EST":
|
||||
return left == right
|
||||
case _:
|
||||
raise Exception(self.op)
|
||||
|
||||
class SiStatement(BaseBox):
|
||||
def __init__(self, test, statements, else_part) -> None:
|
||||
self.test = test
|
||||
self.statements = statements
|
||||
self.else_part = else_part
|
||||
|
||||
def __repr__(self) -> str:
|
||||
test = repr(self.test)
|
||||
statements = f"statements([{rep_join(self.statements)}])"
|
||||
else_part = f"statements([{rep_join(self.else_part)}])"
|
||||
si_string = rep_join([test, statements, else_part])
|
||||
return f"Si({si_string})"
|
||||
|
||||
def eval(self, vtable, ftable, modules):
|
||||
if self.test.eval(vtable, ftable, modules):
|
||||
for statement in self.statements:
|
||||
vtable, ftable = statement.eval(
|
||||
vtable, ftable, modules
|
||||
)
|
||||
else:
|
||||
for statement in self.else_part:
|
||||
vtable, ftable = statement.eval(
|
||||
vtable, ftable, modules
|
||||
)
|
||||
|
||||
return vtable, ftable
|
||||
|
||||
class DumStatement(BaseBox):
|
||||
def __init__(self, test, statements) -> None:
|
||||
self.test = test
|
||||
self.statements = statements
|
||||
|
||||
def __repr__(self) -> str:
|
||||
test = repr(self.test)
|
||||
statements = f"statements([{rep_join(self.statements)}])"
|
||||
dum_string = rep_join([test, statements])
|
||||
return f"Dum({dum_string})"
|
||||
|
||||
def eval(self, vtable, ftable, modules):
|
||||
while not self.test.eval(vtable, ftable, modules):
|
||||
for statement in self.statements:
|
||||
vtable, ftable = statement.eval(
|
||||
vtable, ftable, modules
|
||||
)
|
||||
if vtable["ERVMPE"]:
|
||||
break
|
||||
|
||||
if vtable["ERVMPE"]:
|
||||
vtable["ERVMPE"] = False
|
||||
break
|
||||
|
||||
return vtable, ftable
|
||||
|
||||
class PerStatement(BaseBox):
|
||||
def __init__(self, data_list, variable_name, statements) -> None:
|
||||
self.data_list = data_list
|
||||
self.variable_name = variable_name
|
||||
self.statements = statements
|
||||
|
||||
def __repr__(self) -> str:
|
||||
test = repr(self.data_list)
|
||||
variable_name = repr(self.variable_name)
|
||||
statements = f"statements([{rep_join(self.statements)}])"
|
||||
dum_string = rep_join([test, variable_name, statements])
|
||||
return f"Per({dum_string})"
|
||||
|
||||
def eval(self, vtable, ftable, modules):
|
||||
data_array = self.data_list.eval(vtable, ftable, modules)
|
||||
variable_name = self.variable_name.name
|
||||
for i in data_array:
|
||||
vtable[variable_name] = i
|
||||
for statement in self.statements:
|
||||
vtable, ftable = statement.eval(
|
||||
vtable, ftable, modules
|
||||
)
|
||||
if vtable["ERVMPE"]:
|
||||
break
|
||||
|
||||
if vtable["ERVMPE"]:
|
||||
vtable["ERVMPE"] = False
|
||||
break
|
||||
|
||||
return vtable, ftable
|
||||
|
||||
class Invoca(BaseBox):
|
||||
def __init__(self, name, parameters) -> None:
|
||||
self.name = name
|
||||
self.parameters = parameters
|
||||
|
||||
def __repr__(self) -> str:
|
||||
parameters_string = f"parameters([{rep_join(self.parameters)}])"
|
||||
invoca_string = rep_join([self.name, parameters_string])
|
||||
return f"Invoca({invoca_string})"
|
||||
|
||||
def eval(self, vtable, ftable, modules):
|
||||
parameters = [
|
||||
i.eval(vtable.copy(), ftable.copy(), modules)
|
||||
for i in self.parameters
|
||||
]
|
||||
vtable_copy = vtable.copy()
|
||||
function = ftable[self.name.name]
|
||||
for i, parameter in enumerate(function[0]):
|
||||
vtable_copy[parameter.name] = parameters[i]
|
||||
|
||||
vtable_copy["REDI"] = None
|
||||
for statement in function[1]:
|
||||
statement.eval(vtable_copy, ftable, modules)
|
||||
if vtable_copy["REDI"] is not None:
|
||||
return vtable_copy["REDI"]
|
||||
|
||||
class BuiltIn(BaseBox):
|
||||
def __init__(self, builtin, parameters) -> None:
|
||||
self.builtin = builtin
|
||||
self.parameters = parameters
|
||||
|
||||
def __repr__(self) -> str:
|
||||
parameter_string = f"parameters([{rep_join(self.parameters)}])"
|
||||
builtin_string = rep_join([self.builtin, parameter_string])
|
||||
return f"Builtin({builtin_string})"
|
||||
|
||||
def eval(self, vtable, ftable, modules):
|
||||
parameters = [
|
||||
i.eval(vtable.copy(), ftable.copy(), modules)
|
||||
for i in self.parameters
|
||||
]
|
||||
|
||||
match self.builtin:
|
||||
case "AVDI_NVMERVS":
|
||||
return num_to_int(input())
|
||||
case "DICE":
|
||||
print(' '.join(make_string(i) for i in parameters))
|
||||
return None
|
||||
case "ERVMPE":
|
||||
vtable["ERVMPE"] = True
|
||||
return None
|
||||
case "FORTIS_NVMERVS":
|
||||
# TODO: Fors
|
||||
return random.randint(parameters[0], parameters[1])
|
||||
case _:
|
||||
raise Exception(self.builtin)
|
||||
|
||||
class Program(BaseBox):
|
||||
def __init__(self, module_calls: list[ModuleCall], statements) -> None:
|
||||
self.modules = module_calls
|
||||
self.statements = statements
|
||||
|
||||
def __repr__(self) -> str:
|
||||
modules_string = f"modules([{rep_join(self.modules)}])"
|
||||
statements_string = f"statements([{rep_join(self.statements)}])"
|
||||
return f"{modules_string},\n{statements_string}"
|
||||
|
||||
def eval(self, *_):
|
||||
vtable = {"ERVMPE": False}
|
||||
ftable = {}
|
||||
modules = [module.module_name for module in self.modules]
|
||||
|
||||
for statement in self.statements:
|
||||
vtable, ftable = statement.eval(vtable, ftable, modules)
|
||||
89
centvrion/lexer.py
Normal file
89
centvrion/lexer.py
Normal file
@@ -0,0 +1,89 @@
|
||||
from rply import LexerGenerator
|
||||
|
||||
valid_characters = '|'.join(list("abcdefghiklmnopqrstvxyz_"))
|
||||
|
||||
keyword_tokens = [("KEYWORD_"+i, i) for i in [
|
||||
"ALVID",
|
||||
"DEFINI",
|
||||
"DESIGNA",
|
||||
"DONICVM",
|
||||
"DVM",
|
||||
"ERVMPE",
|
||||
"EST",
|
||||
"FACE",
|
||||
"FALSITAS",
|
||||
"INVOCA",
|
||||
"IN",
|
||||
"MINVS",
|
||||
"NVLLVS",
|
||||
"PER",
|
||||
"PLVS",
|
||||
"REDI",
|
||||
"SI",
|
||||
"TVNC",
|
||||
"VSQVE",
|
||||
"VT",
|
||||
"VERITAS",
|
||||
"VOCA"
|
||||
]]
|
||||
|
||||
builtin_tokens = [("BUILTIN", i) for i in [
|
||||
"AVDI_NVMERVS",
|
||||
"AVDI",
|
||||
"DICE",
|
||||
"FORTIS_NVMERVS",
|
||||
"FORTIS_ELECTIONIS",
|
||||
"LONGITVDO"
|
||||
]]
|
||||
|
||||
data_tokens = [
|
||||
("DATA_STRING", r"\".*?\""),
|
||||
("DATA_NUMERAL", r"[IVXLCDM]+")
|
||||
]
|
||||
|
||||
module_tokens = [("MODULE", i) for i in [
|
||||
"FORS",
|
||||
"FRACTIO",
|
||||
"MAGNVM",
|
||||
"SVBNVLLA"
|
||||
]]
|
||||
|
||||
symbol_tokens = [
|
||||
("SYMBOL_LPARENS", r"\("),
|
||||
("SYMBOL_RPARENS", r"\)"),
|
||||
("SYMBOL_LBRACKET", r"\["),
|
||||
("SYMBOL_RBRACKET", r"\]"),
|
||||
("SYMBOL_LCURL", r"\{"),
|
||||
("SYMBOL_RCURL", r"\}"),
|
||||
("SYMBOL_PLUS", r"\+"),
|
||||
("SYMBOL_MINUS", r"\-"),
|
||||
("SYMBOL_TIMES", r"\*"),
|
||||
("SYMBOL_DIVIDE", r"\/")
|
||||
]
|
||||
|
||||
whitespace_tokens = [
|
||||
("NEWLINE", r"\n+")
|
||||
]
|
||||
|
||||
all_tokens = (
|
||||
keyword_tokens +
|
||||
builtin_tokens +
|
||||
module_tokens +
|
||||
symbol_tokens +
|
||||
data_tokens +
|
||||
whitespace_tokens +
|
||||
[("ID", f"({valid_characters})+")]
|
||||
)
|
||||
|
||||
class Lexer():
|
||||
def __init__(self):
|
||||
self.lexer = LexerGenerator()
|
||||
|
||||
def _add_tokens(self):
|
||||
for token in all_tokens:
|
||||
self.lexer.add(*token)
|
||||
self.lexer.ignore(r" +")
|
||||
|
||||
def get_lexer(self):
|
||||
self._add_tokens()
|
||||
return self.lexer.build()
|
||||
184
centvrion/parser.py
Normal file
184
centvrion/parser.py
Normal file
@@ -0,0 +1,184 @@
|
||||
from rply import ParserGenerator
|
||||
|
||||
from centvrion.lexer import all_tokens
|
||||
from . import ast_nodes
|
||||
|
||||
ALL_TOKENS = list(set([i[0] for i in all_tokens]))
|
||||
|
||||
class Parser():
|
||||
def __init__(self):
|
||||
self.pg = ParserGenerator(
|
||||
ALL_TOKENS,
|
||||
precedence=[
|
||||
('left', ["KEYWORD_PLVS", "KEYWORD_MINVS", "KEYWORD_EST"]),
|
||||
('left', ["SYMBOL_PLUS", "SYMBOL_MINUS"]),
|
||||
('left', ["SYMBOL_TIMES", "SYMBOL_DIVIDE"])
|
||||
]
|
||||
)
|
||||
|
||||
def parse(self, tokens_input) -> ast_nodes.BaseBox:
|
||||
@self.pg.production('program : opt_newline module_calls statements')
|
||||
def program(tokens):
|
||||
return ast_nodes.Program(tokens[-2], tokens[-1])
|
||||
|
||||
@self.pg.production('opt_newline : ')
|
||||
@self.pg.production('opt_newline : NEWLINE')
|
||||
def opt_newline(_):
|
||||
return None
|
||||
|
||||
@self.pg.production('module_calls : ')
|
||||
@self.pg.production('module_calls : module_call NEWLINE module_calls')
|
||||
def module_calls(calls):
|
||||
if len(calls) == 0:
|
||||
return []
|
||||
else:
|
||||
return [calls[0]] + calls[2]
|
||||
|
||||
@self.pg.production('module_call : KEYWORD_VOCA MODULE')
|
||||
def module_call(tokens):
|
||||
return ast_nodes.ModuleCall(tokens[1].value)
|
||||
|
||||
@self.pg.production('statements : ')
|
||||
@self.pg.production('statements : statement NEWLINE statements')
|
||||
def statements(calls):
|
||||
if len(calls) == 0:
|
||||
return []
|
||||
else:
|
||||
return [calls[0]] + calls[2]
|
||||
|
||||
@self.pg.production('statement : KEYWORD_DESIGNA id KEYWORD_VT expression')
|
||||
def statement_designa(tokens):
|
||||
return ast_nodes.Designa(tokens[1], tokens[3])
|
||||
|
||||
@self.pg.production('statement : expression')
|
||||
def statement_expression(tokens):
|
||||
return ast_nodes.ExpressionStatement(tokens[0])
|
||||
|
||||
@self.pg.production('expressions : ')
|
||||
@self.pg.production('expressions : expression expressions')
|
||||
def expressions(calls):
|
||||
if len(calls) == 0:
|
||||
return []
|
||||
else:
|
||||
return [calls[0]] + calls[1]
|
||||
|
||||
@self.pg.production('ids : ')
|
||||
@self.pg.production('ids : id ids')
|
||||
def ids(calls):
|
||||
if len(calls) == 0:
|
||||
return []
|
||||
else:
|
||||
return [calls[0]] + calls[1]
|
||||
|
||||
@self.pg.production('expression : id')
|
||||
def expression_id(tokens):
|
||||
return tokens[0]
|
||||
|
||||
@self.pg.production('statement : KEYWORD_DEFINI id ids KEYWORD_VT SYMBOL_LCURL opt_newline statements opt_newline SYMBOL_RCURL')
|
||||
def defini(tokens):
|
||||
return ast_nodes.Defini(tokens[1], tokens[2], tokens[6])
|
||||
|
||||
@self.pg.production('statement : KEYWORD_REDI expressions')
|
||||
def redi(tokens):
|
||||
return ast_nodes.Redi(tokens[1])
|
||||
|
||||
@self.pg.production('expression : DATA_STRING')
|
||||
def expression_string(tokens):
|
||||
return ast_nodes.String(tokens[0].value[1:-1])
|
||||
|
||||
@self.pg.production('expression : DATA_NUMERAL')
|
||||
def expression_numeral(tokens):
|
||||
return ast_nodes.Numeral(tokens[0].value)
|
||||
|
||||
@self.pg.production('expression : KEYWORD_FALSITAS')
|
||||
@self.pg.production('expression : KEYWORD_VERITAS')
|
||||
def expression_bool(tokens):
|
||||
return ast_nodes.Bool(tokens[0].name == "KEYWORD_VERITAS")
|
||||
|
||||
@self.pg.production('expression : KEYWORD_NVLLVS')
|
||||
def expression_nullus(_):
|
||||
return ast_nodes.Nullus()
|
||||
|
||||
@self.pg.production('expression : expression SYMBOL_MINUS expression')
|
||||
@self.pg.production('expression : expression SYMBOL_PLUS expression')
|
||||
@self.pg.production('expression : expression SYMBOL_TIMES expression')
|
||||
@self.pg.production('expression : expression SYMBOL_DIVIDE expression')
|
||||
@self.pg.production('expression : expression KEYWORD_EST expression')
|
||||
@self.pg.production('expression : expression KEYWORD_MINVS expression')
|
||||
@self.pg.production('expression : expression KEYWORD_PLVS expression')
|
||||
def binop(tokens):
|
||||
return ast_nodes.BinOp(tokens[0], tokens[2], tokens[1].name)
|
||||
|
||||
@self.pg.production('expression : BUILTIN expressions')
|
||||
def expression_builtin(tokens):
|
||||
return ast_nodes.BuiltIn(tokens[0].value, tokens[1])
|
||||
|
||||
@self.pg.production("id : ID")
|
||||
def id_expression(tokens):
|
||||
return ast_nodes.ID(tokens[0].value)
|
||||
|
||||
@self.pg.production('expression : KEYWORD_INVOCA id expressions')
|
||||
def invoca(tokens):
|
||||
return ast_nodes.Invoca(tokens[1], tokens[2])
|
||||
|
||||
@self.pg.production('statement : si_statement')
|
||||
def si_statement(tokens):
|
||||
return tokens[0]
|
||||
|
||||
@self.pg.production('statement : per_statement')
|
||||
@self.pg.production('statement : dum_statement')
|
||||
@self.pg.production('statement : donicum_statement')
|
||||
def loops(tokens):
|
||||
return tokens[0]
|
||||
|
||||
@self.pg.production('statement : KEYWORD_ERVMPE')
|
||||
def erumpe(_):
|
||||
return ast_nodes.Erumpe()
|
||||
|
||||
@self.pg.production('si_statement : KEYWORD_SI expression KEYWORD_TVNC SYMBOL_LCURL opt_newline statements opt_newline SYMBOL_RCURL opt_newline aluid_statement')
|
||||
def si(tokens):
|
||||
return ast_nodes.SiStatement(tokens[1], tokens[5], tokens[9])
|
||||
|
||||
@self.pg.production('dum_statement : KEYWORD_DVM expression KEYWORD_FACE SYMBOL_LCURL opt_newline statements opt_newline SYMBOL_RCURL')
|
||||
def dum(tokens):
|
||||
return ast_nodes.DumStatement(tokens[1], tokens[5])
|
||||
|
||||
@self.pg.production('per_statement : KEYWORD_PER id KEYWORD_IN expression KEYWORD_FACE SYMBOL_LCURL opt_newline statements opt_newline SYMBOL_RCURL')
|
||||
def per(tokens):
|
||||
return ast_nodes.PerStatement(tokens[3], tokens[1], tokens[7])
|
||||
|
||||
@self.pg.production('donicum_statement : KEYWORD_DONICVM id KEYWORD_VT expression KEYWORD_VSQVE expression KEYWORD_FACE SYMBOL_LCURL opt_newline statements opt_newline SYMBOL_RCURL')
|
||||
def donicum(tokens):
|
||||
range_array = ast_nodes.DataRangeArray(tokens[3], tokens[5])
|
||||
return ast_nodes.PerStatement(range_array, tokens[1], tokens[9])
|
||||
|
||||
@self.pg.production('aluid_statement : ')
|
||||
def aluid_empty(_):
|
||||
return None
|
||||
|
||||
@self.pg.production('aluid_statement : KEYWORD_ALVID si_statement')
|
||||
def aluid_si(tokens):
|
||||
return [tokens[1]]
|
||||
|
||||
@self.pg.production('aluid_statement : KEYWORD_ALVID SYMBOL_LCURL opt_newline statements opt_newline SYMBOL_RCURL aluid_statement')
|
||||
def aluid(tokens):
|
||||
return tokens[3]
|
||||
|
||||
@self.pg.production('expression : SYMBOL_LPARENS expression SYMBOL_RPARENS')
|
||||
def parens(tokens):
|
||||
return tokens[1]
|
||||
|
||||
@self.pg.production('expression : SYMBOL_LBRACKET expressions SYMBOL_RBRACKET')
|
||||
def array(tokens):
|
||||
return ast_nodes.DataArray(tokens[1])
|
||||
|
||||
@self.pg.production('expression : SYMBOL_LBRACKET expression KEYWORD_VSQVE expression SYMBOL_RBRACKET')
|
||||
def range_array(tokens):
|
||||
return ast_nodes.DataRangeArray(tokens[1], tokens[3])
|
||||
|
||||
@self.pg.error
|
||||
def error_handle(token):
|
||||
raise ValueError(token)
|
||||
|
||||
parser = self.pg.build()
|
||||
return parser.parse(tokens_input)
|
||||
Reference in New Issue
Block a user