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)