aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/interp.c1
-rw-r--r--src/primitives.c11
-rw-r--r--src/primitives.h1
3 files changed, 13 insertions, 0 deletions
diff --git a/src/interp.c b/src/interp.c
index 8b5c15f..4a6a455 100644
--- a/src/interp.c
+++ b/src/interp.c
@@ -122,6 +122,7 @@ void Interp_init(Interp *self) {
Interp_add_primitive(self, "assert", primitive_assert);
Interp_add_primitive(self, "assert-error", primitive_assert_error);
Interp_add_primitive(self, "load", primitive_load);
+ Interp_add_primitive(self, "unwind-protect", primitive_unwind_protect);
Interp_add_userfunc(self, "function?", builtin_functionp);
Interp_add_userfunc(self, "map", builtin_map);
diff --git a/src/primitives.c b/src/primitives.c
index a8bb62a..9f3e670 100644
--- a/src/primitives.c
+++ b/src/primitives.c
@@ -79,6 +79,17 @@ SExpRef primitive_eval(Interp *interp, SExpRef args, bool istail) {
return lisp_eval(interp, args, istail);
}
+SExpRef primitive_unwind_protect(Interp *interp, SExpRef args, bool istail) {
+ if (LENGTH(args) < 2) {
+ return new_error(interp, "unwind-protect: syntax error.\n");
+ }
+ SExpRef ret = EVAL(CAR(args));
+ for (SExpRef i = CDR(args); !NILP(i); i = CDR(i)) {
+ EVAL(CAR(i));
+ }
+ return ret;
+}
+
SExpRef primitive_if(Interp *interp, SExpRef args, bool istail) {
SExpRef cond, tb, fb;
diff --git a/src/primitives.h b/src/primitives.h
index f5dd8e8..a5aa2bc 100644
--- a/src/primitives.h
+++ b/src/primitives.h
@@ -28,5 +28,6 @@ SExpRef primitive_quote(Interp *interp, SExpRef sexp, bool istail);
SExpRef primitive_quasi(Interp *interp, SExpRef sexp, bool istail);
SExpRef primitive_and(Interp *interp, SExpRef sexp, bool istail);
SExpRef primitive_or(Interp *interp, SExpRef sexp, bool istail);
+SExpRef primitive_unwind_protect(Interp *interp, SExpRef sexp, bool istail);
#endif