diff options
| author | mryouse | 2022-07-29 19:56:22 +0000 |
|---|---|---|
| committer | mryouse | 2022-07-29 19:56:22 +0000 |
| commit | 9fd33f4864310c017a1013f8d18635c1e784f0ab (patch) | |
| tree | 8cc89071be5e6214e1039df87783000c10540123 | |
| parent | 8c7ff22c9cce5478eb20046b7f5f649f529cdf95 (diff) | |
have builtins return :nil when appropriate
| -rw-r--r-- | neb/std/core.py | 38 | ||||
| -rw-r--r-- | neb/std/fs.py | 12 | ||||
| -rw-r--r-- | neb/std/repl.py | 4 | ||||
| -rw-r--r-- | neb/std/sys.py | 10 | ||||
| -rw-r--r-- | neb/structs.py | 5 |
5 files changed, 37 insertions, 32 deletions
diff --git a/neb/std/core.py b/neb/std/core.py index 15a7d61..60c1161 100644 --- a/neb/std/core.py +++ b/neb/std/core.py @@ -14,7 +14,7 @@ def interpretIf(symbol, args, env, ns): return evaluate(args[1], env, ns) elif len(args) == 3: return evaluate(args[2], env, ns) - return List([]) + return Nil() cond = Arg("cond", TypeEnum.BOOL) t_branch = Arg("t-branch", TypeEnum.ANY) @@ -23,7 +23,7 @@ CORE.register("if", NebSyntax("if", interpretIf, [cond, t_branch, f_branch])) def_name_arg = Arg("name", TypeEnum.ANY) def_val_arg = Arg("value", TypeEnum.ANY) -CORE.register("def", NebSyntax("def", None, [def_name_arg, def_val_arg], return_type=Type(":list"))) +CORE.register("def", NebSyntax("def", None, [def_name_arg, def_val_arg], return_type=Type(":nil"))) def interpretRedef(symbol, args, env, ns): if not isinstance(args[0], Symbol): @@ -34,9 +34,9 @@ def interpretRedef(symbol, args, env, ns): res = evaluate(args[1], env, ns) env.reregister(name, res) - return List([]) + return Nil() -CORE.register("redef", NebSyntax("redef", interpretRedef, [def_name_arg, def_val_arg], return_type=Type(":list"))) +CORE.register("redef", NebSyntax("redef", interpretRedef, [def_name_arg, def_val_arg], return_type=Type(":nil"))) lambda_args_arg = Arg("args", TypeEnum.ANY) lambda_body_arg = Arg("body", TypeEnum.ANY) @@ -53,7 +53,7 @@ def interpretForCount(symbol, args, env, ns): for arg in args[1:]: ret = evaluate(arg, new_env, ns) if ret is None: - return List([]) + return Nil() return ret for_count_arg = Arg("count", TypeEnum.INT) @@ -71,7 +71,7 @@ def interpretForEach(symbol, args, env, ns): for arg in args[1:]: ret = evaluate(arg, new_env, ns) if ret is None: - return List([]) + return Nil() return ret for_each_arg = Arg("list", TypeEnum.LIST) @@ -116,7 +116,7 @@ def interpretDropWhile(symbol, args, env, ns): if which_idx is not None: return List(coll.args[which_idx:]) else: - return List([]) + return Nil() CORE.register("drop-while", NebSyntax("drop-while", interpretDropWhile, [for_each_arg, for_body_arg], for_body_arg)) @@ -129,15 +129,15 @@ def interpretBranch(symbol, args, env, ns): raise InterpretPanic(symbol, "branch condition must be :bool", cond) if cond.value: return evaluate(arg.args[1], env, ns) - return List([]) + return Nil() CORE.register("branch", NebSyntax("branch", interpretBranch, [for_body_arg], for_body_arg)) -CORE.register("func", NebSyntax("func", None, [def_name_arg, lambda_args_arg, lambda_body_arg], lambda_body_arg, Type(":list"))) +CORE.register("func", NebSyntax("func", None, [def_name_arg, lambda_args_arg, lambda_body_arg], lambda_body_arg, Type(":nil"))) def interpretBlock(symbol, args, env, ns): new_env = Environment(env) - ret = List([]) + ret = Nil() for arg in args: ret = evaluate(arg, new_env, ns) return ret @@ -148,7 +148,7 @@ CORE.register("block", NebSyntax("block", interpretBlock, [block_arg], block_arg def interpretWhile(symbol, args, env, ns): new_env = Environment(env) cond = args[0] - ret = List([]) + ret = Nil() while True: ev = evaluate(cond, new_env, ns) if not isinstance(ev, Bool): @@ -175,9 +175,9 @@ def interpretUse(symbol, args, env, ns): with open(target_file, "r") as fil: data = fil.read() interpret(parse(lex(data)), env, ns) - return List([]) + return Nil() -CORE.register("use", NebSyntax("use", interpretUse, [Arg("lib-or-file", TypeEnum.STRING)], return_type=Type(":list"))) +CORE.register("use", NebSyntax("use", interpretUse, [Arg("lib-or-file", TypeEnum.STRING)], return_type=Type(":nil"))) # NOTE this doesn't technically need to be a macro def interpretAssert(symbol, args, env, ns): @@ -186,9 +186,9 @@ def interpretAssert(symbol, args, env, ns): raise InterpretPanic(symbol, "requires a :bool condition", cond) if cond.value != True: raise InterpretPanic(symbol, "assertion failed") - return List([]) + return Nil() -CORE.register("assert", NebSyntax("assert", interpretAssert, [Arg("cond", TypeEnum.BOOL)], return_type=Type(":list"))) +CORE.register("assert", NebSyntax("assert", interpretAssert, [Arg("cond", TypeEnum.BOOL)], return_type=Type(":nil"))) def interpretUseAs(symbol, args, env, ns): target = evaluate(args[0], env, ns) @@ -203,9 +203,9 @@ def interpretUseAs(symbol, args, env, ns): with open(target_file, "r") as fil: data = fil.read() interpret(parse(lex(data)), env, new_ns) - return List([]) + return Nil() -CORE.register("use-as", NebSyntax("use-as", interpretUseAs, [Arg("filename", TypeEnum.STRING), Arg("namespace", TypeEnum.ANY)], return_type=Type(":list"))) +CORE.register("use-as", NebSyntax("use-as", interpretUseAs, [Arg("filename", TypeEnum.STRING), Arg("namespace", TypeEnum.ANY)], return_type=Type(":nil"))) def interpretQuote(symbol, args, env, ns): return args[0] @@ -240,12 +240,12 @@ def interpretType(symbol, args, env, ns): new_type = UserType(name, parent_type, func) env.register(name, new_type) - return List([]) + return Nil() type_name_arg = Arg("name", TypeEnum.ANY) type_parent_arg = Arg("name", TypeEnum.ANY) type_func_arg = Arg("func", TypeEnum.ANY) -CORE.register("type", NebSyntax("type", interpretType, [type_name_arg, type_parent_arg, type_func_arg])) +CORE.register("type", NebSyntax("type", interpretType, [type_name_arg, type_parent_arg, type_func_arg], return_type=Type(":nil"))) def interpretOr(symbol, args, env, ns): # or returns true for the first expression that returns true diff --git a/neb/std/fs.py b/neb/std/fs.py index b49d63c..8500140 100644 --- a/neb/std/fs.py +++ b/neb/std/fs.py @@ -33,9 +33,9 @@ def interpretUnlink(symbol, args, env, ns): if not target_path.exists(): raise InterpretPanic(symbol, "target file does not exist", target_path) target_path.unlink() - return List([]) + return Nil() -unlink_func = Builtin("unlink", interpretUnlink, [Arg("filename", TypeEnum.STRING)], return_type=Type(":list")) +unlink_func = Builtin("unlink", interpretUnlink, [Arg("filename", TypeEnum.STRING)], return_type=Type(":nil")) unlink_multi = MultiFunction("unlink") unlink_multi.register(unlink_func) FS.register("unlink", unlink_multi) @@ -49,9 +49,9 @@ def interpretWrite(symbol, args, env, ns): raise InterpretPanic(symbol, f"{handle} is not writable!") except ValueError: raise InterpretPanic(symbol, f"{handle} is closed") - return List([]) + return Nil() -write_func = Builtin("write", interpretWrite, [Arg("string", TypeEnum.STRING), Arg("handle", TypeEnum.HANDLE)], return_type=TypeEnum.LIST) +write_func = Builtin("write", interpretWrite, [Arg("string", TypeEnum.STRING), Arg("handle", TypeEnum.HANDLE)], return_type=Type(":nil")) write_multi = MultiFunction("write") write_multi.register(write_func) FS.register("write", write_multi) @@ -109,9 +109,9 @@ def interpretClose(symbol, args, env, ns): # (close (print (read (open-read "fil.txt")))) except: raise InterpretPanic(symbol, "cannot close {args[0]}") - return List([]) + return Nil() -close_func = Builtin("close", interpretClose, [Arg("handle", TypeEnum.HANDLE)], return_type=TypeEnum.LIST) +close_func = Builtin("close", interpretClose, [Arg("handle", TypeEnum.HANDLE)], return_type=Type(":nil")) close_multi = MultiFunction("close") close_multi.register(close_func) FS.register("close", close_multi) diff --git a/neb/std/repl.py b/neb/std/repl.py index 0274e48..2979c5b 100644 --- a/neb/std/repl.py +++ b/neb/std/repl.py @@ -15,9 +15,9 @@ def interpretHowTo(symbol, args, env, ns): print(des) else: print("\n".join(des)) - return List([]) + return Nil() -howto_func = Builtin("howto", interpretHowTo, [Arg("symbol", TypeEnum.ANY)], return_type=Type(":list")) +howto_func = Builtin("howto", interpretHowTo, [Arg("symbol", TypeEnum.ANY)], return_type=Type(":nil")) howto_multi = MultiFunction("howto") howto_multi.register(howto_func) REPL.register("howto", howto_multi) diff --git a/neb/std/sys.py b/neb/std/sys.py index 1bbc938..7ff5e56 100644 --- a/neb/std/sys.py +++ b/neb/std/sys.py @@ -31,10 +31,10 @@ SYS.register("$", shell_multi) def interpretExit(symbol, args, env, ns): status = 0 if len(args) == 0 else args[0].value sys.exit(status) - return List([]) + return Nil() -exit_func = Builtin("exit", interpretExit, [], return_type=Type(":list")) -exit_status_func = Builtin("exit", interpretExit, [Arg("status", TypeEnum.INT)], return_type=Type(":list")) +exit_func = Builtin("exit", interpretExit, [], return_type=Type(":nil")) +exit_status_func = Builtin("exit", interpretExit, [Arg("status", TypeEnum.INT)], return_type=Type(":nil")) exit_multi = MultiFunction("exit") exit_multi.register(exit_func) exit_multi.register(exit_status_func) @@ -42,9 +42,9 @@ SYS.register("exit", exit_multi) def interpretPrint(symbol, args, env, ns): print(args[0].value) - return List([]) # print returns nothing + return Nil() -print_func = Builtin("print", interpretPrint, [Arg("arg", TypeEnum.STRING)], return_type=Type(":list")) +print_func = Builtin("print", interpretPrint, [Arg("arg", TypeEnum.STRING)], return_type=Type(":nil")) print_multi = MultiFunction("print") print_multi.register(print_func) SYS.register("print", print_multi) diff --git a/neb/structs.py b/neb/structs.py index 2423a69..db71aa0 100644 --- a/neb/structs.py +++ b/neb/structs.py @@ -169,6 +169,11 @@ class List: def __str__(self): return "(" + " ".join(f"{arg}" for arg in self.args) + ")" +class Nil(List): + def __init__(self): + self.args = [] + self.type_ = ALL_TYPES[":nil"] + # function things class Arg: |
