diff options
| author | mryouse | 2022-05-26 03:26:14 +0000 |
|---|---|---|
| committer | mryouse | 2022-05-26 03:26:14 +0000 |
| commit | aeb75a610d712c0d853b7d6b8337c6f6d395859d (patch) | |
| tree | dd3f86e983fa7f6c9c386d82e6d89ff48313f0d3 | |
| parent | 856989c4dc74803678464399a21024e7b5d24985 (diff) | |
implement argv, in?, last, join, with-write, write, newline, exists?
| -rw-r--r-- | interpreter.py | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/interpreter.py b/interpreter.py index afdde60..dbf8c82 100644 --- a/interpreter.py +++ b/interpreter.py @@ -628,3 +628,87 @@ def interpretUnlink(symbol, args, env): GLOBALS.register("unlink", Builtin(interpretUnlink, 1)) +def interpretArgv(symbol, args, env): + out = [] + for arg in sys.argv[1:]: + out.append(Literal(arg)) + return List(out, True) + +GLOBALS.register("argv", Builtin(interpretArgv, 0)) + +def interpretIn(symbol, args, env): + target = evaluate(args[0], env) + if not isinstance(target, Literal): + raise Exception("'in?' expects a literal as its first argument") + lst = evaluate(args[1], env) + if not isinstance(lst, List): + raise Exception("'in?' expects a list as its second argument") + for arg in lst.args: + ev = evaluate(arg, env) + if isinstance(ev, Literal) and ev.value == target.value: + return Literal(True) + return Literal(False) + +GLOBALS.register("in?", Builtin(interpretIn, 2)) + +def interpretLast(symbol, args, env): + ev = evaluate(args[0], env) + if not isinstance(ev, List): + raise Exception("'last' expects a List") + if len(ev.args) == 0: + raise Exception("List is empty") + return evaluate(ev.args[-1], env) + +GLOBALS.register("last", Builtin(interpretLast, 1)) + +def interpretJoin(symbol, args, env): + lst = evaluate(args[0], env) + if not isinstance(lst, List): + raise Exception("'join' expects a List as its first argument") + target = evaluate(args[1], env) + if not isinstance(target, Literal): + raise Exception("'join' expects a :string as its second argument") + return Literal(target.value.join(lst.args)) + +GLOBALS.register("join", Builtin(interpretJoin, 2)) + +def interpretWithWrite(symbol, args, env): + if len(args) == 0: + raise Exception("'with-write' expects at least one argument") + target_file = evaluate(args[0], env) + if not isinstance(target_file, Literal): + raise Exception("'with-write' expects a filename as its first argument") + new_env = Environment(env) + 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! + for arg in args[1:]: + ret = evaluate(arg, new_env) + return ret + +GLOBALS.register("with-write", Builtin(interpretWithWrite)) + +def interpretWrite(symbol, args, env): + # write :string :filehandle + line = evaluate(args[0], env) + if not isinstance(line, Literal): + raise Exception("'write' expects a string as its first argument") + handle = evaluate(args[1], env) + handle.args[0].write(line.value) # TODO wrong! how do we evaluate a handle? + return Literal([]) + +GLOBALS.register("write", Builtin(interpretWrite, 2)) + +def interpretNewline(symbol, args, env): + return Literal("\n") + +GLOBALS.register("newline", Builtin(interpretNewline, 0)) + +def interpretExists(symbol, args, env): + file_or_dir = evaluate(args[0], env) + if not isinstance(file_or_dir, Literal): + raise Exception("'exists?' expects a string as its first argument") + return Literal(Path(file_or_dir.value).resolve().exists()) + +GLOBALS.register("exists?", Builtin(interpretExists, 1)) |
