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)
{
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);
#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)
{
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));
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));
}