5 #include "./builtins.h"
7 #include "./interpreter.h"
9 struct EvalResult eval_success(struct Expr expr)
11 struct EvalResult result = {
20 struct EvalResult eval_failure(const char *error, struct Expr expr)
22 struct EvalResult result = {
31 static struct EvalResult eval_atom(Gc *gc, struct Expr scope, struct Atom *atom)
35 /* TODO(#314): Evaluating symbols is not implemented */
40 /* TODO(#322): get rid of unnecessary clone_expr from interpreter */
41 return eval_success(clone_expr(gc, atom_as_expr(atom)));
44 return eval_failure("Unexpected expression", clone_expr(gc, atom_as_expr(atom)));
47 static struct EvalResult eval_args(Gc *gc, struct Expr scope, struct Expr args)
54 return eval_atom(gc, scope, args.atom);
57 struct EvalResult car = eval(gc, scope, args.cons->car);
62 struct EvalResult cdr = eval_args(gc, scope, args.cons->cdr);
67 return eval_success(cons_as_expr(create_cons(gc, car.expr, cdr.expr)));
73 return eval_failure("Unexpected expression", clone_expr(gc, args));
76 static struct EvalResult plus_op(Gc *gc, struct Expr args)
80 while (!nil_p(args)) {
81 if (args.type != EXPR_CONS) {
82 return eval_failure("Expected cons", clone_expr(gc, args));
85 if (args.cons->car.type != EXPR_ATOM ||
86 args.cons->car.atom->type != ATOM_NUMBER) {
87 return eval_failure("Expected number", clone_expr(gc, args.cons->car));
90 result += args.cons->car.atom->num;
91 args = args.cons->cdr;
94 return eval_success(atom_as_expr(create_number_atom(gc, result)));
97 static struct EvalResult eval_funcall(Gc *gc, struct Expr scope, struct Cons *cons)
102 if (!symbol_p(cons->car)) {
103 return eval_failure("Expected symbol", clone_expr(gc, cons->car));
106 /* TODO: set builtin function is not implemented */
107 /* depends on #317 */
108 if (strcmp(cons->car.atom->sym, "+") == 0) {
109 struct EvalResult args = eval_args(gc, scope, cons->cdr);
113 return plus_op(gc, args.expr);
116 return eval_failure("Unknown function", clone_expr(gc, cons->car));
119 /* TODO(#317): eval does not return new scope after the evaluation */
120 struct EvalResult eval(Gc *gc, struct Expr scope, struct Expr expr)
124 return eval_atom(gc, scope, expr.atom);
127 return eval_funcall(gc, scope, expr.cons);
132 return eval_failure("Unexpected expression", clone_expr(gc, expr));
135 void print_eval_error(FILE *stream, struct EvalResult result)
137 if (!result.is_error) {
141 fprintf(stream, "%s\n", result.error);
142 print_expr_as_sexpr(result.expr);