diff options
| -rw-r--r-- | neb/interpreter.py | 47 | ||||
| -rw-r--r-- | neb/structs.py | 10 |
2 files changed, 30 insertions, 27 deletions
diff --git a/neb/interpreter.py b/neb/interpreter.py index d190ca2..a492307 100644 --- a/neb/interpreter.py +++ b/neb/interpreter.py @@ -137,7 +137,7 @@ class UserFunction(Function): # if we got "many", wrap the rest in a list if self.many: - this_env.register(self.many.name, List(evaluated_args[len(self.params):], True)) + this_env.register(self.many.name, List(evaluated_args[len(self.params):])) return interpret(self.body, env=this_env, ns=ns) @@ -160,9 +160,6 @@ def evaluate(expr, env, ns=None): else: raise NebPanic(f"no such symbol: {expr}") - # if it's a literal list, return it - if expr.data: - return expr # if it's an empty list, return it elif len(expr.args) == 0: return expr @@ -446,7 +443,7 @@ def interpretReadLines(symbol, args, env, ns): raise InterpretPanic(symbol, "no such file", target_file) with open(target_file, "r") as fil: data = fil.readlines() - out = List([String(d) for d in data], True) # all lines are strings + out = List([String(d) for d in data]) # all lines are strings return out GLOBALS.register("read-lines", Builtin(interpretReadLines, [Arg("filename", TypeEnum.STRING)])) @@ -469,10 +466,10 @@ GLOBALS.register("string->int", Builtin(interpretStringToInt, [Arg("arg", TypeEn def interpretSplit(symbol, args, env, ns): target = args[0] if len(args) == 1: - return List([String(char) for char in target.value], True) + return List([String(char) for char in target.value]) splitter = args[1] ret = target.value.split(splitter.value) - return List([String(r) for r in ret], True) + return List([String(r) for r in ret]) GLOBALS.register("split", Builtin(interpretSplit, [Arg("target", TypeEnum.STRING)], Arg("splitter", TypeEnum.STRING, optional=True))) @@ -490,7 +487,7 @@ GLOBALS.register("first", Builtin(interpretFirst, [Arg("arg", TypeEnum.LIST, )]) def interpretRest(symbol, args, env, ns): # TODO do we know it's not evaluated? - return List(args[0].args[1:], True) # we don't evaluate the remainder of the list + return List(args[0].args[1:]) # we don't evaluate the remainder of the list GLOBALS.register("rest", Builtin(interpretRest, [Arg("arg", TypeEnum.LIST)])) @@ -498,14 +495,14 @@ 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 = evaluate(args[1], env, ns) + 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(List([func, arg]), env, ns) + ev = func.call(Expr([func, arg]), env, ns) out.append(ev) - return List(out, True) + return List(out) GLOBALS.register("map", Builtin(interpretMap, [Arg("func", TypeEnum.ANY), Arg("list", TypeEnum.LIST)])) @@ -518,21 +515,21 @@ def interpretZip(symbol, args, env, ns): for idx in range(len(z1.args)): f = z1.args[idx] s = z2.args[idx] - out.append(List([f, s], True)) - return List(out, True) + out.append(List([f, s])) + return List(out) zip_arg = Arg("list", TypeEnum.LIST) GLOBALS.register("zip", Builtin(interpretZip, [zip_arg, zip_arg])) def interpretList(symbol, args, env, ns): - return List(args, True) + return List(args) GLOBALS.register("list", Builtin(interpretList, [], Arg("item", TypeEnum.ANY))) def interpretListReverse(symbol, args, env, ns): new_args = args[0].args[:] # make a copy of the args new_args.reverse() - return List(new_args, True) + return List(new_args) GLOBALS.register("list-reverse", Builtin(interpretListReverse, [Arg("list", TypeEnum.LIST)])) @@ -548,13 +545,13 @@ GLOBALS.register("apply", Builtin(interpretApply, [Arg("func", TypeEnum.ANY, laz def interpretGlob(symbol, args, env, ns): items = glob(args[0].value) - return List([String(item) for item in items], True) + return List([String(item) for item in items]) GLOBALS.register("glob", Builtin(interpretGlob, [Arg("regex", TypeEnum.STRING)])) def interpretShell(symbol, args, env, ns): ret = subprocess.run(shlex.split(args[0].value), capture_output=True) - return List([String(r) for r in ret.stdout.decode("utf-8").split("\n")], True) + return List([String(r) for r in ret.stdout.decode("utf-8").split("\n")]) GLOBALS.register("$", Builtin(interpretShell, [Arg("command", TypeEnum.STRING)])) @@ -566,7 +563,7 @@ GLOBALS.register("empty?", Builtin(interpretEmpty, [Arg("list", TypeEnum.LIST)]) def interpretShuf(symbol, args, env, ns): items = args[0].args[:] random.shuffle(items) - return List(items, True) + return List(items) GLOBALS.register("shuf", Builtin(interpretShuf, [Arg("list", TypeEnum.LIST)])) @@ -605,7 +602,7 @@ def interpretArgv(symbol, args, env, ns): out = [] for arg in sys.argv[1:]: out.append(String(arg)) - return List(out, True) + return List(out) GLOBALS.register("argv", Builtin(interpretArgv, [])) @@ -643,7 +640,7 @@ def interpretWithWrite(symbol, args, env, ns): target_path = Path(target_file.value).resolve() ret = Literal([]) with open(str(target_path), "w") as fil: - new_env.register("_file_", List([fil], True)) # TODO wrong! + new_env.register("_file_", List([fil])) # TODO wrong! for arg in args[1:]: ret = evaluate(arg, new_env, ns) return ret @@ -726,7 +723,7 @@ def interpretAppend(symbol, args, env, ns): lst = args[0] val = args[1] items = lst.args[:] - return List(items + [val], True) + return List(items + [val]) GLOBALS.register("append", Builtin(interpretAppend, [Arg("list", TypeEnum.LIST), Arg("item", TypeEnum.ANY)])) @@ -738,7 +735,7 @@ def interpretRemove(symbol, args, env, ns): for arg in lst.args: if arg.args[0].value != key.value: out.append(arg) - return List(out, True) + return List(out) GLOBALS.register("remove", Builtin(interpretRemove, [Arg("list", TypeEnum.LIST), Arg("key", TypeEnum.ANY)])) @@ -823,12 +820,12 @@ def interpretFilter(symbol, args, env, ns): lst = args[1] out = [] for arg in lst.args: - ev = func.call(List([func, arg]), env, ns) + 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, True) + return List(out) GLOBALS.register("filter", Builtin(interpretFilter, [Arg("func", TypeEnum.ANY), Arg("list", TypeEnum.LIST)])) @@ -865,7 +862,7 @@ GLOBALS.register("bool?", Builtin(interpretIsBool, [Arg("arg", TypeEnum.ANY)])) def interpretUserSymbols(symbol, args, env, ns): keys = [Symbol(k, -1) for k,v in env.environment.items() if isinstance(v, UserFunction) or isinstance(v, Literal)] - return List(keys, True) + return List(keys) GLOBALS.register("user-symbols", Builtin(interpretUserSymbols, [])) diff --git a/neb/structs.py b/neb/structs.py index 947f3f6..c8e7e8b 100644 --- a/neb/structs.py +++ b/neb/structs.py @@ -99,10 +99,16 @@ class Symbol: def __str__(self): return f"{self.name}" +class Expr: + def __init__(self, args): + self.args = args + self.type_ = TypeEnum.ANY # TODO no it's not + def __str__(self): + return "(" + " ".join(f"{arg}" for arg in self.args) + ")" + class List: - def __init__(self, args, data=False): + def __init__(self, args): self.args = args - self.data = data self.type_ = TypeEnum.LIST def __str__(self): return "(" + " ".join(f"{arg}" for arg in self.args) + ")" |
