5 #include "./builtins.h"
7 #include "./interpreter.h"
10 struct EvalResult eval_success(struct Expr expr, struct Expr scope)
12 struct EvalResult result = {
22 struct EvalResult eval_failure(const char *error, struct Expr expr, struct Expr scope)
24 struct EvalResult result = {
34 static struct EvalResult eval_atom(Gc *gc, struct Expr scope, struct Atom *atom)
39 /* TODO(#314): Evaluating symbols is not implemented */
44 return eval_success(atom_as_expr(atom), scope);
47 return eval_failure("Unexpected expression", atom_as_expr(atom), scope);
50 static struct EvalResult eval_args(Gc *gc, struct Expr scope, struct Expr args)
57 return eval_atom(gc, scope, args.atom);
60 struct EvalResult car = eval(gc, scope, args.cons->car);
65 struct EvalResult cdr = eval_args(gc, scope, args.cons->cdr);
70 return eval_success(cons_as_expr(create_cons(gc, car.expr, cdr.expr)), scope);
76 return eval_failure("Unexpected expression", args, scope);
79 static struct EvalResult plus_op(Gc *gc, struct Expr args, struct Expr scope)
83 while (!nil_p(args)) {
84 if (args.type != EXPR_CONS) {
85 return eval_failure("Expected cons", args, scope);
88 if (args.cons->car.type != EXPR_ATOM ||
89 args.cons->car.atom->type != ATOM_NUMBER) {
90 return eval_failure("Expected number", args.cons->car, scope);
93 result += args.cons->car.atom->num;
94 args = args.cons->cdr;
97 return eval_success(atom_as_expr(create_number_atom(gc, result)), scope);
100 static struct EvalResult eval_funcall(Gc *gc, struct Expr scope, struct Cons *cons)
105 if (!symbol_p(cons->car)) {
106 return eval_failure("Expected symbol", cons->car, scope);
109 /* TODO(#323): set builtin function is not implemented */
110 if (strcmp(cons->car.atom->sym, "+") == 0) {
111 struct EvalResult args = eval_args(gc, scope, cons->cdr);
115 return plus_op(gc, args.expr, scope);
118 return eval_failure("Unknown function", cons->car, scope);
121 struct EvalResult eval(Gc *gc, struct Expr scope, struct Expr expr)
125 return eval_atom(gc, scope, expr.atom);
128 return eval_funcall(gc, scope, expr.cons);
133 return eval_failure("Unexpected expression", expr, scope);
136 void print_eval_error(FILE *stream, struct EvalResult result)
138 if (!result.is_error) {
142 fprintf(stream, "%s\n", result.error);
143 print_expr_as_sexpr(result.expr);