diff options
Diffstat (limited to 'neb/__init__.py')
| -rw-r--r-- | neb/__init__.py | 44 |
1 files changed, 34 insertions, 10 deletions
diff --git a/neb/__init__.py b/neb/__init__.py index 42e1d00..e3167b9 100644 --- a/neb/__init__.py +++ b/neb/__init__.py @@ -12,7 +12,7 @@ def interpret(exprs, env, ns=None): return ret def evaluate(expr, env, ns=None): - if isinstance(expr, Literal) or isinstance(expr, Function) or isinstance(expr, TypeWrap) or isinstance(expr, List) or isinstance(expr, Handle): + if isinstance(expr, Literal) or isinstance(expr, Callable) or isinstance(expr, TypeWrap) or isinstance(expr, List) or isinstance(expr, Handle): return expr elif isinstance(expr, Symbol) or isinstance(expr, Type): if env.contains(expr.name): @@ -51,7 +51,8 @@ def evaluate(expr, env, ns=None): else: raise InterpretPanic(expr.args[0], "unable to evaluate") -class Function: + +class Callable: def __init__(self, name, params, body, args=None, many=None): self.name = name @@ -84,7 +85,35 @@ class Function: raise InterpretPanic(symbol, f"expected [{fmt}] arguments, received {len(params)}") return True - def evaluate_args(self, symbol, params, env, ns): + def call(self, expr, env): + pass + +class Special(Callable): + + def __init__(self, name, params, body, args=None, many=None): + super().__init__(name, params, body, args, many) + +class NebSyntax(Special): + + def __init__(self, name, callable_, args=None, many=None, return_type=None): + super().__init__(name, None, callable_, args, many) + if return_type is not None: + self.return_type = return_type + + def __str__(self): + return f"syntax function {self.name}" + + def call(self, expr, env, ns): + self.arity_check(expr.args[0], expr.args[1:]) + return self.body(expr.args[0], expr.args[1:], env, ns) + + +class Function(Callable): + + def __init__(self, name, params, body, args=None, many=None): + super().__init__(name, params, body, args, many) + + def precall(self, symbol, params, env, ns): ret = [] for idx, param in enumerate(params): @@ -92,9 +121,6 @@ class Function: arg = self.args[idx] else: arg = self.many - if arg.lazy: - ret.append(param) - continue ev = evaluate(param, env, ns) expected_type = evaluate(arg.type_, env, ns) valid = expected_type.validate_type(ev, env, ns) @@ -105,8 +131,6 @@ class Function: ret.append(ev) return ret - def call(self, expr, env): - pass class Builtin(Function): @@ -120,7 +144,7 @@ class Builtin(Function): def call(self, expr, env, ns): self.arity_check(expr.args[0], expr.args[1:]) - evaluated_args = self.evaluate_args(expr.args[0], expr.args[1:], env, ns) + evaluated_args = self.precall(expr.args[0], expr.args[1:], env, ns) return self.body(expr.args[0], evaluated_args, env, ns) @@ -172,7 +196,7 @@ class UserFunction(Function): def call(self, expr, env, ns): self.arity_check(expr.args[0], expr.args[1:]) - evaluated_args = self.evaluate_args(expr.args[0], expr.args[1:], env, ns) + evaluated_args = self.precall(expr.args[0], expr.args[1:], env, ns) this_env = Environment(env) for idx, param in enumerate(self.params): this_env.register(param.name, evaluated_args[idx]) |
