5 #include "./builtins.h"
7 #include "./interpreter.h"
10 struct EvalResult eval_success(struct Expr expr)
12 struct EvalResult result = {
20 struct EvalResult eval_failure(struct Expr error)
22 struct EvalResult result = {
30 static struct EvalResult length(Gc *gc, struct Expr obj)
33 return eval_failure(list(gc, 3,
34 SYMBOL(gc, "wrong-argument-type"),
39 return eval_success(NUMBER(gc, length_of_list(obj)));
42 static struct EvalResult eval_atom(Gc *gc, struct Scope *scope, struct Atom *atom)
51 return eval_success(atom_as_expr(atom));
54 if (nil_p(atom_as_expr(atom))) {
55 return eval_success(atom_as_expr(atom));
58 struct Expr value = get_scope_value(scope, atom_as_expr(atom));
61 return eval_failure(CONS(gc,
62 SYMBOL(gc, "void-variable"),
66 return eval_success(value.cons->cdr);
70 return eval_failure(CONS(gc,
71 SYMBOL(gc, "unexpected-expression"),
75 static struct EvalResult eval_all_args(Gc *gc, struct Scope *scope, struct Expr args)
82 return eval_atom(gc, scope, args.atom);
85 struct EvalResult car = eval(gc, scope, args.cons->car);
90 struct EvalResult cdr = eval_all_args(gc, scope, args.cons->cdr);
95 return eval_success(cons_as_expr(create_cons(gc, car.expr, cdr.expr)));
101 return eval_failure(CONS(gc,
102 SYMBOL(gc, "unexpected-expression"),
106 static struct EvalResult plus_op(Gc *gc, struct Expr args)
108 long int result = 0.0f;
110 while (!nil_p(args)) {
111 if (args.type != EXPR_CONS) {
112 return eval_failure(CONS(gc,
113 SYMBOL(gc, "expected-cons"),
117 if (args.cons->car.type != EXPR_ATOM ||
118 args.cons->car.atom->type != ATOM_NUMBER) {
119 return eval_failure(CONS(gc,
120 SYMBOL(gc, "expected-number"),
124 result += args.cons->car.atom->num;
125 args = args.cons->cdr;
128 return eval_success(atom_as_expr(create_number_atom(gc, result)));
131 static struct EvalResult call_callable(Gc *gc,
133 struct Expr callable,
135 if (!callable_p(callable)) {
136 return eval_failure(CONS(gc,
137 SYMBOL(gc, "expected-callable"),
142 return eval_failure(CONS(gc,
143 SYMBOL(gc, "expected-list"),
147 struct Expr vars = callable.cons->cdr.cons->car;
149 if (length_of_list(args) != length_of_list(vars)) {
150 return eval_failure(CONS(gc,
151 SYMBOL(gc, "wrong-number-of-arguments"),
152 NUMBER(gc, length_of_list(args))));
155 push_scope_frame(gc, scope, vars, args);
156 struct Expr body = callable.cons->cdr.cons->cdr;
158 struct EvalResult result = eval_success(NIL(gc));
160 while (!nil_p(body)) {
161 print_expr_as_sexpr(body.cons->car);
162 result = eval(gc, scope, body.cons->car);
163 if (result.is_error) {
166 body = body.cons->cdr;
169 pop_scope_frame(gc, scope);
174 static struct EvalResult eval_funcall(Gc *gc, struct Scope *scope, struct Cons *cons)
179 if (symbol_p(cons->car)) {
180 if (strcmp(cons->car.atom->sym, "+") == 0) {
181 struct EvalResult args = eval_all_args(gc, scope, cons->cdr);
185 return plus_op(gc, args.expr);
186 } else if (strcmp(cons->car.atom->sym, "set") == 0) {
187 struct Expr args = cons->cdr;
188 struct EvalResult n = length(gc, args);
194 if (n.expr.atom->num != 2) {
195 return eval_failure(list(gc, 3,
196 SYMBOL(gc, "wrong-number-of-arguments"),
198 NUMBER(gc, n.expr.atom->num)));
201 struct Expr name = args.cons->car;
202 if (!symbol_p(name)) {
203 return eval_failure(list(gc, 3,
204 SYMBOL(gc, "wrong-type-argument"),
205 SYMBOL(gc, "symbolp"),
209 struct EvalResult value = eval(gc, scope, args.cons->cdr.cons->car);
210 if (value.is_error) {
214 set_scope_value(gc, scope, name, value.expr);
216 return eval_success(value.expr);
217 } else if (strcmp(cons->car.atom->sym, "quote") == 0) {
218 /* TODO(#334): quote does not check the amout of it's arguments */
219 return eval_success(cons->cdr.cons->car);
220 } else if (strcmp(cons->car.atom->sym, "lambda") == 0) {
221 /* TODO(#335): lambda special form doesn't check if it forms a callable object */
222 return eval_success(cons_as_expr(cons));
226 struct EvalResult r = eval_all_args(gc, scope, cons_as_expr(cons));
232 return call_callable(gc, scope, r.expr.cons->car, r.expr.cons->cdr);
235 struct EvalResult eval(Gc *gc, struct Scope *scope, struct Expr expr)
239 return eval_atom(gc, scope, expr.atom);
242 return eval_funcall(gc, scope, expr.cons);
247 return eval_failure(CONS(gc,
248 SYMBOL(gc, "unexpected-expression"),