1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
from .. import TypeEnum, Environment, Arg, Builtin, evaluate, InterpretPanic, NebSyntax, MultiFunction, Callable
from ..structs import *
FUNCTOOLS = Environment()
def interpretFilter(symbol, args, env, ns):
func = args[0]
if not isinstance(func, Callable):
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)
filter_func = Builtin("filter", interpretFilter, [Arg("func", TypeEnum.ANY), Arg("list", TypeEnum.LIST)], return_type=Type(":[]"))
filter_multi = MultiFunction("filter")
filter_multi.register(filter_func)
FUNCTOOLS.register("filter", filter_multi)
def interpretMap(symbol, args, env, ns):
func = args[0]
if not isinstance(func, Callable):
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)
map_func = Builtin("map", interpretMap, [Arg("func", TypeEnum.ANY), Arg("list", TypeEnum.LIST)], return_type=Type(":[]"))
map_multi = MultiFunction("map")
map_multi.register(map_func)
FUNCTOOLS.register("map", map_multi)
# TODO I think this is wrong
def interpretApply(symbol, args, env, ns):
func = args[0]
if not isinstance(func, Callable):
raise InterpretPanic(symbol, "requires a :func as its first argument", func)
return func.call(Expr([func] + args[1].args), env, ns)
apply_func = Builtin("apply", interpretApply, [Arg("func", TypeEnum.ANY), Arg("list", TypeEnum.LIST)])
apply_multi = MultiFunction("apply")
apply_multi.register(apply_func)
FUNCTOOLS.register("apply", apply_multi)
def interpretReduce(symbol, args, env, ns):
func = args[0]
if not isinstance(func, Callable):
raise InterpretPanic(symbol, "requires a :func as its first argument", func)
ret = args[2] # this is the accumulator
for arg in args[1].args:
ret = func.call(Expr([func, ret, arg]), env, ns)
return ret
reduce_func = Builtin("reduce", interpretReduce, [Arg("func", TypeEnum.ANY), Arg("list", TypeEnum.LIST), Arg("accum", TypeEnum.ANY)])
reduce_multi = MultiFunction("reduce")
reduce_multi.register(reduce_func)
FUNCTOOLS.register("reduce", reduce_multi)
|