]> git.lizzy.rs Git - nothing.git/commitdiff
(#580) Move (defun) to stdlib
authorrexim <reximkut@gmail.com>
Sat, 22 Dec 2018 21:29:15 +0000 (04:29 +0700)
committerrexim <reximkut@gmail.com>
Sat, 22 Dec 2018 21:29:15 +0000 (04:29 +0700)
src/ebisp/interpreter.c
src/ebisp/std.c

index 267df2078c81b769fa8606dc1122e695ae73a7d7..e70067be7d00405d0e5dd8607c7322925f15a4e2 100644 (file)
@@ -182,13 +182,6 @@ static struct EvalResult call_callable(Gc *gc,
     return call_lambda(gc, scope, callable_result.expr, args_result.expr);
 }
 
-static struct Expr
-lambda(Gc *gc, struct Expr args, struct Expr body)
-{
-    return CONS(gc,
-                SYMBOL(gc, "lambda"),
-                CONS(gc, args, body));
-}
 
 struct EvalResult eval_block(Gc *gc, struct Scope *scope, struct Expr block)
 {
@@ -223,22 +216,6 @@ static struct EvalResult eval_funcall(Gc *gc, struct Scope *scope, struct Cons *
         if (is_lambda(cons)) {
             /* TODO(#335): lambda special form doesn't check if it forms a callable object */
             return eval_success(cons_as_expr(cons));
-        } else if (strcmp(cons->car.atom->sym, "defun") == 0) {
-            struct Expr name = NIL(gc);
-            struct Expr args = NIL(gc);
-            struct Expr body = NIL(gc);
-
-            /* TODO(#554): defun doesn't support functions with empty body because of #545 */
-            struct EvalResult result = match_list(gc, "ee*", cons->cdr, &name, &args, &body);
-            if (result.is_error) {
-                return result;
-            }
-
-            return eval(gc, scope,
-                        list(gc, 3,
-                             SYMBOL(gc, "set"),
-                             name,
-                             lambda(gc, args, body)));
         } else if (strcmp(cons->car.atom->sym, "when") == 0) {
             struct Expr condition = NIL(gc);
             struct Expr body = NIL(gc);
index 6b58c0c729ab82e581cf727e91031c978ee08d02..8aa279eef6f970d9b168da5b5697451855183453 100644 (file)
@@ -7,6 +7,14 @@
 
 #include "std.h"
 
+static struct Expr
+lambda(Gc *gc, struct Expr args, struct Expr body)
+{
+    return CONS(gc,
+                SYMBOL(gc, "lambda"),
+                CONS(gc, args, body));
+}
+
 static struct EvalResult
 quasiquote(void *param, Gc *gc, struct Scope *scope, struct Expr expr)
 {
@@ -150,6 +158,29 @@ begin(void *param, Gc *gc, struct Scope *scope, struct Expr args)
     return eval_block(gc, scope, block);
 }
 
+static struct EvalResult
+defun(void *param, Gc *gc, struct Scope *scope, struct Expr args)
+{
+    (void) param;
+    assert(gc);
+    assert(scope);
+
+    struct Expr name = void_expr();
+    struct Expr args_list = void_expr();
+    struct Expr body = void_expr();
+
+    struct EvalResult result = match_list(gc, "ee*", args, &name, &args_list, &body);
+    if (result.is_error) {
+        return result;
+    }
+
+    return eval(gc, scope,
+                list(gc, 3,
+                     SYMBOL(gc, "set"),
+                     name,
+                     lambda(gc, args_list, body)));
+}
+
 void load_std_library(Gc *gc, struct Scope *scope)
 {
     set_scope_value(gc, scope, SYMBOL(gc, "car"), NATIVE(gc, car, NULL));
@@ -163,4 +194,5 @@ void load_std_library(Gc *gc, struct Scope *scope)
     set_scope_value(gc, scope, SYMBOL(gc, "set"), NATIVE(gc, set, NULL));
     set_scope_value(gc, scope, SYMBOL(gc, "quote"), NATIVE(gc, quote, NULL));
     set_scope_value(gc, scope, SYMBOL(gc, "begin"), NATIVE(gc, begin, NULL));
+    set_scope_value(gc, scope, SYMBOL(gc, "defun"), NATIVE(gc, defun, NULL));
 }