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)
50 return eval_success(atom_as_expr(atom));
53 if (nil_p(atom_as_expr(atom))) {
54 return eval_success(atom_as_expr(atom));
57 struct Expr value = get_scope_value(scope, atom_as_expr(atom));
60 return eval_failure(CONS(gc,
61 SYMBOL(gc, "void-variable"),
65 return eval_success(value.cons->cdr);
69 return eval_failure(CONS(gc,
70 SYMBOL(gc, "unexpected-expression"),
74 static struct EvalResult eval_all_args(Gc *gc, struct Scope *scope, struct Expr args)
81 return eval_atom(gc, scope, args.atom);
84 struct EvalResult car = eval(gc, scope, args.cons->car);
89 struct EvalResult cdr = eval_all_args(gc, scope, args.cons->cdr);
94 return eval_success(cons_as_expr(create_cons(gc, car.expr, cdr.expr)));
100 return eval_failure(CONS(gc,
101 SYMBOL(gc, "unexpected-expression"),
105 static struct EvalResult plus_op(Gc *gc, struct Expr args)
107 long int result = 0.0f;
109 while (!nil_p(args)) {
110 if (args.type != EXPR_CONS) {
111 return eval_failure(CONS(gc,
112 SYMBOL(gc, "expected-cons"),
116 if (args.cons->car.type != EXPR_ATOM ||
117 args.cons->car.atom->type != ATOM_NUMBER) {
118 return eval_failure(CONS(gc,
119 SYMBOL(gc, "expected-number"),
123 result += args.cons->car.atom->num;
124 args = args.cons->cdr;
127 return eval_success(atom_as_expr(create_number_atom(gc, result)));
130 static struct EvalResult call_callable(Gc *gc,
132 struct Expr callable,
134 if (!callable_p(callable)) {
135 return eval_failure(CONS(gc,
136 SYMBOL(gc, "expected-callable"),
141 return eval_failure(CONS(gc,
142 SYMBOL(gc, "expected-list"),
146 struct Expr vars = callable.cons->cdr.cons->car;
148 if (length_of_list(args) != length_of_list(vars)) {
149 return eval_failure(CONS(gc,
150 SYMBOL(gc, "wrong-number-of-arguments"),
151 NUMBER(gc, length_of_list(args))));
154 push_scope_frame(gc, scope, vars, args);
155 struct Expr body = callable.cons->cdr.cons->cdr;
157 struct EvalResult result = eval_success(NIL(gc));
159 while (!nil_p(body)) {
160 print_expr_as_sexpr(body.cons->car);
161 result = eval(gc, scope, body.cons->car);
162 if (result.is_error) {
165 body = body.cons->cdr;
168 pop_scope_frame(gc, scope);
173 static struct EvalResult eval_funcall(Gc *gc, struct Scope *scope, struct Cons *cons)
178 if (symbol_p(cons->car)) {
179 if (strcmp(cons->car.atom->sym, "+") == 0) {
180 struct EvalResult args = eval_all_args(gc, scope, cons->cdr);
184 return plus_op(gc, args.expr);
185 } else if (strcmp(cons->car.atom->sym, "set") == 0) {
186 struct Expr args = cons->cdr;
187 struct EvalResult n = length(gc, args);
193 if (n.expr.atom->num != 2) {
194 return eval_failure(list(gc, 3,
195 SYMBOL(gc, "wrong-number-of-arguments"),
197 NUMBER(gc, n.expr.atom->num)));
200 struct Expr name = args.cons->car;
201 if (!symbol_p(name)) {
202 return eval_failure(list(gc, 3,
203 SYMBOL(gc, "wrong-type-argument"),
204 SYMBOL(gc, "symbolp"),
208 struct EvalResult value = eval(gc, scope, args.cons->cdr.cons->car);
209 if (value.is_error) {
213 set_scope_value(gc, scope, name, value.expr);
215 return eval_success(value.expr);
216 } else if (strcmp(cons->car.atom->sym, "quote") == 0) {
217 /* TODO: quote does not check the amout of it's arguments */
218 return eval_success(cons->cdr.cons->car);
219 } else if (strcmp(cons->car.atom->sym, "lambda") == 0) {
220 return eval_success(cons_as_expr(cons));
222 struct EvalResult r = eval_all_args(gc, scope, cons_as_expr(cons));
228 if (!callable_p(r.expr.cons->car)) {
229 return eval_failure(CONS(gc,
230 SYMBOL(gc, "not-callable"),
234 return call_callable(gc, scope, r.expr.cons->car, r.expr.cons->cdr);
236 } else if (callable_p(cons->car)) {
237 /* TODO: Call cons->car */
240 return eval_failure(CONS(gc,
241 SYMBOL(gc, "unknown-function"),
245 struct EvalResult eval(Gc *gc, struct Scope *scope, struct Expr expr)
249 return eval_atom(gc, scope, expr.atom);
252 return eval_funcall(gc, scope, expr.cons);
257 return eval_failure(CONS(gc,
258 SYMBOL(gc, "unexpected-expression"),