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 return eval_success(clone_expr(gc, atom_as_expr(atom)));
43 return eval_failure("Unexpected expression", clone_expr(gc, atom_as_expr(atom)));
46 static struct EvalResult eval_args(Gc *gc, struct Expr scope, struct Expr args)
53 return eval_atom(gc, scope, args.atom);
56 struct EvalResult car = eval(gc, scope, args.cons->car);
61 struct EvalResult cdr = eval_args(gc, scope, args.cons->cdr);
66 return eval_success(cons_as_expr(create_cons(gc, car.expr, cdr.expr)));
72 return eval_failure("Unexpected expression", clone_expr(gc, args));
75 static struct EvalResult plus_op(Gc *gc, struct Expr args)
79 while (!nil_p(args)) {
80 if (args.type != EXPR_CONS) {
81 return eval_failure("Expected cons", clone_expr(gc, args));
84 if (args.cons->car.type != EXPR_ATOM ||
85 args.cons->car.atom->type != ATOM_NUMBER) {
86 return eval_failure("Expected number", clone_expr(gc, args.cons->car));
89 result += args.cons->car.atom->num;
90 args = args.cons->cdr;
93 return eval_success(atom_as_expr(create_number_atom(gc, result)));
96 static struct EvalResult eval_funcall(Gc *gc, struct Expr scope, struct Cons *cons)
101 if (!symbol_p(cons->car)) {
102 return eval_failure("Expected symbol", clone_expr(gc, cons->car));
105 if (strcmp(cons->car.atom->sym, "+") == 0) {
106 struct EvalResult args = eval_args(gc, scope, cons->cdr);
110 return plus_op(gc, args.expr);
113 return eval_failure("Unknown function", clone_expr(gc, cons->car));
116 /* TODO(#317): eval does not return new scope after the evaluation */
117 struct EvalResult eval(Gc *gc, struct Expr scope, struct Expr expr)
121 return eval_atom(gc, scope, expr.atom);
124 return eval_funcall(gc, scope, expr.cons);
129 return eval_failure("Unexpected expression", clone_expr(gc, expr));
132 void print_eval_error(FILE *stream, struct EvalResult result)
134 if (!result.is_error) {
138 fprintf(stream, "%s\n", result.error);
139 print_expr_as_sexpr(result.expr);