diff options
| author | mryouse | 2022-06-11 18:01:14 +0000 |
|---|---|---|
| committer | mryouse | 2022-06-11 18:01:14 +0000 |
| commit | 2dea2a15ff9c734c788beea4b91ebde58672fee4 (patch) | |
| tree | f67de16263ba2c867f817d5fd7c3e171416390c7 /interpreter.py | |
| parent | 05f68ac90f83df0c7d1c994cb11cd6e69ab7611f (diff) | |
refactor: remove redundant type checking
Diffstat (limited to 'interpreter.py')
| -rw-r--r-- | interpreter.py | 308 |
1 files changed, 75 insertions, 233 deletions
diff --git a/interpreter.py b/interpreter.py index 84fae67..1e6d78d 100644 --- a/interpreter.py +++ b/interpreter.py @@ -193,15 +193,9 @@ def interpretAnd(symbol, args, env): GLOBALS.register("and", Builtin(interpretAnd, [or_arg, or_arg], or_arg)) def interpretEq(symbol, args, env): - # equal # NOTE this currently only works for literals - first = evaluate(args[0], env) - second = evaluate(args[1], env) - if not (isinstance(first, Literal) and isinstance(second, Literal)): - raise InterpretPanic(symbol, "can only compare :literals") # compare types because 0 != #false in neb - # TODO number equality? - if type(first) == type(second) and first.value == second.value: + if type(args[0]) == type(args[1]) and args[0].value == args[1].value: return Bool(True) else: return Bool(False) @@ -210,57 +204,30 @@ eq_arg = Arg("value", T.Literal, False, False) GLOBALS.register("eq?", Builtin(interpretEq, [eq_arg, eq_arg])) def interpretGreaterThan(symbol, args, env): - left = evaluate(args[0], env) - if not (isinstance(left, Int) or isinstance(left, Float)): - raise InterpretPanic(symbol, "first argument must be a :number", left) - right = evaluate(args[1], env) - if not (isinstance(right, Int) or isinstance(right, Float)): - raise InterpretPanic(symbol, "second argument must be a :number", right) - return Bool(left.value > right.value) + return Bool(args[0].value > args[1].value) compare_arg = Arg("num", T.Number, False, False) GLOBALS.register(">", Builtin(interpretGreaterThan, [compare_arg, compare_arg])) def interpretGreaterThanEqual(symbol, args, env): - left = evaluate(args[0], env) - if not (isinstance(left, Int) or isinstance(left, Float)): - raise InterpretPanic(symbol, "first argument must be a :number", left) - right = evaluate(args[1], env) - if not (isinstance(right, Int) or isinstance(right, Float)): - raise InterpretPanic(symbol, "second argument must be a :number", right) - return Bool(left.value >= right.value) + return Bool(args[0].value >= args[1].value) GLOBALS.register(">=", Builtin(interpretGreaterThanEqual, [compare_arg, compare_arg])) def interpretLessThan(symbol, args, env): - left = evaluate(args[0], env) - if not (isinstance(left, Int) or isinstance(left, Float)): - raise InterpretPanic(symbol, "first argument must be a :number", left) - right = evaluate(args[1], env) - if not (isinstance(right, Int) or isinstance(right, Float)): - raise InterpretPanic(symbol, "second argument must be a :number", right) - return Bool(left.value < right.value) + return Bool(args[0].value < args[1].value) GLOBALS.register("<", Builtin(interpretLessThan, [compare_arg, compare_arg])) def interpretLessThanEqual(symbol, args, env): - left = evaluate(args[0], env) - if not (isinstance(left, Int) or isinstance(left, Float)): - raise InterpretPanic(symbol, "first argument must be a :number", left) - right = evaluate(args[1], env) - if not (isinstance(right, Int) or isinstance(right, Float)): - raise InterpretPanic(symbol, "second argument must be a :number", right) - return Bool(left.value <= right.value) + return Bool(args[0].value <= args[1].value) GLOBALS.register("<=", Builtin(interpretLessThanEqual, [compare_arg, compare_arg])) def interpretAddition(symbol, args, env): res = 0 for arg in args: - ev = evaluate(arg, env) - if not (isinstance(ev, Int) or isinstance(ev, Float)): - raise InterpretPanic(symbol, "argument must be a :number", ev) - res += ev.value + res += arg.value if isinstance(res, float): return Float(res) else: @@ -270,18 +237,12 @@ term_arg = Arg("term", T.Number, False, False) GLOBALS.register("+", Builtin(interpretAddition, [term_arg], term_arg)) def interpretSubtraction(symbol, args, env): - first = evaluate(args[0], env) - if not (isinstance(first, Int) or isinstance(first, Float)): - raise InterpretPanic(symbol, "argument must be a :number", first) if len(args) == 1: - res = -first.value + res = -args[0].value else: - res = first.value + res = args[0].value for arg in args[1:]: - ev = evaluate(arg, env) - if not (isinstance(ev, Int) or isinstance(ev, Float)): - raise InterpretPanic(symbol, "argument must be a :number", ev) - res -= ev.value + res -= arg.value if isinstance(res, float): return Float(res) else: @@ -290,15 +251,9 @@ def interpretSubtraction(symbol, args, env): GLOBALS.register("-", Builtin(interpretSubtraction, [term_arg], term_arg)) def interpretMultiplication(symbol, args, env): - first = evaluate(args[0], env) - if not (isinstance(first, Int) or isinstance(first, Float)): - raise InterpretPanic(symbol, "argument must be a :number", first) - res = first.value + res = args[0].value for arg in args[1:]: - tmp = evaluate(arg, env) - if not (isinstance(tmp, Int) or isinstance(tmp, Float)): - raise InterpretPanic(symbol, "argument must be a :number", tmp) - res = res * tmp.value + res = res * arg.value if isinstance(res, float): return Float(res) else: @@ -308,13 +263,7 @@ factor_arg = Arg("factor", T.Number, False, False) GLOBALS.register("*", Builtin(interpretMultiplication, [factor_arg, factor_arg], factor_arg)) def interpretDivision(symbol, args, env): - num = evaluate(args[0], env) - if not (isinstance(num, Int) or isinstance(num, Float)): - raise InterpretPanic(symbol, "numerator must be a :number", num) - denom = evaluate(args[1], env) - if not (isinstance(denom, Int) or isinstance(denom, Float)): - raise InterpretPanic(symbol, "denominator must be a :number", denom) - ret = num.value / denom.value + ret = args[0].value / args[1].value if int(ret) == ret: return Int(int(ret)) else: @@ -323,24 +272,18 @@ def interpretDivision(symbol, args, env): GLOBALS.register("/", Builtin(interpretDivision, [factor_arg, factor_arg])) def interpretNot(symbol, args, env): - res = evaluate(args[0], env) - if not isinstance(res, Bool): - raise InterpretPanic(symbol, "requires a :bool", res) - return Bool(not res.value) + return Bool(not args[0].value) not_arg = Arg("not", T.Bool, False, False) GLOBALS.register("not", Builtin(interpretNot, [not_arg])) def interpretIf(symbol, args, env): # if cond t-branch [f-branch] - cond = evaluate(args[0], env) - if not isinstance(cond, Bool): - raise InterpretPanic(symbol, "condition must be :bool", cond) - if cond.value: + if args[0].value: return evaluate(args[1], env) elif len(args) == 3: return evaluate(args[2], env) - return List([]) # this shouldn't be reached + return List([]) cond = Arg("cond", T.Bool, False, False) t_branch = Arg("t-branch", T.Any, False, True) @@ -348,11 +291,7 @@ f_branch = Arg("f-branch", T.Any, True, True) GLOBALS.register("if", Builtin(interpretIf, [cond, t_branch, f_branch])) def interpretPrint(symbol, args, env): - ev = evaluate(args[0], env) - if not isinstance(ev, String): - raise InterpretPanic(symbol, "requires a :string") - print(ev.value) - + print(args[0].value) return List([]) # print returns nothing GLOBALS.register("print", Builtin(interpretPrint, [Arg("arg", T.String, False, False)])) @@ -364,8 +303,7 @@ def interpretDef(symbol, args, env): if not isinstance(name, str): raise InterpretPanic(symbol, "requires a :string name") - ev = evaluate(args[1], env) - env.register(name, ev) + env.register(name, args[1]) # TODO since this isn't lazily evaluated, side effects are allowed (bad!) return List([]) def_name_arg = Arg("name", T.Any, False, True) @@ -379,8 +317,7 @@ def interpretRedef(symbol, args, env): if not env.contains(name): raise InterpretPanic(symbol, "not previously defined", args[0]) - ev = evaluate(args[1], env) - env.reregister(name, ev) + env.reregister(name, args[1]) return List([]) GLOBALS.register("redef", Builtin(interpretRedef, [def_name_arg, def_val_arg])) @@ -397,13 +334,13 @@ lambda_body_arg = Arg("body", T.Any, False, True) GLOBALS.register("lambda", Builtin(interpretLambda, [lambda_args_arg, lambda_body_arg], lambda_body_arg)) def interpretToString(symbol, args, env): - ev = evaluate(args[0], env) - if isinstance(ev, String): - return ev - elif isinstance(ev, Literal): - return String(str(ev)) + item = args[0] + if isinstance(item, String): + return item + elif isinstance(item, Literal): + return String(str(item)) else: - return String(f"{ev}") + return String(f"{item}") GLOBALS.register("->string", Builtin(interpretToString, [Arg("arg", T.Any, False, False)])) @@ -411,10 +348,7 @@ def interpretConcat(symbol, args, env): # concat str1 str2...strN out = "" for arg in args: - tmp = evaluate(arg, env) - if not isinstance(tmp, String): - raise InterpretPanic(symbol, "requires :string", tmp) - out += tmp.value + out += arg.value return String(out) string_arg = Arg("arg", T.String, False, False) @@ -422,12 +356,9 @@ GLOBALS.register("concat", Builtin(interpretConcat, [string_arg, string_arg], st def interpretForCount(symbol, args, env): # for-count int exprs - num = evaluate(args[0], env) - if not isinstance(num, Int): - raise InterpretPanic(symbol, "count must be an integer", num) new_env = Environment(env) ret = None - for idx in range(0, num.value): + for idx in range(0, args[0].value): new_env.register("idx", Int(idx + 1)) for arg in args[1:]: ret = evaluate(arg, new_env) @@ -441,12 +372,9 @@ GLOBALS.register("for-count", Builtin(interpretForCount, [for_count_arg, for_bod def interpretForEach(symbol, args, env): # for-each list exprs - lst = evaluate(args[0], env) - if not isinstance(lst, List): - raise InterpretPanic(symbok, "requires a :list", lst) new_env = Environment(env) ret = None - for item in lst.args: + for item in args[0].args: new_env.register("_item_", evaluate(item, env)) for arg in args[1:]: ret = evaluate(arg, new_env) @@ -509,7 +437,7 @@ GLOBALS.register("func", Builtin(interpretFunc, [def_name_arg, lambda_args_arg, # THINGS NEEDED FOR AOC # - read the contents of a file def interpretReadLines(symbol, args, env): - target_file_name = evaluate(args[0], env).value + target_file_name = args[0].value target_file = Path(target_file_name).resolve() if not target_file.exists(): raise InterpretPanic(symbol, "no such file", target_file) @@ -522,36 +450,26 @@ GLOBALS.register("read-lines", Builtin(interpretReadLines, [Arg("filename", T.St # - strip whitespace from string def interpretStrip(symbol, args, env): - out = evaluate(args[0], env) - if not isinstance(out, String): - raise InterpretPanic(symbol, "requires a :string", out) - return String(out.value.strip()) + return String(args[0].value.strip()) GLOBALS.register("strip", Builtin(interpretStrip, [Arg("filename", T.String, False, False)])) # - string->int and string->float def interpretStringToInt(symbol, args, env): - ev = evaluate(args[0], env) - if not isinstance(ev, String): - raise InterpretPanic(symbol, "requires a :string", ev) try: - val = int(ev.value) + val = int(args[0].value) return Int(val) except: - raise InterpretPanic(symbol, "can't convert to an :int", ev) + raise InterpretPanic(symbol, "can't convert to an :int", args[0]) GLOBALS.register("string->int", Builtin(interpretStringToInt, [Arg("arg", T.String, False, False)])) # - split a string by a given field def interpretSplit(symbol, args, env): - target = evaluate(args[0], env) - if not isinstance(target, String): - raise InterpretPanic(symbol, "requires a :string as its first argument", target) + target = args[0] if len(args) == 1: return List([String(char) for char in target.value], True) - splitter = evaluate(args[1], env) - if not isinstance(splitter, String): - raise InterpretPanic(symbol, "requires a :string as its second argument", splitter) + splitter = args[1] ret = target.value.split(splitter.value) return List([String(r) for r in ret], True) @@ -559,30 +477,21 @@ GLOBALS.register("split", Builtin(interpretSplit, [Arg("target", T.String, False # - get the length of a list def interpretListLength(symbol, args, env): - ev = evaluate(args[0], env) - if not isinstance(ev, List): - raise InterpretPanic(symbol, "requires a :list", ev) - return Int(len(ev.args)) + return Int(len(args[0].args)) GLOBALS.register("list-length", Builtin(interpretListLength, [Arg("arg", T.List, False, False)])) # - first/rest of list def interpretFirst(symbol, args, env): - ev = evaluate(args[0], env) - if not isinstance(ev, List): - raise InterpretPanic(symbol, "requires a :list", ev) - if len(ev.args) == 0: + if len(args[0].args) == 0: raise InterpretPanic(symbol, "list is empty") - return evaluate(ev.args[0], env) + return evaluate(args[0].args[0], env) GLOBALS.register("first", Builtin(interpretFirst, [Arg("arg", T.List, False, False)])) def interpretRest(symbol, args, env): - ev = evaluate(args[0], env) - if not isinstance(ev, List): - raise InterpretPanic(symbol, "requires a :list", ev) # TODO do we know it's not evaluated? - return List(ev.args[1:], True) # we don't evaluate the remainder of the list + return List(args[0].args[1:], True) # we don't evaluate the remainder of the list GLOBALS.register("rest", Builtin(interpretRest, [Arg("arg", T.List, False, False)])) @@ -603,20 +512,17 @@ def interpretMap(symbol, args, env): return List(out, True) GLOBALS.register("map", Builtin(interpretMap, [Arg("func", T.Any, False, True), Arg("list", T.List, False, False)])) +#GLOBALS.register("map", Builtin(interpretMap, [Arg("func", T.Any, False, False), Arg("list", T.List, False, False)])) def interpretZip(symbol, args, env): - z1 = evaluate(args[0], env) - if not isinstance(z1, List): - raise InterpretPanic(symbol, "requires two :lists", z1) - z2 = evaluate(args[1], env) - if not isinstance(z2, List): - raise InterpretPanic(symbol, "requires two :lists", z2) + z1 = args[0] + z2 = args[1] if len(z1.args) != len(z2.args): raise InterpretPanic(symbol, "requires two :lists of the same size") out = [] for idx in range(len(z1.args)): - f = evaluate(z1.args[idx], env) - s = evaluate(z2.args[idx], env) + f = z1.args[idx] + s = z2.args[idx] out.append(List([f, s], True)) return List(out, True) @@ -624,75 +530,54 @@ zip_arg = Arg("list", T.List, False, False) GLOBALS.register("zip", Builtin(interpretZip, [zip_arg, zip_arg])) def interpretList(symbol, args, env): - out = [] - for arg in args: - out.append(evaluate(arg, env)) - return List(out, True) + return List(args, True) GLOBALS.register("list", Builtin(interpretList, [], Arg("item", T.Any, False, False))) def interpretListReverse(symbol, args, env): - lst = evaluate(args[0], env) - if not isinstance(lst, List): - raise InterpretPanic(symbol, "requires a :list", lst) - new_args = lst.args[:] # make a copy of the args + new_args = args[0].args[:] # make a copy of the args new_args.reverse() return List(new_args, True) GLOBALS.register("list-reverse", Builtin(interpretListReverse, [Arg("list", T.List, False, False)])) def interpretApply(symbol, args, env): + # 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) - lst = evaluate(args[1], env) - if not isinstance(lst, List): - raise InterpretPanic(symbol, "requires a :list as its second argument". lst) - new_lst = List([func] + lst.args) + new_lst = List([func] + args[1].args) return evaluate(new_lst, env) GLOBALS.register("apply", Builtin(interpretApply, [Arg("func", T.Any, False, True), Arg("list", T.List, False, False)])) def interpretGlob(symbol, args, env): - ev = evaluate(args[0], env) - if not isinstance(ev, String): - raise InterpretPanic(symbol, "requires a :string", ev) - items = glob(ev.value) + items = glob(args[0].value) return List([String(item) for item in items], True) GLOBALS.register("glob", Builtin(interpretGlob, [Arg("regex", T.String, False, False)])) def interpretShell(symbol, args, env): - ev = evaluate(args[0], env) - if not isinstance(ev, String): - raise InterpretPanic(symbol, "requires a :string", ev) # TODO either fail or throw exception (?) on error - ret = subprocess.run(shlex.split(ev.value), capture_output=True) + 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) GLOBALS.register("$", Builtin(interpretShell, [Arg("command", T.String, False, False)])) def interpretEmpty(symbol, args, env): - ev = evaluate(args[0], env) - if not isinstance(ev, List): - raise InterpretPanic(symbol, "requires a :list", ev) - return Bool(len(ev.args) == 0) + return Bool(len(args[0].args) == 0) GLOBALS.register("empty?", Builtin(interpretEmpty, [Arg("list", T.List, False, False)])) def interpretShuf(symbol, args, env): - ev = evaluate(args[0], env) - if not isinstance(ev, List): - raise InterpretPanic(symbol, "expects a :list", ev) - items = ev.args[:] + items = args[0].args[:] random.shuffle(items) return List(items, True) GLOBALS.register("shuf", Builtin(interpretShuf, [Arg("list", T.List, False, False)])) def interpretIsList(symbol, args, env): - ev = evaluate(args[0], env) - return Bool(isinstance(ev, List)) + return Bool(isinstance(args[0], List)) GLOBALS.register("list?", Builtin(interpretIsList, [Arg("arg", T.Any, False, False)])) @@ -706,9 +591,7 @@ block_arg = Arg("expr", T.Any, False, True) GLOBALS.register("block", Builtin(interpretBlock, [block_arg], block_arg)) def interpretExit(symbol, args, env): - status = 0 if len(args) == 0 else evaluate(args[0], env).value - if not isinstance(status, int): - raise InterpretPanic(symbol, "expects an :int", status) + status = 0 if len(args) == 0 else args[0].value sys.exit(status) return List([]) @@ -716,10 +599,7 @@ exit_arg = Arg("status", T.Int, True, False) GLOBALS.register("exit", Builtin(interpretExit, [exit_arg])) def interpretUnlink(symbol, args, env): - ev = evaluate(args[0], env) - if not isinstance(ev, String): - raise InterpretPanic(symbol, "expects a :string", ev) - target_path = Path(ev.value).resolve() + target_path = Path(args[0].value).resolve() if not target_path.exists(): raise InterpretPanic(symbol, "target file does not exist", target_path) target_path.unlink() @@ -736,15 +616,10 @@ def interpretArgv(symbol, args, env): GLOBALS.register("argv", Builtin(interpretArgv, [])) def interpretIn(symbol, args, env): - target = evaluate(args[0], env) - if not isinstance(target, Literal): - raise InterpretPanic(symbol, "expects a :literal as its first argument", target) - lst = evaluate(args[1], env) - if not isinstance(lst, List): - raise InterpretPanic(symbol, "expects a :list as its second argument", lst) + target = args[0] + lst = args[1] for arg in lst.args: - ev = evaluate(arg, env) - if type(ev) == type(target) and ev.value == target.value: + if type(arg) == type(target) and arg.value == target.value: return Bool(True) return Bool(False) @@ -753,22 +628,15 @@ in_list_arg = Arg("list", T.List, False, False) GLOBALS.register("in?", Builtin(interpretIn, [in_target_arg, in_list_arg])) def interpretLast(symbol, args, env): - ev = evaluate(args[0], env) - if not isinstance(ev, List): - raise InterpretPanic("'last' expects a List") - if len(ev.args) == 0: + if len(args[0].args) == 0: raise InterpretPanic("List is empty") - return evaluate(ev.args[-1], env) + return evaluate(args[0].args[-1], env) GLOBALS.register("last", Builtin(interpretLast, [Arg("list", T.List, False, False)])) def interpretJoin(symbol, args, env): - lst = evaluate(args[0], env) - if not isinstance(lst, List): - raise InterpretPanic(symbol, "expects a :list as its first argument", lst) - target = evaluate(args[1], env) - if not isinstance(target, String): - raise InterpretPanic(symbol, "expects a :string as its second argument", target) + lst = args[0] + target = args[1] return String(target.value.join([a.value for a in lst.args])) join_list_arg = Arg("list", T.List, False, False) @@ -776,11 +644,7 @@ join_string_arg = Arg("joiner", T.String, False, False) GLOBALS.register("join", Builtin(interpretJoin, [join_list_arg, join_string_arg])) def interpretWithWrite(symbol, args, env): - if len(args) == 0: - raise InterpretPanic(symbol, "expects at least one argument") - target_file = evaluate(args[0], env) - if not isinstance(target_file, String): - raise InterpretPanic(symbol, "expects a :string as its first argument", target_file) + target_file = args[0] new_env = Environment(env) target_path = Path(target_file.value).resolve() ret = Literal([]) @@ -790,14 +654,12 @@ def interpretWithWrite(symbol, args, env): ret = evaluate(arg, new_env) return ret -GLOBALS.register("with-write", Builtin(interpretWithWrite, [Arg("filename", T.String, False, False)])) +GLOBALS.register("with-write", Builtin(interpretWithWrite, [Arg("filename", T.String, False, False)], Arg("exprs", T.Any, False, True))) def interpretWrite(symbol, args, env): # write :string :filehandle - line = evaluate(args[0], env) - if not isinstance(line, String): - raise InterpretPanic(symbol, "expects a :string as its first argument", line) - handle = evaluate(args[1], env) + line = args[0] + handle = args[1] handle.args[0].write(line.value) # TODO wrong! how do we evaluate a handle? return Literal([]) @@ -809,43 +671,28 @@ def interpretNewline(symbol, args, env): GLOBALS.register("newline", Builtin(interpretNewline, [])) def interpretExists(symbol, args, env): - file_or_dir = evaluate(args[0], env) - if not isinstance(file_or_dir, String): - raise InterpretPanic(symbol, "expects a :string", file_or_dir) - return Bool(Path(file_or_dir.value).resolve().exists()) + return Bool(Path(args[0].value).resolve().exists()) GLOBALS.register("exists?", Builtin(interpretExists, [Arg("filename", T.String, False, False)])) def interpretFirstChar(symbol, args, env): - ev = evaluate(args[0], env) - if not isinstance(ev, String): - raise InterpretPanic(symbol, "expects a :string", ev) - if len(ev.value) == 0: + if len(args[0].value) == 0: raise InterpretPanic(symbol, ":string is empty", ev) - return String(ev.value[0]) + return String(args[0].value[0]) GLOBALS.register("first-char", Builtin(interpretFirstChar, [Arg("string", T.String, False, False)])) def interpretRestChar(symbol, args, env): - ev = evaluate(args[0], env) - if not isinstance(ev, String): - raise InterpretPanic(symbol, "expects a string", ev) - return String(ev.value[1:]) + return String(args[0].value[1:]) GLOBALS.register("rest-char", Builtin(interpretRestChar, [Arg("string", T.String, False, False)])) def interpretSlice(symbol, args, env): - lst = evaluate(args[0], env) - if not isinstance(lst, List): - raise InterpretPanic(symbol, "expects a :list as its first argument", lst) - idx = evaluate(args[1], env) - if not isinstance(idx, Int): - raise InterpretPanic(symbol, "expects an :int as its second argument", idx) + lst = args[0] + idx = args[1] if len(args) == 2: return List(lst.args[idx.value - 1:]) - length = evaluate(args[2], env) - if not isinstance(length, Int): - raise InterpretPanic(symbol, "expects an :int as its third argument", length) + length = args[2] diff = idx.value - 1 + length.value return List(lst.args[idx.value - 1:diff]) @@ -861,19 +708,14 @@ def interpretClear(symbol, args, env): GLOBALS.register("clear", Builtin(interpretClear, [])) def interpretInput(symbol, args, env): - ev = evaluate(args[0], env) - if not isinstance(ev, String): - raise InterpretPanic(symbol, "expects a :string", ev) - ret = input(ev.value) + ret = input(args[0].value) return String(ret) GLOBALS.register("input", Builtin(interpretInput, [Arg("prompt", T.String, False, False)])) def interpretAppend(symbol, args, env): - lst = evaluate(args[0], env) - if not isinstance(lst, List): - raise InterpretPanic(symbol, "expects a :list as its first argument", lst) - val = evaluate(args[1], env) + lst = args[0] + val = args[1] items = lst.args[:] return List(items + [val], True) @@ -914,7 +756,7 @@ def interpretAnsiEscape(symbol, args, env): GLOBALS.register("ansi-escape", Builtin(interpretAnsiEscape, [])) def interpretUse(symbol, args, env): - target_file_name = evaluate(args[0], env).value + target_file_name = args[0].value target_file = Path(target_file_name).resolve() if not target_file.exists(): raise InterpretPanic(symbol, "no such file", target_file) |
