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 eval_funcall(Gc *gc, struct Scope *scope, struct Cons *cons)
135 if (!symbol_p(cons->car)) {
136 return eval_failure(CONS(gc,
137 SYMBOL(gc, "expected-symbol"),
141 /* TODO(#323): set builtin function is not implemented */
142 if (strcmp(cons->car.atom->sym, "+") == 0) {
143 struct EvalResult args = eval_all_args(gc, scope, cons->cdr);
147 return plus_op(gc, args.expr);
148 } else if (strcmp(cons->car.atom->sym, "set") == 0) {
149 struct Expr args = cons->cdr;
150 struct EvalResult n = length(gc, args);
156 if (n.expr.atom->num != 2) {
157 return eval_failure(list(gc, 3,
158 SYMBOL(gc, "wrong-number-of-arguments"),
160 NUMBER(gc, n.expr.atom->num)));
163 struct Expr name = args.cons->car;
164 if (!symbol_p(name)) {
165 return eval_failure(list(gc, 3,
166 SYMBOL(gc, "wrong-type-argument"),
167 SYMBOL(gc, "symbolp"),
171 struct EvalResult value = eval(gc, scope, args.cons->cdr.cons->car);
172 if (value.is_error) {
176 set_scope_value(gc, scope, name, value.expr);
178 return eval_success(value.expr);
181 return eval_failure(CONS(gc,
182 SYMBOL(gc, "unknown-function"),
186 struct EvalResult eval(Gc *gc, struct Scope *scope, struct Expr expr)
190 return eval_atom(gc, scope, expr.atom);
193 return eval_funcall(gc, scope, expr.cons);
198 return eval_failure(CONS(gc,
199 SYMBOL(gc, "unexpected-expression"),