6 #include "./builtins.h"
8 #include "./interpreter.h"
11 struct EvalResult eval_success(struct Expr expr)
13 struct EvalResult result = {
21 struct EvalResult eval_failure(struct Expr error)
23 struct EvalResult result = {
32 wrong_argument_type(Gc *gc, const char *type, struct Expr obj)
36 SYMBOL(gc, "wrong-argument-type"),
42 wrong_number_of_arguments(Gc *gc, long int count)
46 SYMBOL(gc, "wrong-number-of-arguments"),
51 not_implemented(Gc *gc)
53 return eval_failure(SYMBOL(gc, "not-implemented"));
56 static struct EvalResult length(Gc *gc, struct Expr obj)
59 return wrong_argument_type(gc, "listp", obj);
62 return eval_success(NUMBER(gc, length_of_list(obj)));
65 static struct EvalResult eval_atom(Gc *gc, struct Scope *scope, struct Atom *atom)
74 return eval_success(atom_as_expr(atom));
77 if (nil_p(atom_as_expr(atom))) {
78 return eval_success(atom_as_expr(atom));
81 struct Expr value = get_scope_value(scope, atom_as_expr(atom));
84 return eval_failure(CONS(gc,
85 SYMBOL(gc, "void-variable"),
89 return eval_success(value.cons->cdr);
93 return eval_failure(CONS(gc,
94 SYMBOL(gc, "unexpected-expression"),
98 static struct EvalResult eval_all_args(Gc *gc, struct Scope *scope, struct Expr args)
105 return eval_atom(gc, scope, args.atom);
108 struct EvalResult car = eval(gc, scope, args.cons->car);
113 struct EvalResult cdr = eval_all_args(gc, scope, args.cons->cdr);
118 return eval_success(cons_as_expr(create_cons(gc, car.expr, cdr.expr)));
124 return eval_failure(CONS(gc,
125 SYMBOL(gc, "unexpected-expression"),
129 /* TODO(#540): plus_op should be part of std library */
130 static struct EvalResult plus_op(Gc *gc, struct Expr args)
132 long int result = 0.0f;
134 while (!nil_p(args)) {
135 if (args.type != EXPR_CONS) {
136 return eval_failure(CONS(gc,
137 SYMBOL(gc, "expected-cons"),
141 if (args.cons->car.type != EXPR_ATOM ||
142 args.cons->car.atom->type != ATOM_NUMBER) {
143 return eval_failure(CONS(gc,
144 SYMBOL(gc, "expected-number"),
148 result += args.cons->car.atom->num;
149 args = args.cons->cdr;
152 return eval_success(atom_as_expr(create_number_atom(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);
208 static struct EvalResult eval_block(Gc *gc, struct Scope *scope, struct Expr block)
213 if (!list_p(block)) {
214 return wrong_argument_type(gc, "listp", block);
217 struct Expr head = block;
218 struct EvalResult eval_result = eval_success(NIL(gc));
220 while (cons_p(head)) {
221 eval_result = eval(gc, scope, CAR(head));
222 if (eval_result.is_error) {
232 static struct EvalResult eval_funcall(Gc *gc, struct Scope *scope, struct Cons *cons)
237 if (symbol_p(cons->car)) {
238 /* TODO(#541): special forms should be just regular native functions but with no arguments evaluation */
239 if (strcmp(cons->car.atom->sym, "+") == 0) {
240 struct EvalResult args = eval_all_args(gc, scope, cons->cdr);
244 return plus_op(gc, args.expr);
245 } else if (strcmp(cons->car.atom->sym, "set") == 0) {
246 struct Expr args = cons->cdr;
247 struct EvalResult n = length(gc, args);
253 if (n.expr.atom->num != 2) {
254 return eval_failure(list(gc, 3,
255 SYMBOL(gc, "wrong-number-of-arguments"),
257 NUMBER(gc, n.expr.atom->num)));
260 struct Expr name = args.cons->car;
261 if (!symbol_p(name)) {
262 return eval_failure(list(gc, 3,
263 SYMBOL(gc, "wrong-type-argument"),
264 SYMBOL(gc, "symbolp"),
268 struct EvalResult value = eval(gc, scope, args.cons->cdr.cons->car);
269 if (value.is_error) {
273 set_scope_value(gc, scope, name, value.expr);
275 return eval_success(value.expr);
276 } else if (strcmp(cons->car.atom->sym, "quote") == 0) {
277 /* TODO(#334): quote does not check the amout of it's arguments */
278 return eval_success(cons->cdr.cons->car);
279 } else if (strcmp(cons->car.atom->sym, "begin") == 0) {
280 return eval_block(gc, scope, CDR(cons_as_expr(cons)));
281 } else if (strcmp(cons->car.atom->sym, "lambda") == 0) {
282 /* TODO(#335): lambda special form doesn't check if it forms a callable object */
283 return eval_success(cons_as_expr(cons));
284 } else if (strcmp(cons->car.atom->sym, "when") == 0) {
285 struct Expr condition = NIL(gc);
286 struct Expr body = NIL(gc);
288 struct EvalResult result = match_list(
289 gc, "e*", cons->cdr, &condition, &body);
290 if (result.is_error) {
294 result = eval(gc, scope, condition);
295 if (result.is_error) {
299 if (!nil_p(result.expr)) {
300 return eval_block(gc, scope, body);
303 return eval_success(NIL(gc));
307 struct EvalResult r = eval_all_args(gc, scope, cons_as_expr(cons));
313 return call_callable(gc, scope, r.expr.cons->car, r.expr.cons->cdr);
316 struct EvalResult eval(Gc *gc, struct Scope *scope, struct Expr expr)
320 return eval_atom(gc, scope, expr.atom);
323 return eval_funcall(gc, scope, expr.cons);
328 return eval_failure(CONS(gc,
329 SYMBOL(gc, "unexpected-expression"),
334 car(void *param, Gc *gc, struct Scope *scope, struct Expr args)
340 struct Expr xs = NIL(gc);
341 struct Expr x = NIL(gc);
343 struct EvalResult result = match_list(gc, "e", args, &xs);
344 if (result.is_error) {
349 return eval_success(xs);
352 result = match_list(gc, "e*", xs, &x, NULL);
353 if (result.is_error) {
357 return eval_success(x);
360 /* TODO(#536): greaterThan does not support arbitrary amount of arguments */
361 static struct EvalResult
362 greaterThan(void *param, Gc *gc, struct Scope *scope, struct Expr args)
368 long int x = 0, y = 0;
370 struct EvalResult result = match_list(gc, "dd", args, &x, &y);
371 if (result.is_error) {
376 /* TODO(#537): in ebisp t is not a special symbol that evaluates to itself */
377 return eval_success(SYMBOL(gc, "t"));
379 return eval_success(NIL(gc));
383 void load_std_library(Gc *gc, struct Scope *scope)
389 NATIVE(gc, car, NULL));
395 NATIVE(gc, greaterThan, NULL));
399 match_list(struct Gc *gc, const char *format, struct Expr xs, ...)
402 va_start(args_list, xs);
406 return wrong_argument_type(gc, "listp", xs);
410 for (i = 0; *format != 0 && !nil_p(xs); ++i) {
411 struct Expr x = CAR(xs);
417 return wrong_argument_type(gc, "numberp", x);
420 long int *p = va_arg(args_list, long int *);
429 return wrong_argument_type(gc, "stringp", x);
432 const char **p = va_arg(args_list, const char**);
441 return wrong_argument_type(gc, "symbolp", x);
444 const char **p = va_arg(args_list, const char**);
451 struct Expr *p = va_arg(args_list, struct Expr*);
456 struct Expr *p = va_arg(args_list, struct Expr*);
470 if (*format != 0 || !nil_p(xs)) {
473 SYMBOL(gc, "wrong-number-of-arguments"),
477 return eval_success(NIL(gc));
480 /* TODO(#542): format_list(). Similar to match_list() but for constructing list */