🐐 First order functions
This commit is contained in:
@@ -144,6 +144,8 @@ def make_string(val, magnvm=False, svbnvlla=False) -> str:
|
||||
for k, v in val.value().items()
|
||||
)
|
||||
return "{" + inner + "}"
|
||||
elif isinstance(val, ValFunc):
|
||||
return "FVNCTIO"
|
||||
else:
|
||||
raise CentvrionError(f"Cannot display {val!r}")
|
||||
|
||||
@@ -577,6 +579,31 @@ class Defini(Node):
|
||||
return vtable, ValNul()
|
||||
|
||||
|
||||
class Fvnctio(Node):
|
||||
def __init__(self, parameters: list[ID], statements: list[Node]) -> None:
|
||||
self.parameters = parameters
|
||||
self.statements = statements
|
||||
|
||||
def __eq__(self, other):
|
||||
return (type(self) == type(other)
|
||||
and self.parameters == other.parameters
|
||||
and self.statements == other.statements)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
parameter_string = f"parameters([{rep_join(self.parameters)}])"
|
||||
statements_string = f"statements([{rep_join(self.statements)}])"
|
||||
fvn_string = rep_join([parameter_string, statements_string])
|
||||
return f"Fvnctio({fvn_string})"
|
||||
|
||||
def print(self):
|
||||
params = ", ".join(p.print() for p in self.parameters)
|
||||
body = "\n".join(s.print() for s in self.statements)
|
||||
return f"FVNCTIO ({params}) VT {{\n{body}\n}}"
|
||||
|
||||
def _eval(self, vtable):
|
||||
return vtable, ValFunc(self.parameters, self.statements)
|
||||
|
||||
|
||||
class Redi(Node):
|
||||
def __init__(self, values: list[Node]) -> None:
|
||||
self.values = values
|
||||
@@ -954,32 +981,36 @@ class PerStatement(Node):
|
||||
|
||||
|
||||
class Invoca(Node):
|
||||
def __init__(self, name, parameters) -> None:
|
||||
self.name = name
|
||||
def __init__(self, callee, parameters) -> None:
|
||||
self.callee = callee
|
||||
self.parameters = parameters
|
||||
|
||||
def __eq__(self, other):
|
||||
return type(self) == type(other) and self.name == other.name and self.parameters == other.parameters
|
||||
return (type(self) == type(other)
|
||||
and self.callee == other.callee
|
||||
and self.parameters == other.parameters)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
parameters_string = f"parameters([{rep_join(self.parameters)}])"
|
||||
invoca_string = rep_join([self.name, parameters_string])
|
||||
invoca_string = rep_join([self.callee, parameters_string])
|
||||
return f"Invoca({invoca_string})"
|
||||
|
||||
def print(self):
|
||||
args = ", ".join(p.print() for p in self.parameters)
|
||||
return f"INVOCA {self.name.print()} ({args})"
|
||||
return f"INVOCA {self.callee.print()} ({args})"
|
||||
|
||||
def _eval(self, vtable):
|
||||
params = [p.eval(vtable)[1] for p in self.parameters]
|
||||
if self.name.name not in vtable:
|
||||
raise CentvrionError(f"Undefined function: {self.name.name}")
|
||||
func = vtable[self.name.name]
|
||||
vtable, func = self.callee.eval(vtable)
|
||||
if not isinstance(func, ValFunc):
|
||||
raise CentvrionError(f"{self.name.name} is not a function")
|
||||
callee_desc = (self.callee.name
|
||||
if isinstance(self.callee, ID) else "expression")
|
||||
raise CentvrionError(f"{callee_desc} is not a function")
|
||||
if len(params) != len(func.params):
|
||||
callee_desc = (self.callee.name
|
||||
if isinstance(self.callee, ID) else "FVNCTIO")
|
||||
raise CentvrionError(
|
||||
f"{self.name.name} expects {len(func.params)} argument(s), got {len(params)}"
|
||||
f"{callee_desc} expects {len(func.params)} argument(s), got {len(params)}"
|
||||
)
|
||||
func_vtable = vtable.copy()
|
||||
for i, param in enumerate(func.params):
|
||||
|
||||
Reference in New Issue
Block a user