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 length(Gc *gc, struct Expr scope, struct Expr obj)
35 return eval_failure(list(gc, 3,
36 SYMBOL(gc, "wrong-argument-type"),
49 return eval_success(NUMBER(gc, count), scope);
52 static struct EvalResult eval_atom(Gc *gc, struct Expr scope, struct Atom *atom)
60 return eval_success(atom_as_expr(atom), scope);
63 if (nil_p(atom_as_expr(atom))) {
64 return eval_success(atom_as_expr(atom), scope);
67 struct Expr value = get_scope_value(scope, atom_as_expr(atom));
70 return eval_failure(CONS(gc,
71 SYMBOL(gc, "void-variable"),
76 return eval_success(value.cons->cdr, scope);
80 return eval_failure(CONS(gc,
81 SYMBOL(gc, "unexpected-expression"),
86 static struct EvalResult eval_all_args(Gc *gc, struct Expr scope, struct Expr args)
93 return eval_atom(gc, scope, args.atom);
96 struct EvalResult car = eval(gc, scope, args.cons->car);
101 struct EvalResult cdr = eval_all_args(gc, scope, args.cons->cdr);
106 return eval_success(cons_as_expr(create_cons(gc, car.expr, cdr.expr)), scope);
112 return eval_failure(CONS(gc,
113 SYMBOL(gc, "unexpected-expression"),
118 static struct EvalResult plus_op(Gc *gc, struct Expr args, struct Expr scope)
120 long int result = 0.0f;
122 while (!nil_p(args)) {
123 if (args.type != EXPR_CONS) {
124 return eval_failure(CONS(gc,
125 SYMBOL(gc, "expected-cons"),
130 if (args.cons->car.type != EXPR_ATOM ||
131 args.cons->car.atom->type != ATOM_NUMBER) {
132 return eval_failure(CONS(gc,
133 SYMBOL(gc, "expected-number"),
138 result += args.cons->car.atom->num;
139 args = args.cons->cdr;
142 return eval_success(atom_as_expr(create_number_atom(gc, result)), scope);
145 static struct EvalResult eval_funcall(Gc *gc, struct Expr scope, struct Cons *cons)
150 if (!symbol_p(cons->car)) {
151 return eval_failure(CONS(gc,
152 SYMBOL(gc, "expected-symbol"),
157 /* TODO(#323): set builtin function is not implemented */
158 if (strcmp(cons->car.atom->sym, "+") == 0) {
159 struct EvalResult args = eval_all_args(gc, scope, cons->cdr);
163 return plus_op(gc, args.expr, scope);
164 } else if (strcmp(cons->car.atom->sym, "set") == 0) {
165 struct Expr args = cons->cdr;
166 struct EvalResult n = length(gc, scope, args);
173 if (n.expr.atom->num != 2) {
174 return eval_failure(list(gc, 3,
175 SYMBOL(gc, "wrong-number-of-arguments"),
177 NUMBER(gc, n.expr.atom->num)),
181 struct Expr name = args.cons->car;
182 if (!symbol_p(name)) {
183 return eval_failure(list(gc, 3,
184 SYMBOL(gc, "wrong-type-argument"),
185 SYMBOL(gc, "symbolp"),
190 struct EvalResult value = eval(gc, scope, args.cons->cdr.cons->car);
191 if (value.is_error) {
196 return eval_success(value.expr, set_scope_value(gc, scope, name, value.expr));
199 return eval_failure(CONS(gc,
200 SYMBOL(gc, "unknown-function"),
205 struct EvalResult eval(Gc *gc, struct Expr scope, struct Expr expr)
209 return eval_atom(gc, scope, expr.atom);
212 return eval_funcall(gc, scope, expr.cons);
217 return eval_failure(CONS(gc,
218 SYMBOL(gc, "unexpected-expression"),