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 /* TODO(#540): plus_op should be part of std library */
131 static struct EvalResult
132 plus_op(void *param, Gc *gc, struct Scope *scope, struct Expr args)
138 long int result = 0L;
140 while (!nil_p(args)) {
142 return wrong_argument_type(gc, "consp", args);
145 if (!number_p(CAR(args))) {
146 return wrong_argument_type(gc, "numberp", CAR(args));
149 result += CAR(args).atom->num;
153 return eval_success(NUMBER(gc, result));
156 static struct EvalResult call_lambda(Gc *gc,
160 if (!lambda_p(lambda)) {
161 return eval_failure(CONS(gc,
162 SYMBOL(gc, "expected-callable"),
167 return eval_failure(CONS(gc,
168 SYMBOL(gc, "expected-list"),
172 struct Expr vars = lambda.cons->cdr.cons->car;
174 if (length_of_list(args) != length_of_list(vars)) {
175 return eval_failure(CONS(gc,
176 SYMBOL(gc, "wrong-number-of-arguments"),
177 NUMBER(gc, length_of_list(args))));
180 push_scope_frame(gc, scope, vars, args);
181 struct Expr body = lambda.cons->cdr.cons->cdr;
183 struct EvalResult result = eval_success(NIL(gc));
185 while (!nil_p(body)) {
186 result = eval(gc, scope, body.cons->car);
187 if (result.is_error) {
190 body = body.cons->cdr;
193 pop_scope_frame(gc, scope);
198 static struct EvalResult call_callable(Gc *gc,
200 struct Expr callable,
202 if (callable.type == EXPR_ATOM && callable.atom->type == ATOM_NATIVE) {
203 return ((NativeFunction)callable.atom->native.fun)(callable.atom->native.param, gc, scope, args);
206 return call_lambda(gc, scope, callable, args);
210 lambda(Gc *gc, struct Expr args, struct Expr body)
213 SYMBOL(gc, "lambda"),
214 CONS(gc, args, body));
217 static struct EvalResult eval_block(Gc *gc, struct Scope *scope, struct Expr block)
222 if (!list_p(block)) {
223 return wrong_argument_type(gc, "listp", block);
226 struct Expr head = block;
227 struct EvalResult eval_result = eval_success(NIL(gc));
229 while (cons_p(head)) {
230 eval_result = eval(gc, scope, CAR(head));
231 if (eval_result.is_error) {
241 static struct EvalResult eval_funcall(Gc *gc, struct Scope *scope, struct Cons *cons)
246 if (symbol_p(cons->car)) {
247 if (strcmp(cons->car.atom->sym, "set") == 0) {
248 struct Expr args = cons->cdr;
249 struct EvalResult n = length(gc, args);
255 if (n.expr.atom->num != 2) {
256 return eval_failure(list(gc, 3,
257 SYMBOL(gc, "wrong-number-of-arguments"),
259 NUMBER(gc, n.expr.atom->num)));
262 struct Expr name = args.cons->car;
263 if (!symbol_p(name)) {
264 return eval_failure(list(gc, 3,
265 SYMBOL(gc, "wrong-type-argument"),
266 SYMBOL(gc, "symbolp"),
270 struct EvalResult value = eval(gc, scope, args.cons->cdr.cons->car);
271 if (value.is_error) {
275 set_scope_value(gc, scope, name, value.expr);
277 return eval_success(value.expr);
278 } else if (strcmp(cons->car.atom->sym, "quote") == 0) {
279 /* TODO(#334): quote does not check the amout of it's arguments */
280 return eval_success(cons->cdr.cons->car);
281 } else if (strcmp(cons->car.atom->sym, "begin") == 0) {
282 return eval_block(gc, scope, CDR(cons_as_expr(cons)));
283 } else if (is_lambda(cons)) {
284 /* TODO(#335): lambda special form doesn't check if it forms a callable object */
285 return eval_success(cons_as_expr(cons));
286 } else if (strcmp(cons->car.atom->sym, "defun") == 0) {
287 struct Expr name = NIL(gc);
288 struct Expr args = NIL(gc);
289 struct Expr body = NIL(gc);
291 /* TODO(#554): defun doesn't support functions with empty body because of #545 */
292 struct EvalResult result = match_list(gc, "ee*", cons->cdr, &name, &args, &body);
293 if (result.is_error) {
297 return eval(gc, scope,
301 lambda(gc, args, body)));
302 } else if (strcmp(cons->car.atom->sym, "when") == 0) {
303 struct Expr condition = NIL(gc);
304 struct Expr body = NIL(gc);
306 struct EvalResult result = match_list(
307 gc, "e*", cons->cdr, &condition, &body);
308 if (result.is_error) {
312 result = eval(gc, scope, condition);
313 if (result.is_error) {
317 if (!nil_p(result.expr)) {
318 return eval_block(gc, scope, body);
321 return eval_success(NIL(gc));
325 struct EvalResult r = eval_all_args(gc, scope, cons_as_expr(cons));
331 return call_callable(gc, scope, r.expr.cons->car, r.expr.cons->cdr);
334 struct EvalResult eval(Gc *gc, struct Scope *scope, struct Expr expr)
338 return eval_atom(gc, scope, expr.atom);
341 return eval_funcall(gc, scope, expr.cons);
346 return eval_failure(CONS(gc,
347 SYMBOL(gc, "unexpected-expression"),
352 car(void *param, Gc *gc, struct Scope *scope, struct Expr args)
358 struct Expr xs = NIL(gc);
360 struct EvalResult result = match_list(gc, "e", args, &xs);
361 if (result.is_error) {
366 return eval_success(xs);
370 return wrong_argument_type(gc, "consp", xs);
373 return eval_success(CAR(xs));
376 /* TODO(#536): greaterThan does not support arbitrary amount of arguments */
377 static struct EvalResult
378 greaterThan(void *param, Gc *gc, struct Scope *scope, struct Expr args)
384 long int x = 0, y = 0;
386 struct EvalResult result = match_list(gc, "dd", args, &x, &y);
387 if (result.is_error) {
392 /* TODO(#537): in ebisp t is not a special symbol that evaluates to itself */
393 return eval_success(SYMBOL(gc, "t"));
395 return eval_success(NIL(gc));
399 void load_std_library(Gc *gc, struct Scope *scope)
405 NATIVE(gc, car, NULL));
410 NATIVE(gc, greaterThan, NULL));
415 NATIVE(gc, plus_op, NULL));
419 match_list(struct Gc *gc, const char *format, struct Expr xs, ...)
422 va_start(args_list, xs);
425 for (i = 0; *format != 0 && !nil_p(xs); ++i) {
428 return wrong_argument_type(gc, "consp", xs);
431 struct Expr x = CAR(xs);
437 return wrong_argument_type(gc, "numberp", x);
440 long int *p = va_arg(args_list, long int *);
449 return wrong_argument_type(gc, "stringp", x);
452 const char **p = va_arg(args_list, const char**);
461 return wrong_argument_type(gc, "symbolp", x);
464 const char **p = va_arg(args_list, const char**);
471 struct Expr *p = va_arg(args_list, struct Expr*);
476 struct Expr *p = va_arg(args_list, struct Expr*);
490 if (*format != 0 || !nil_p(xs)) {
492 return wrong_number_of_arguments(gc, i);
496 return eval_success(NIL(gc));
499 /* TODO(#542): format_list(). Similar to match_list() but for constructing list */