diff options
| author | mryouse | 2022-05-22 22:08:48 +0000 |
|---|---|---|
| committer | mryouse | 2022-05-22 22:08:48 +0000 |
| commit | 93c8a167ed7e8a8288e813bd0bd2bc54f7bb769d (patch) | |
| tree | 9bb50974107df1aea3db4cac328ed5103189d1b4 | |
| parent | 28e89dff46b23b2fd73704d46db96b86e7e35e3c (diff) | |
implement read-lines, strip, first, rest, map
| -rw-r--r-- | interpreter.py | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/interpreter.py b/interpreter.py index e888944..03b5c00 100644 --- a/interpreter.py +++ b/interpreter.py @@ -1,4 +1,5 @@ from structs import Literal, Symbol, List +from pathlib import Path class Function: @@ -332,3 +333,63 @@ def interpretFunc(symbol, args, env): GLOBALS.register("func", Builtin(interpretFunc)) +# THINGS NEEDED FOR AOC +# - read the contents of a file +def interpretReadLines(symbol, args, env): + target_file_name = evaluate(args[0], env) + target_file = Path(target_file_name).resolve() + if not target_file.exists(): + raise Exception(f"no such file: {target_file}") + with open(target_file, "r") as fil: + data = fil.readlines() + out = List([Literal(d) for d in data]) # all lines are strings + return out + +GLOBALS.register("read-lines", Builtin(interpretReadLines, 1)) + +# - strip whitespace from string +def interpretStrip(symbol, args, env): + out = evaluate(args[0], env) + return out.strip() + +GLOBALS.register("strip", Builtin(interpretStrip, 1)) + +# - string->int and string->float +# - split a string by a given field +# - get the length of a list +# - first/rest of list +def interpretFirst(symbol, args, env): + ev = evaluate(args[0], env) + if not isinstance(ev, List): + raise Exception("'first' expects a List") + if len(ev.args) == 0: + raise Exception("List is empty") + return evaluate(ev.args[0], env) + +GLOBALS.register("first", Builtin(interpretFirst, 1)) + +def interpretRest(symbol, args, env): + ev = evaluate(args[0], env) + if not isinstance(ev, List): + raise Exception("'rest' expects a List") + return List(ev.args[1:]) # we don't evaluate the remainder of the list + +GLOBALS.register("rest", Builtin(interpretRest, 1)) + +# - iterate over list +# - map +def interpretMap(symbol, args, env): + # TODO: to support lambdas, we can't assume the func is defined + func = args[0] + if not isinstance(func, Symbol): + raise Exception("'map' takes a function as its first argument") + lst = evaluate(args[1], env) + if not isinstance(lst, List): + raise Exception("'map' takes a List as its second argument") + out = [] + for arg in lst.args: + ev = evaluate(List([func, arg]), env) + out.append(ev) + return List(out) + +GLOBALS.register("map", Builtin(interpretMap, 2)) |
