7 #include "./builtins.h"
9 #include "./interpreter.h"
12 struct EvalResult eval_success(struct Expr expr)
14 struct EvalResult result = {
22 struct EvalResult eval_failure(struct Expr error)
24 struct EvalResult result = {
33 wrong_argument_type(Gc *gc, const char *type, struct Expr obj)
37 SYMBOL(gc, "wrong-argument-type"),
43 wrong_number_of_arguments(Gc *gc, long int count)
47 SYMBOL(gc, "wrong-number-of-arguments"),
52 not_implemented(Gc *gc)
54 return eval_failure(SYMBOL(gc, "not-implemented"));
57 static struct EvalResult length(Gc *gc, struct Expr obj)
60 return wrong_argument_type(gc, "listp", obj);
63 return eval_success(NUMBER(gc, length_of_list(obj)));
66 static struct EvalResult eval_atom(Gc *gc, struct Scope *scope, struct Atom *atom)
75 return eval_success(atom_as_expr(atom));
78 if (nil_p(atom_as_expr(atom))) {
79 return eval_success(atom_as_expr(atom));
82 struct Expr value = get_scope_value(scope, atom_as_expr(atom));
85 return eval_failure(CONS(gc,
86 SYMBOL(gc, "void-variable"),
90 return eval_success(value.cons->cdr);
94 return eval_failure(CONS(gc,
95 SYMBOL(gc, "unexpected-expression"),
99 static struct EvalResult eval_all_args(Gc *gc, struct Scope *scope, struct Expr args)
106 return eval_atom(gc, scope, args.atom);
109 struct EvalResult car = eval(gc, scope, args.cons->car);
114 struct EvalResult cdr = eval_all_args(gc, scope, args.cons->cdr);
119 return eval_success(cons_as_expr(create_cons(gc, car.expr, cdr.expr)));
125 return eval_failure(CONS(gc,
126 SYMBOL(gc, "unexpected-expression"),
130 static struct EvalResult
131 plus_op(void *param, Gc *gc, struct Scope *scope, struct Expr args)
137 long int result = 0L;
139 while (!nil_p(args)) {
141 return wrong_argument_type(gc, "consp", args);
144 if (!number_p(CAR(args))) {
145 return wrong_argument_type(gc, "numberp", CAR(args));
148 result += CAR(args).atom->num;
152 return eval_success(NUMBER(gc, result));
155 static struct EvalResult call_lambda(Gc *gc,
159 if (!lambda_p(lambda)) {
160 return eval_failure(CONS(gc,
161 SYMBOL(gc, "expected-callable"),
166 return eval_failure(CONS(gc,
167 SYMBOL(gc, "expected-list"),
171 struct Expr vars = lambda.cons->cdr.cons->car;
173 if (length_of_list(args) != length_of_list(vars)) {
174 return eval_failure(CONS(gc,
175 SYMBOL(gc, "wrong-number-of-arguments"),
176 NUMBER(gc, length_of_list(args))));
179 push_scope_frame(gc, scope, vars, args);
180 struct Expr body = lambda.cons->cdr.cons->cdr;
182 struct EvalResult result = eval_success(NIL(gc));
184 while (!nil_p(body)) {
185 result = eval(gc, scope, body.cons->car);
186 if (result.is_error) {
189 body = body.cons->cdr;
192 pop_scope_frame(gc, scope);
197 static struct EvalResult call_callable(Gc *gc,
199 struct Expr callable,
201 if (callable.type == EXPR_ATOM && callable.atom->type == ATOM_NATIVE) {
202 return ((NativeFunction)callable.atom->native.fun)(callable.atom->native.param, gc, scope, args);
205 return call_lambda(gc, scope, callable, args);
209 lambda(Gc *gc, struct Expr args, struct Expr body)
212 SYMBOL(gc, "lambda"),
213 CONS(gc, args, body));
216 static struct EvalResult eval_block(Gc *gc, struct Scope *scope, struct Expr block)
221 if (!list_p(block)) {
222 return wrong_argument_type(gc, "listp", block);
225 struct Expr head = block;
226 struct EvalResult eval_result = eval_success(NIL(gc));
228 while (cons_p(head)) {
229 eval_result = eval(gc, scope, CAR(head));
230 if (eval_result.is_error) {
240 static struct EvalResult eval_funcall(Gc *gc, struct Scope *scope, struct Cons *cons)
245 if (symbol_p(cons->car)) {
246 if (strcmp(cons->car.atom->sym, "set") == 0) {
247 struct Expr args = cons->cdr;
248 struct EvalResult n = length(gc, args);
254 if (n.expr.atom->num != 2) {
255 return eval_failure(list(gc, 3,
256 SYMBOL(gc, "wrong-number-of-arguments"),
258 NUMBER(gc, n.expr.atom->num)));
261 struct Expr name = args.cons->car;
262 if (!symbol_p(name)) {
263 return eval_failure(list(gc, 3,
264 SYMBOL(gc, "wrong-type-argument"),
265 SYMBOL(gc, "symbolp"),
269 struct EvalResult value = eval(gc, scope, args.cons->cdr.cons->car);
270 if (value.is_error) {
274 set_scope_value(gc, scope, name, value.expr);
276 return eval_success(value.expr);
277 } else if (strcmp(cons->car.atom->sym, "quote") == 0) {
278 /* TODO(#334): quote does not check the amout of it's arguments */
279 return eval_success(cons->cdr.cons->car);
280 } else if (strcmp(cons->car.atom->sym, "begin") == 0) {
281 return eval_block(gc, scope, CDR(cons_as_expr(cons)));
282 } else if (is_lambda(cons)) {
283 /* TODO(#335): lambda special form doesn't check if it forms a callable object */
284 return eval_success(cons_as_expr(cons));
285 } else if (strcmp(cons->car.atom->sym, "defun") == 0) {
286 struct Expr name = NIL(gc);
287 struct Expr args = NIL(gc);
288 struct Expr body = NIL(gc);
290 /* TODO(#554): defun doesn't support functions with empty body because of #545 */
291 struct EvalResult result = match_list(gc, "ee*", cons->cdr, &name, &args, &body);
292 if (result.is_error) {
296 return eval(gc, scope,
300 lambda(gc, args, body)));
301 } else if (strcmp(cons->car.atom->sym, "when") == 0) {
302 struct Expr condition = NIL(gc);
303 struct Expr body = NIL(gc);
305 struct EvalResult result = match_list(
306 gc, "e*", cons->cdr, &condition, &body);
307 if (result.is_error) {
311 result = eval(gc, scope, condition);
312 if (result.is_error) {
316 if (!nil_p(result.expr)) {
317 return eval_block(gc, scope, body);
320 return eval_success(NIL(gc));
324 struct EvalResult r = eval_all_args(gc, scope, cons_as_expr(cons));
330 return call_callable(gc, scope, r.expr.cons->car, r.expr.cons->cdr);
333 struct EvalResult eval(Gc *gc, struct Scope *scope, struct Expr expr)
337 return eval_atom(gc, scope, expr.atom);
340 return eval_funcall(gc, scope, expr.cons);
345 return eval_failure(CONS(gc,
346 SYMBOL(gc, "unexpected-expression"),
351 car(void *param, Gc *gc, struct Scope *scope, struct Expr args)
357 struct Expr xs = NIL(gc);
359 struct EvalResult result = match_list(gc, "e", args, &xs);
360 if (result.is_error) {
365 return eval_success(xs);
369 return wrong_argument_type(gc, "consp", xs);
372 return eval_success(CAR(xs));
375 static struct EvalResult
376 list_op(void *param, Gc *gc, struct Scope *scope, struct Expr args)
382 return eval_success(args);
385 /* TODO(#536): greaterThan does not support arbitrary amount of arguments */
386 static struct EvalResult
387 greaterThan(void *param, Gc *gc, struct Scope *scope, struct Expr args)
393 long int x = 0, y = 0;
395 struct EvalResult result = match_list(gc, "dd", args, &x, &y);
396 if (result.is_error) {
401 /* TODO(#537): in ebisp t is not a special symbol that evaluates to itself */
402 return eval_success(SYMBOL(gc, "t"));
404 return eval_success(NIL(gc));
408 void load_std_library(Gc *gc, struct Scope *scope)
414 NATIVE(gc, car, NULL));
419 NATIVE(gc, greaterThan, NULL));
424 NATIVE(gc, plus_op, NULL));
429 NATIVE(gc, list_op, NULL));
433 match_list(struct Gc *gc, const char *format, struct Expr xs, ...)
436 va_start(args_list, xs);
439 for (i = 0; *format != 0 && !nil_p(xs); ++i) {
442 return wrong_argument_type(gc, "consp", xs);
445 struct Expr x = CAR(xs);
451 return wrong_argument_type(gc, "numberp", x);
454 long int *p = va_arg(args_list, long int *);
463 return wrong_argument_type(gc, "stringp", x);
466 const char **p = va_arg(args_list, const char**);
475 return wrong_argument_type(gc, "symbolp", x);
478 const char **p = va_arg(args_list, const char**);
485 struct Expr *p = va_arg(args_list, struct Expr*);
490 struct Expr *p = va_arg(args_list, struct Expr*);
504 if (*format == '*' && nil_p(xs)) {
505 struct Expr *p = va_arg(args_list, struct Expr*);
512 if (*format != 0 || !nil_p(xs)) {
514 return wrong_number_of_arguments(gc, i);
518 return eval_success(NIL(gc));
521 /* TODO(#542): format_list(). Similar to match_list() but for constructing list */