aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormryouse2022-07-29 19:56:22 +0000
committermryouse2022-07-29 19:56:22 +0000
commit9fd33f4864310c017a1013f8d18635c1e784f0ab (patch)
tree8cc89071be5e6214e1039df87783000c10540123
parent8c7ff22c9cce5478eb20046b7f5f649f529cdf95 (diff)
have builtins return :nil when appropriate
-rw-r--r--neb/std/core.py38
-rw-r--r--neb/std/fs.py12
-rw-r--r--neb/std/repl.py4
-rw-r--r--neb/std/sys.py10
-rw-r--r--neb/structs.py5
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: