diff options
| author | mryouse | 2022-07-05 03:24:49 +0000 |
|---|---|---|
| committer | mryouse | 2022-07-05 03:24:49 +0000 |
| commit | 2402523aa84780447e3ce0a8109a14e1286665c8 (patch) | |
| tree | 8bb4792c24154defbb046ca17a879bbb01da94b0 /neb/std/fs.py | |
| parent | db0327ba8c9fae4a57f85f60e2f0bac438781b8e (diff) | |
| parent | cf0ae625ddc9076e0ca02079b8d461de22244998 (diff) | |
Merge branch 'master' into feature/listtypes
Diffstat (limited to 'neb/std/fs.py')
| -rw-r--r-- | neb/std/fs.py | 80 |
1 files changed, 75 insertions, 5 deletions
diff --git a/neb/std/fs.py b/neb/std/fs.py index 495c7ea..d20cde9 100644 --- a/neb/std/fs.py +++ b/neb/std/fs.py @@ -2,9 +2,15 @@ from .. import TypeEnum, Environment, Arg, Builtin, evaluate, InterpretPanic from ..structs import * from pathlib import Path from glob import glob +from io import UnsupportedOperation +import sys FS = Environment() +FS.register("_stdin_", Handle(sys.stdin)) +FS.register("_stdout_", Handle(sys.stdout)) +FS.register("_stderr_", Handle(sys.stderr)) + def interpretExists(symbol, args, env, ns): return Bool(Path(args[0].value).resolve().exists()) @@ -39,13 +45,77 @@ def interpretWithWrite(symbol, args, env, ns): FS.register("with-write", Builtin("with-write", interpretWithWrite, [Arg("filename", TypeEnum.STRING)], Arg("exprs", TypeEnum.ANY, lazy=True))) def interpretWrite(symbol, args, env, ns): - # write :string :filehandle - line = args[0] + string = args[0] handle = args[1] - handle.args[0].write(line.value) # TODO wrong! how do we evaluate a handle? - return Literal([]) + try: + handle.file.write(string.value) + except UnsupportedOperation: + raise InterpretPanic(symbol, f"{handle} is not writable!") + except ValueError: + raise InterpretPanic(symbol, f"{handle} is closed") + return List([]) + +FS.register("write", Builtin("write", interpretWrite, [Arg("string", TypeEnum.STRING), Arg("handle", TypeEnum.HANDLE)], return_type=TypeEnum.LIST)) + +def interpretOpenRead(symbol, args, env, ns): + name = args[0].value + fil = Path(name) + if not fil.exists(): + raise InterpretPanic(symbol, "file does not exist", fil) + try: + f = open(str(fil), "r") + except: + raise InterpretPanic(symbol, "cannot open {fil} for reading") + return Handle(f) + +FS.register("open-read", Builtin("open-read", interpretOpenRead, [Arg("filename", TypeEnum.STRING)], return_type=TypeEnum.HANDLE)) + +def interpretOpenWrite(symbol, args, env, ns): + name = args[0].value + fil = Path(name) + try: + f = open(str(fil), "w") + except: + raise InterpretPanic(symbol, "cannot open {fil} for writing") + return Handle(f) + +FS.register("open-write", Builtin("open-write", interpretOpenWrite, [Arg("filename", TypeEnum.STRING)], return_type=TypeEnum.HANDLE)) + +def interpretOpenAppend(symbol, args, env, ns): + name = args[0].value + fil = Path(name) + try: + f = open(str(fil), "a") + except: + raise InterpretPanic(symbol, "cannot open {fil} for appending") + return Handle(f) + +FS.register("open-append", Builtin("open-append", interpretOpenAppend, [Arg("filename", TypeEnum.STRING)], return_type=TypeEnum.HANDLE)) + +def interpretClose(symbol, args, env, ns): + try: + args[0].file.close() + # TODO ideally we'd be able to remove it from the env + # but by this point, we don't know its symbol + # though it may not be in the env, e.g. + # (close (print (read (open-read "fil.txt")))) + except: + raise InterpretPanic(symbol, "cannot close {args[0]}") + return List([]) + +FS.register("close", Builtin("close", interpretClose, [Arg("handle", TypeEnum.HANDLE)], return_type=TypeEnum.LIST)) + +def interpretRead(symbol, args, env, ns): + handle = args[0] + try: + inp = args[0].file.read() + except UnsupportedOperation: + raise InterpretPanic(symbol, f"{handle} is not writable!") + except ValueError: + raise InterpretPanic(symbol, f"{handle} is closed") + return String(inp) -FS.register("write", Builtin("write", interpretWrite, [Arg("string", TypeEnum.STRING), Arg("filename", TypeEnum.LIST)])) +FS.register("read", Builtin("read", interpretRead, [Arg("handle", TypeEnum.HANDLE)], return_type=TypeEnum.STRING)) def interpretReadLines(symbol, args, env, ns): target_file_name = args[0].value |
