diff options
| author | mryouse | 2022-06-21 01:49:29 +0000 |
|---|---|---|
| committer | mryouse | 2022-06-21 01:49:29 +0000 |
| commit | 776fe3193b515c028b5ac69326baed51d760d32f (patch) | |
| tree | db111c3fe7a20143b2f058259f86dbbecae4cbd6 /neb/std/functools.py | |
| parent | b1550660adaca68bb38541aed371e36b7000e124 (diff) | |
refactor: break stdlib into several files
Diffstat (limited to 'neb/std/functools.py')
| -rw-r--r-- | neb/std/functools.py | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/neb/std/functools.py b/neb/std/functools.py new file mode 100644 index 0000000..59f4a2a --- /dev/null +++ b/neb/std/functools.py @@ -0,0 +1,46 @@ +from .. import TypeEnum, Environment, Arg, Builtin, Function, evaluate +from ..structs import * + +FUNCTOOLS = Environment() + +def interpretFilter(symbol, args, env, ns): + func = args[0] + if not isinstance(func, Function): + raise InterpretPanic(symbol, "requires a :func as its first argument", func) + lst = args[1] + out = [] + for arg in lst.args: + ev = func.call(Expr([func, arg]), env, ns) + if not isinstance(ev, Bool): + raise InterpretPanic(symbol, "function must return :bool", ev) + if ev.value: + out.append(arg) + return List(out) + +FUNCTOOLS.register("filter", Builtin(interpretFilter, [Arg("func", TypeEnum.ANY), Arg("list", TypeEnum.LIST)])) + +def interpretMap(symbol, args, env, ns): + func = args[0] + if not isinstance(func, Function): + raise InterpretPanic(symbol, "requires a :func as its first argument", func) + lst = args[1] + if not isinstance(lst, List): + raise InterpretPanic(symbol, "requires a :list as its second argument", lst) + out = [] + for arg in lst.args: + ev = func.call(Expr([func, arg]), env, ns) + out.append(ev) + return List(out) + +FUNCTOOLS.register("map", Builtin(interpretMap, [Arg("func", TypeEnum.ANY), Arg("list", TypeEnum.LIST)])) + +def interpretApply(symbol, args, env, ns): + # TODO: to support lambdas, we can't assume the func is defined + func = args[0] + if not isinstance(func, Symbol): + raise InterpretPanic(symbol, "requires a symbol as its first argument", func) + new_lst = List([func] + args[1].args) + return evaluate(new_lst, env, ns) + +FUNCTOOLS.register("apply", Builtin(interpretApply, [Arg("func", TypeEnum.ANY, lazy=True), Arg("list", TypeEnum.LIST)])) + |
