return cons(b, rest);
        // big problem: need to rewrite to wiggle around quotes
        Sexpr* args = b->value.b.args;
-       Sexpr* _cdr = eval(car(args), env);
+       Sexpr* raw_cdr = eval(clone(car(args)), env);
+       Sexpr* _cdr = raw_cdr;
        if(_cdr->type == QUOTE)
                _cdr = _cdr->value.q;
-       Sexpr* _car = eval(car(cdr(args)), env);
+       Sexpr* raw_car = eval(clone(car(cdr(args))), env);
+       Sexpr* _car = raw_car;
        if(_car->type == QUOTE)
                _car = _car->value.q;
-       return cons(from_quote(cons(_car, _cdr)), rest);
+       Sexpr* ret = cons(from_quote(cons(clone(_car),clone(_cdr))), rest);
+       //return cons(from_quote(cons(_car, _cdr)), rest);
+       sexpr_free(raw_car);
+       sexpr_free(raw_cdr);
+       sexpr_free(b);
+       return ret;
 }
 Sexpr* c_car(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(CORE_CAR_ARGS != u64_get_num_args(b))
                return cons(b, rest);
        Sexpr* args = b->value.b.args;
-       Sexpr* arg = unquote(eval(car(args), env));
-       return cons(from_quote(car(arg)), rest);
+       Sexpr* unqargev = eval(clone(car(args)), env);
+       Sexpr* ret = cons(from_quote(clone(car(unquote(unqargev)))), rest);
+       sexpr_free(unqargev);
+       sexpr_free(b);
+       return ret;
 }
 Sexpr* c_cdr(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(CORE_CDR_ARGS != u64_get_num_args(b))
                return cons(b, rest);
        Sexpr* args = b->value.b.args;
-       Sexpr* arg = unquote(eval(car(args), env));
-       return cons(from_quote(cdr(arg)), rest);
+       Sexpr* unqargev = eval(clone(car(args)), env);
+       Sexpr* ret = cons(from_quote(clone(cdr(unquote(unqargev)))), rest);
+       //Sexpr* arg = unquote(eval(car(args), env));
+       //return cons(from_quote(cdr(arg)), rest);
+       sexpr_free(unqargev);
+       sexpr_free(b);
+       return ret;
 }
 Sexpr* c_if(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(CORE_IF_ARGS != u64_get_num_args(b))
                return cons(b, rest);
        Sexpr* args = b->value.b.args;
        
-       Sexpr* falsy = car(args);
-       Sexpr* truthy = car(cdr(args));
-       Sexpr* cond = car(cdr(cdr(args)));
-       if(unquote(eval(cond, env))->type != NIL)
+       //Sexpr* falsy = car(args);
+       //Sexpr* truthy = car(cdr(args));
+       Sexpr* cond = eval(clone(car(cdr(cdr(args)))), env);
+       if(unquote(cond)->type != NIL) {
+               Sexpr* truthy = clone(car(cdr(args)));
+               sexpr_free(cond);
+               sexpr_free(b);
                return cons(truthy, rest);
-       else
+       }
+       else {
+               Sexpr* falsy = clone(car(args));
+               sexpr_free(cond);
+               sexpr_free(b);
                return cons(falsy, rest);
+       }
 }
 Sexpr* c_eq(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(CORE_EQ_ARGS != u64_get_num_args(b))
                return cons(b, rest);
        Sexpr* args = b->value.b.args;
        // yeah eval is kinda necessary for this one I'd say
-       Sexpr* lh = unquote(eval(car(args), env));
-       Sexpr* rh = unquote(eval(car(cdr(args)), env));
-
-       if(equal(lh, rh)->type == T)
+       Sexpr* lh = eval(clone(car(args)), env);
+       Sexpr* rh = eval(clone(car(cdr(args))), env);
+       Sexpr* eq_b = equal(unquote(lh), unquote(rh));
+       bool equality = eq_b->type == T;
+       sexpr_free(eq_b);
+       sexpr_free(lh);
+       sexpr_free(rh);
+       sexpr_free(b);
+       if(equality)
                return cons(from_t(), rest);
        return cons(from_nil(), rest);
 }
                return cons(b, rest);
        Sexpr* args = b->value.b.args;
        // I guess I would need the eval to check if eventually is nil
-       if(unquote(eval(car(args), env))->type == NIL)
+       Sexpr* crux = eval(clone(car(args)), env);
+       bool isnil = unquote(crux)->type == NIL;
+       sexpr_free(crux);
+       sexpr_free(b);
+       if(isnil)
                return cons(from_t(), rest);
        return cons(from_nil(), rest);
 }
        if(CORE_ATOM_ARGS != u64_get_num_args(b))
                return cons(b, rest);
        Sexpr* args = b->value.b.args;
-       Sexpr* argeval = eval(car(args), env);
+       Sexpr* argevalhead = eval(clone(car(args)), env);
+       Sexpr* argeval = argevalhead;
        while(argeval->type == QUOTE) {
                argeval = argeval->value.q;
        }
        if(argeval->type != CONS) {
+               sexpr_free(argevalhead);
+               sexpr_free(b);
                return cons(from_t(), rest);
        }
+       sexpr_free(argevalhead);
+       sexpr_free(b);
        return cons(from_nil(), rest);
 }
 
        if(CORE_DEF_ARGS != u64_get_num_args(b))
                return cons(b, rest);
        Sexpr* args = b->value.b.args;
-       Sexpr* val = eval(car(args), env);
-       Sexpr* key = car(cdr(args));
+       Sexpr* val = eval(clone(car(args)), env);
+       Sexpr* key = clone(car(cdr(args)));
        append_to_dict(env, key, val);
+       sexpr_free(key);
+       sexpr_free(b);
        return cons(val, rest);
 }
 Sexpr* c_exit(Sexpr* b, Sexpr* rest, Sexpr* env) {