Sexpr* apply_builtin(Sexpr* func, Sexpr* arg, Sexpr* env);
Sexpr* eval(Sexpr* s, Sexpr* dict) {
- //printf("s: %s\n", sprint_sexpr(s));
+ /* char* out = sprint_sexpr(s);
+ printf("s: %s\n", out);
+ free(out); /**/
+ // okay.. important to note,
+ // this needs to free s
+ // (I think)
+ // that makes the most sense at this point
+
+
// non-null s
// generally assumes that a sexpr passed to this is well-formed (ie no inapt NULLS)
// question: does a completed builtin get evaluated here?
Sexpr* lookedup = lookup(dict, s);
if(lookedup->type == NIL) {
printf("%s not defined\n", s->value.s);
+ sexpr_free(s);
return lookedup;
}
- return car(lookedup);
+ sexpr_free(s);
+ Sexpr* lookedupcar = clone(car(lookedup));
+ sexpr_free(lookedup);
+ return lookedupcar;
}
if(s->type != CONS) {
return s;
} // from now on: type is cons
Sexpr* curr = s;
while(curr->type == CONS) {
- if(cdr(curr)->type == NIL) // this is okay to keep, yeah
- return eval(car(curr), dict);
- if(cdr(curr)->type != CONS)
+ if(cdr(curr)->type == NIL) { // this is okay to keep, yeah
+ Sexpr* endeval = eval(clone(car(curr)), dict);
+ sexpr_free(curr);
+ return endeval;
+ }
+ if(cdr(curr)->type != CONS) {
// need to redo, how do i eval "(f . x)" ?
// ^ easy, just return (f . x)
return curr;
+ }
// now i need to apply actually
//Sexpr* arg = car(cdr(curr));
- Sexpr* rest = cdr(curr);
- Sexpr* func = eval(car(curr), dict);
- //Sexpr* newcar = apply_builtin(func, arg, dict);
- //Sexpr* newcdr = cdr(cdr(curr));
+ Sexpr* rest = clone(cdr(curr));
+ // wait, where does rest get freed?
+ Sexpr* func = eval(clone(car(curr)), dict);
+ sexpr_free(curr);
curr = apply_builtin(func, rest, dict); // is this ok?
- //curr = cons(newcar, newcdr);
+ //sexpr_free(rest);
+ sexpr_free(func);
}
return curr;
}
+Sexpr* eval2(Sexpr* s, Sexpr* env) {
+ if(s == NULL) return NULL;
+ if(s->type == SYM) {
+ Sexpr* lookedup = lookup(env, s);
+ if(lookedup->type == NIL) {
+ printf("%s not defined", s->value.s);
+ sexpr_free(s);
+ return lookedup;
+ }
+ sexpr_free(s);
+ Sexpr* lookedupval = clone(car(lookedup));
+ sexpr_free(lookedup);
+ return lookedupval;
+ }
+ if(s->type != CONS) {
+ return s;
+ } // s must be a cons cell now
+ Sexpr* curr = s;
+ while(curr->type == CONS) {
+ if(cdr(curr)->type == NIL)
+ return eval(car(curr), env);
+ }
+
+
+}
+
Sexpr* apply_builtin(Sexpr* func, Sexpr* rest, Sexpr* env) {
if(func->type != BUILTIN) {
printf("uh oh\n");
Sexpr* ret = malloc(sizeof(Sexpr));
ret->type = BUILTIN;
ret->value.b.opcode = func->value.b.opcode;
- ret->value.b.args = cons(car(rest), func->value.b.args);
-
- return dispatch(ret, cdr(rest), env);
+ ret->value.b.args = cons(clone(car(rest)), clone(func->value.b.args));
+ Sexpr* cdrrest = clone(cdr(rest));
+ sexpr_free(rest);
+ return dispatch(ret, cdrrest, env);
// applies if correct no of args, just returns self otherwise
}
Sexpr* env = init_dict();
load_env(env);
- Sexpr* parsed = parse("(cons 1 2)");
- Sexpr* val = eval(car(parsed), env);
- char* out = sprint_sexpr(val);
+ Sexpr* x1 = from_uint(45);
+ Sexpr* x2 = from_sym("+");
+ //Sexpr* cc = cons(x1, x2);
+ Sexpr* e = eval(x1, env);
+ char* out = sprint_sexpr(e);
+ printf("e: %s\n", out);
+ free(out);
+ sexpr_free(e);
+ //sexpr_free(x1);
+ e = eval(x2, env);
+ out = sprint_sexpr(e);
+ printf("e: %s\n", out);
+ free(out);
+ sexpr_free(e);
+
+
+ //Sexpr* parsed = parse("(cons 1 (cons 2 nil))");
+ Sexpr* parsed = parse("(quote abcd)");
+ Sexpr* val = eval(clone(car(parsed)), env);
+ out = sprint_sexpr(val);
printf(" - %s\n", out);
free(out);
- sexpr_free(val);
- printf("uh\n");
+ out = sprint_sexpr(parsed);
+ printf("idk %s\n", out);
+ free(out);
sexpr_free(parsed);
+ printf("uh\n");
+ sexpr_free(val);
printf("um\n");
-
sexpr_free(env);
}