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(struct Expr scope, struct Atom *atom)
35 /* TODO(#314): Evaluating symbols is not implemented */
40 return eval_success(clone_expr(atom_as_expr(atom)));
43 return eval_failure("Unexpected expression", clone_expr(atom_as_expr(atom)));
46 static struct EvalResult eval_args(struct Expr scope, struct Expr args)
53 return eval_atom(scope, args.atom);
56 struct EvalResult car = eval(scope, args.cons->car);
61 struct EvalResult cdr = eval_args(scope, args.cons->cdr);
63 destroy_expr(car.expr);
67 return eval_success(cons_as_expr(create_cons(car.expr, cdr.expr)));
73 return eval_failure("Unexpected expression", clone_expr(args));
76 static struct EvalResult plus_op(struct Expr args)
80 while (!nil_p(args)) {
81 if (args.type != EXPR_CONS) {
82 return eval_failure("Expected cons", clone_expr(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(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(result)));
97 static struct EvalResult eval_funcall(struct Expr scope, struct Cons *cons)
102 if (!symbol_p(cons->car)) {
103 return eval_failure("Expected symbol", clone_expr(cons->car));
106 if (strcmp(cons->car.atom->sym, "+") == 0) {
107 struct EvalResult args = eval_args(scope, cons->cdr);
111 return plus_op(args.expr);
114 return eval_failure("Unknown function", clone_expr(cons->car));
117 /* TODO(#317): eval does not return new scope after the evaluation */
118 struct EvalResult eval(struct Expr scope, struct Expr expr)
122 return eval_atom(scope, expr.atom);
125 return eval_funcall(scope, expr.cons);
130 return eval_failure("Unexpected expression", clone_expr(expr));
133 void print_eval_error(FILE *stream, struct EvalResult result)
135 if (!result.is_error) {
139 fprintf(stream, "%s\n", result.error);
140 print_expr_as_sexpr(result.expr);