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"),
46 return eval_success(NUMBER(gc, count));
49 static struct EvalResult eval_atom(Gc *gc, struct Scope *scope, struct Atom *atom)
57 return eval_success(atom_as_expr(atom));
60 if (nil_p(atom_as_expr(atom))) {
61 return eval_success(atom_as_expr(atom));
64 struct Expr value = get_scope_value(scope, atom_as_expr(atom));
67 return eval_failure(CONS(gc,
68 SYMBOL(gc, "void-variable"),
72 return eval_success(value.cons->cdr);
76 return eval_failure(CONS(gc,
77 SYMBOL(gc, "unexpected-expression"),
81 static struct EvalResult eval_all_args(Gc *gc, struct Scope *scope, struct Expr args)
88 return eval_atom(gc, scope, args.atom);
91 struct EvalResult car = eval(gc, scope, args.cons->car);
96 struct EvalResult cdr = eval_all_args(gc, scope, args.cons->cdr);
101 return eval_success(cons_as_expr(create_cons(gc, car.expr, cdr.expr)));
107 return eval_failure(CONS(gc,
108 SYMBOL(gc, "unexpected-expression"),
112 static struct EvalResult plus_op(Gc *gc, struct Expr args)
114 long int result = 0.0f;
116 while (!nil_p(args)) {
117 if (args.type != EXPR_CONS) {
118 return eval_failure(CONS(gc,
119 SYMBOL(gc, "expected-cons"),
123 if (args.cons->car.type != EXPR_ATOM ||
124 args.cons->car.atom->type != ATOM_NUMBER) {
125 return eval_failure(CONS(gc,
126 SYMBOL(gc, "expected-number"),
130 result += args.cons->car.atom->num;
131 args = args.cons->cdr;
134 return eval_success(atom_as_expr(create_number_atom(gc, result)));
137 static struct EvalResult eval_funcall(Gc *gc, struct Scope *scope, struct Cons *cons)
142 if (!symbol_p(cons->car)) {
143 return eval_failure(CONS(gc,
144 SYMBOL(gc, "expected-symbol"),
148 /* TODO(#323): set builtin function is not implemented */
149 if (strcmp(cons->car.atom->sym, "+") == 0) {
150 struct EvalResult args = eval_all_args(gc, scope, cons->cdr);
154 return plus_op(gc, args.expr);
155 } else if (strcmp(cons->car.atom->sym, "set") == 0) {
156 struct Expr args = cons->cdr;
157 struct EvalResult n = length(gc, args);
163 if (n.expr.atom->num != 2) {
164 return eval_failure(list(gc, 3,
165 SYMBOL(gc, "wrong-number-of-arguments"),
167 NUMBER(gc, n.expr.atom->num)));
170 struct Expr name = args.cons->car;
171 if (!symbol_p(name)) {
172 return eval_failure(list(gc, 3,
173 SYMBOL(gc, "wrong-type-argument"),
174 SYMBOL(gc, "symbolp"),
178 struct EvalResult value = eval(gc, scope, args.cons->cdr.cons->car);
179 if (value.is_error) {
183 set_scope_value(gc, scope, name, value.expr);
185 return eval_success(value.expr);
188 return eval_failure(CONS(gc,
189 SYMBOL(gc, "unknown-function"),
193 struct EvalResult eval(Gc *gc, struct Scope *scope, struct Expr expr)
197 return eval_atom(gc, scope, expr.atom);
200 return eval_funcall(gc, scope, expr.cons);
205 return eval_failure(CONS(gc,
206 SYMBOL(gc, "unexpected-expression"),