@@ -105,7 +105,8 @@ function evalc(env c) {
105105}
106106
107107sexp eval(env c, sexp e) {
108- if (intp(e)) return e;
108+ write("EVAL: " + to_string(e) + "\n" );
109+ if (intp(e) || floatp(e)) return e;
109110 else if (stringp(e)) return env_lookup(c, e);
110111 else if (equal(e, ({}) )) return e;
111112 else if (arrayp(e)) {
@@ -153,6 +154,8 @@ sexp eval(env c, sexp e) {
153154 sexp val = eval(c, tail[1 ]);
154155 set_env(c, tail[0 ], val);
155156 return val;
157+ case "cond" :
158+ return do_cond(c, tail);
156159 default:
157160 function f = eval(c, head);
158161 array args = map(tail, evalc(c));
@@ -163,6 +166,16 @@ sexp eval(env c, sexp e) {
163166 }
164167}
165168
169+ sexp do_cond(env c, array clauses) {
170+ if (sizeof(clauses) == 0 ) return ({});
171+ sexp clause = clauses[0 ];
172+ if (!arrayp(clause) || sizeof(clause) == 0 ) die("Clause of cond must be list: " , clause);
173+ sexp truth = eval(c, clause[0 ]);
174+ if (equal(truth, ({}))) return do_cond(c, clauses[1 ..]);
175+ if (sizeof(clause) == 1 ) return truth;
176+ return eval(c, ({ "progn" }) + clause[1 ..]);
177+ }
178+
166179sexp do_car(array arg) {
167180 if (sizeof(arg) != 1 ) die("Car given wrong number of args: " , arg);
168181 sexp x = arg[0 ];
@@ -219,14 +232,41 @@ sexp do_times(array arg) {
219232 return result;
220233}
221234
235+ sexp do_eq(array arg) {
236+ if (sizeof(arg) != 2 ) die("Call to eq with other than two arguments: " , arg);
237+ return equal(arg[0 ], arg[1 ]);
238+ }
239+
222240void init_prims() {
223241 global_env["car" ] = do_car;
224242 global_env["cdr" ] = do_cdr;
225243 global_env["cons" ] = do_cons;
244+ global_env["eq" ] = do_eq;
226245 global_env["+" ] = do_plus;
227246 global_env["-" ] = do_minus;
228247 global_env["*" ] = do_times;
229248}
230249
231250void main() {
251+ init_prims();
252+
253+ sexp factorial =
254+ ({ "progn" ,
255+ ({ "define" , ({ "fact" , "n" }),
256+ ({ "cond" ,
257+ ({ ({ "eq" , "n" , 0 }), 1 }),
258+ ({ 1 , ({ "*" , "n" , ({ "fact" , ({ "-" , "n" , 1 }) }) }) }) }) }),
259+ ({ "fact" , 5 }) });
260+ write(to_string(eval(env(), factorial)) + "\n" );
232261}
262+
263+ /* Sample program: factorial
264+
265+ (progn
266+ (define (fact n)
267+ (cond
268+ ((eq n 0) 1)
269+ ((quote otherwise) ( * n (fact (- n 1))))))
270+ (fact 5))
271+
272+ */
0 commit comments