5 #include "./builtins.h"
7 #include "./interpreter.h"
10 struct EvalResult eval_success(struct Expr expr, struct Expr scope)
12 struct EvalResult result = {
21 struct EvalResult eval_failure(struct Expr error, struct Expr scope)
23 struct EvalResult result = {
32 static struct EvalResult eval_atom(Gc *gc, struct Expr scope, struct Atom *atom)
37 /* TODO(#314): Evaluating symbols is not implemented */
42 return eval_success(atom_as_expr(atom), scope);
45 return eval_failure(CONS(gc,
46 SYMBOL(gc, "unexpected-expression"),
51 static struct EvalResult eval_args(Gc *gc, struct Expr scope, struct Expr args)
58 return eval_atom(gc, scope, args.atom);
61 struct EvalResult car = eval(gc, scope, args.cons->car);
66 struct EvalResult cdr = eval_args(gc, scope, args.cons->cdr);
71 return eval_success(cons_as_expr(create_cons(gc, car.expr, cdr.expr)), scope);
77 return eval_failure(CONS(gc,
78 SYMBOL(gc, "unexpected-expression"),
83 static struct EvalResult plus_op(Gc *gc, struct Expr args, struct Expr scope)
87 while (!nil_p(args)) {
88 if (args.type != EXPR_CONS) {
89 return eval_failure(CONS(gc,
90 SYMBOL(gc, "expected-cons"),
95 if (args.cons->car.type != EXPR_ATOM ||
96 args.cons->car.atom->type != ATOM_NUMBER) {
97 return eval_failure(CONS(gc,
98 SYMBOL(gc, "expected-number"),
103 result += args.cons->car.atom->num;
104 args = args.cons->cdr;
107 return eval_success(atom_as_expr(create_number_atom(gc, result)), scope);
110 static struct EvalResult eval_funcall(Gc *gc, struct Expr scope, struct Cons *cons)
115 if (!symbol_p(cons->car)) {
116 return eval_failure(CONS(gc,
117 SYMBOL(gc, "expected-symbol"),
122 /* TODO(#323): set builtin function is not implemented */
123 if (strcmp(cons->car.atom->sym, "+") == 0) {
124 struct EvalResult args = eval_args(gc, scope, cons->cdr);
128 return plus_op(gc, args.expr, scope);
131 return eval_failure(CONS(gc,
132 SYMBOL(gc, "unknown-function"),
137 struct EvalResult eval(Gc *gc, struct Expr scope, struct Expr expr)
141 return eval_atom(gc, scope, expr.atom);
144 return eval_funcall(gc, scope, expr.cons);
149 return eval_failure(CONS(gc,
150 SYMBOL(gc, "unexpected-expression"),