aboutsummaryrefslogtreecommitdiff
path: root/neb/std/functools.py
diff options
context:
space:
mode:
authormryouse2022-06-21 01:49:29 +0000
committermryouse2022-06-21 01:49:29 +0000
commit776fe3193b515c028b5ac69326baed51d760d32f (patch)
treedb111c3fe7a20143b2f058259f86dbbecae4cbd6 /neb/std/functools.py
parentb1550660adaca68bb38541aed371e36b7000e124 (diff)
refactor: break stdlib into several files
Diffstat (limited to 'neb/std/functools.py')
-rw-r--r--neb/std/functools.py46
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)]))
+