+GARBAGE COLLECTION
+my grand design is that I will allocate and deallocate all the time, that is, if I 'def' something I keep it, but dereferencing something clones the thing, and then any call using it frees it again.
+is that too slow? yeah probably
 
+---
 
 okay current problem is figuring out the right way to do 'quote'... I think I just need a special thing in my sexpr typedef for a quoted form.. should be easy enough
 
 ALL THE PLACES WHERE I NEED TO GO THROUGH ALL THE TYPES:
 sprint_sexpr
 eval
+clone
+free
 
 is that it?
 
 
        if(CORE_CONS_ARGS != u64_get_num_args(b))
                return b;
        Sexpr* args = b->value.b.args;
-       Sexpr* _cdr = car(args);
-       Sexpr* _car = car(cdr(args));
+       Sexpr* _cdr = eval(car(args), env);
+       Sexpr* _car = eval(car(cdr(args)), env);
        return cons(_car, _cdr);
 }
 Sexpr* c_car(Sexpr* b, Sexpr* env) {
 
        Sexpr* curr = s;
        while(curr->type == CONS) {
                if(cdr(curr)->type == NIL)
-                       //return eval(car(curr), dict);
-                       return car(curr);
+                       return eval(car(curr), dict);
                if(cdr(curr)->type != CONS)
                        // need to redo, how do i eval "(f . x)" ?
                        // ^ easy, just return (f . x)
 
        return from_nil();
 }
 
+void sexpr_free(Sexpr* s) {
+       if(s->type == CONS) {
+               sexpr_free(car(s));
+               sexpr_free(cdr(s));
+       }
+       if(s->type ==QUOTE) {
+               sexpr_free(s->value.q);
+       }
+       if(s->type == BUILTIN) {
+               sexpr_free(s->value.b.args);
+       }
+       if(s->type == SYM) {
+               free(s->value.s);
+       }
+       free(s);
+}
+
+Sexpr* clone(Sexpr* s) {
+       Sexpr* ret;
+       switch(s->type) {
+       case UINT:
+               ret = from_uint(s->value.u);
+               break;
+       case SYM:
+               ret = from_sym(strdup(s->value.s));
+               break;
+       case BUILTIN:
+               ret = from_opcode(s->value.b.opcode);
+               sexpr_free(ret->value.b.args);
+               ret->value.b.args = clone(s->value.b.args);
+               break;
+       case T:
+               ret = from_t();
+               break;
+       case CONS:
+               ret = cons(clone(car(s)), clone(cdr(s)));
+               break;
+       case QUOTE:
+               ret = from_quote(clone(s->value.q));
+               break;
+       case NIL:
+       default:
+               ret = from_nil();
+               break;
+       }
+       return ret;
+}
 
 
 Sexpr* reverse(Sexpr* s) {
 
 Sexpr* from_uint(uint64_t u);
 Sexpr* from_opcode(uint64_t u);
 Sexpr* from_quote(Sexpr* s);
-       
+
+void sexpr_free(Sexpr* s);
+Sexpr* clone(Sexpr* s);
+
 Sexpr* cons(Sexpr* car, Sexpr* cdr);
 Sexpr* car(Sexpr* s);
 Sexpr* cdr(Sexpr* s);