]> git.eli173.com Git - klapaucius/commitdiff
reworking towards full proper reference counting implementation main
authorElijah Cohen <cohen@eli173.com>
Fri, 19 Sep 2025 06:47:32 +0000 (06:47 +0000)
committerElijah Cohen <cohen@eli173.com>
Fri, 19 Sep 2025 06:47:32 +0000 (06:47 +0000)
src/builtins/arithmetic.c
src/builtins/combinators.c
src/builtins/core.c
src/builtins/io.c
src/builtins/meta.c
src/builtins/strings.c
src/sexpr.c
src/sexpr.h
src/test.c

index 1fb7f60d7278bf1517b6e69dc830f78d9bf48fcd..89e716ac3d8f67bfbc4fc21cecc87ff5868a96cd 100644 (file)
@@ -16,22 +16,22 @@ Sexpr* a_plus(Sexpr* b, Sexpr* rest, Sexpr* env) {
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
-       Sexpr* i = eval(clone(car(args)), env);
-       Sexpr* j = eval(clone(car(cdr(args))), env);
+       Sexpr* i = eval(add_ref(car(args)), env);
+       Sexpr* j = eval(add_ref(car(cdr(args))), env);
 #ifdef TYPECHECK
        if((unquote(i)->type != UINT) || (unquote(j)->type != UINT)) {
                ERR("+: ", "arguments not uints");
 #ifdef TYPECHECK
        if((unquote(i)->type != UINT) || (unquote(j)->type != UINT)) {
                ERR("+: ", "arguments not uints");
-               sexpr_free(b);
-               sexpr_free(i);
-               sexpr_free(j);
+               dec_ref(b);
+               dec_ref(i);
+               dec_ref(j);
                return cons(from_nil(), rest);
        }
 #endif // typecheck
        K_UINT_TYPE m = unquote(i)->value.u;
        K_UINT_TYPE n = unquote(j)->value.u;
                return cons(from_nil(), rest);
        }
 #endif // typecheck
        K_UINT_TYPE m = unquote(i)->value.u;
        K_UINT_TYPE n = unquote(j)->value.u;
-       sexpr_free(b);
-       sexpr_free(i);
-       sexpr_free(j);
+       dec_ref(b);
+       dec_ref(i);
+       dec_ref(j);
        return cons(from_uint(m + n), rest);
 }
 
        return cons(from_uint(m + n), rest);
 }
 
@@ -40,22 +40,22 @@ Sexpr* a_minus(Sexpr* b, Sexpr* rest, Sexpr* env) {
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
-       Sexpr* i = eval(clone(car(args)), env);
-       Sexpr* j = eval(clone(car(cdr(args))), env);
+       Sexpr* i = eval(add_ref(car(args)), env);
+       Sexpr* j = eval(add_ref(car(cdr(args))), env);
 #ifdef TYPECHECK
        if((unquote(i)->type != UINT) || (unquote(j)->type != UINT)) {
                ERR("-: ", "arguments not uints");
 #ifdef TYPECHECK
        if((unquote(i)->type != UINT) || (unquote(j)->type != UINT)) {
                ERR("-: ", "arguments not uints");
-               sexpr_free(b);
-               sexpr_free(i);
-               sexpr_free(j);
+               dec_ref(b);
+               dec_ref(i);
+               dec_ref(j);
                return cons(from_nil(), rest);
        }
 #endif // typecheck
        K_UINT_TYPE m = unquote(i)->value.u;
        K_UINT_TYPE n = unquote(j)->value.u;
                return cons(from_nil(), rest);
        }
 #endif // typecheck
        K_UINT_TYPE m = unquote(i)->value.u;
        K_UINT_TYPE n = unquote(j)->value.u;
-       sexpr_free(b);
-       sexpr_free(i);
-       sexpr_free(j);
+       dec_ref(b);
+       dec_ref(i);
+       dec_ref(j);
        return cons(from_uint(n - m), rest);
 }
 
        return cons(from_uint(n - m), rest);
 }
 
@@ -64,22 +64,22 @@ Sexpr* a_mul(Sexpr* b, Sexpr* rest, Sexpr* env) {
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
-       Sexpr* i = eval(clone(car(args)), env);
-       Sexpr* j = eval(clone(car(cdr(args))), env);
+       Sexpr* i = eval(add_ref(car(args)), env);
+       Sexpr* j = eval(add_ref(car(cdr(args))), env);
 #ifdef TYPECHECK
        if((unquote(i)->type != UINT) || (unquote(j)->type != UINT)) {
                ERR("*: ", "arguments not uints");
 #ifdef TYPECHECK
        if((unquote(i)->type != UINT) || (unquote(j)->type != UINT)) {
                ERR("*: ", "arguments not uints");
-               sexpr_free(b);
-               sexpr_free(i);
-               sexpr_free(j);
+               dec_ref(b);
+               dec_ref(i);
+               dec_ref(j);
                return cons(from_nil(), rest);
        }
 #endif // typecheck
        K_UINT_TYPE m = unquote(i)->value.u;
        K_UINT_TYPE n = unquote(j)->value.u;
                return cons(from_nil(), rest);
        }
 #endif // typecheck
        K_UINT_TYPE m = unquote(i)->value.u;
        K_UINT_TYPE n = unquote(j)->value.u;
-       sexpr_free(b);
-       sexpr_free(i);
-       sexpr_free(j);
+       dec_ref(b);
+       dec_ref(i);
+       dec_ref(j);
        return cons(from_uint(m * n), rest);
 }
 
        return cons(from_uint(m * n), rest);
 }
 
@@ -88,22 +88,22 @@ Sexpr* a_div(Sexpr* b, Sexpr* rest, Sexpr* env) {
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
-       Sexpr* i = eval(clone(car(args)), env);
-       Sexpr* j = eval(clone(car(cdr(args))), env);
+       Sexpr* i = eval(add_ref(car(args)), env);
+       Sexpr* j = eval(add_ref(car(cdr(args))), env);
 #ifdef TYPECHECK
        if((unquote(i)->type != UINT) || (unquote(j)->type != UINT)) {
                ERR("/: ", "arguments not uints");
 #ifdef TYPECHECK
        if((unquote(i)->type != UINT) || (unquote(j)->type != UINT)) {
                ERR("/: ", "arguments not uints");
-               sexpr_free(b);
-               sexpr_free(i);
-               sexpr_free(j);
+               dec_ref(b);
+               dec_ref(i);
+               dec_ref(j);
                return cons(from_nil(), rest);
        }
 #endif // typecheck
        K_UINT_TYPE m = unquote(i)->value.u;
        K_UINT_TYPE n = unquote(j)->value.u;
                return cons(from_nil(), rest);
        }
 #endif // typecheck
        K_UINT_TYPE m = unquote(i)->value.u;
        K_UINT_TYPE n = unquote(j)->value.u;
-       sexpr_free(b);
-       sexpr_free(i);
-       sexpr_free(j);
+       dec_ref(b);
+       dec_ref(i);
+       dec_ref(j);
        return cons(from_uint(n / m), rest);
 }
 
        return cons(from_uint(n / m), rest);
 }
 
@@ -112,22 +112,22 @@ Sexpr* a_mod(Sexpr* b, Sexpr* rest, Sexpr* env) {
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
-       Sexpr* i = eval(clone(car(args)), env);
-       Sexpr* j = eval(clone(car(cdr(args))), env);
+       Sexpr* i = eval(add_ref(car(args)), env);
+       Sexpr* j = eval(add_ref(car(cdr(args))), env);
 #ifdef TYPECHECK
        if((unquote(i)->type != UINT) || (unquote(j)->type != UINT)) {
                ERR("%: ", "arguments not uints");
 #ifdef TYPECHECK
        if((unquote(i)->type != UINT) || (unquote(j)->type != UINT)) {
                ERR("%: ", "arguments not uints");
-               sexpr_free(b);
-               sexpr_free(i);
-               sexpr_free(j);
+               dec_ref(b);
+               dec_ref(i);
+               dec_ref(j);
                return cons(from_nil(), rest);
        }
 #endif // typecheck
        K_UINT_TYPE m = unquote(i)->value.u;
        K_UINT_TYPE n = unquote(j)->value.u;
                return cons(from_nil(), rest);
        }
 #endif // typecheck
        K_UINT_TYPE m = unquote(i)->value.u;
        K_UINT_TYPE n = unquote(j)->value.u;
-       sexpr_free(b);
-       sexpr_free(i);
-       sexpr_free(j);
+       dec_ref(b);
+       dec_ref(i);
+       dec_ref(j);
        return cons(from_uint(n % m), rest);
 }
 
        return cons(from_uint(n % m), rest);
 }
 
@@ -136,22 +136,22 @@ Sexpr* a_mod(Sexpr* b, Sexpr* rest, Sexpr* env) {
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
-       Sexpr* i = eval(clone(car(args)), env);
-       Sexpr* j = eval(clone(car(cdr(args))), env);
+       Sexpr* i = eval(add_ref(car(args)), env);
+       Sexpr* j = eval(add_ref(car(cdr(args))), env);
 #ifdef TYPECHECK
        if((unquote(i)->type != UINT) || (unquote(j)->type != UINT)) {
                ERR("%: ", "arguments not uints");
 #ifdef TYPECHECK
        if((unquote(i)->type != UINT) || (unquote(j)->type != UINT)) {
                ERR("%: ", "arguments not uints");
-               sexpr_free(b);
-               sexpr_free(i);
-               sexpr_free(j);
+               dec_ref(b);
+               dec_ref(i);
+               dec_ref(j);
                return cons(from_nil(), rest);
        }
 #endif
                K_UINT_TYPE m = unquote(i)->value.u;
                K_UINT_TYPE n = unquote(j)->value.u;
                return cons(from_nil(), rest);
        }
 #endif
                K_UINT_TYPE m = unquote(i)->value.u;
                K_UINT_TYPE n = unquote(j)->value.u;
-               sexpr_free(b);
-               sexpr_free(i);
-               sexpr_free(j);
+               dec_ref(b);
+               dec_ref(i);
+               dec_ref(j);
                return cons(m < n ? from_t(): from_nil(), rest);
 }
 
                return cons(m < n ? from_t(): from_nil(), rest);
 }
 
@@ -160,22 +160,22 @@ Sexpr* a_lt(Sexpr* b, Sexpr* rest, Sexpr* env) {
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
-       Sexpr* i = eval(clone(car(args)), env);
-       Sexpr* j = eval(clone(car(cdr(args))), env);
+       Sexpr* i = eval(add_ref(car(args)), env);
+       Sexpr* j = eval(add_ref(car(cdr(args))), env);
 #ifdef TYPECHECK
        if((unquote(i)->type != UINT) || (unquote(j)->type != UINT)) {
                ERR("%: ", "arguments not uints");
 #ifdef TYPECHECK
        if((unquote(i)->type != UINT) || (unquote(j)->type != UINT)) {
                ERR("%: ", "arguments not uints");
-               sexpr_free(b);
-               sexpr_free(i);
-               sexpr_free(j);
+               dec_ref(b);
+               dec_ref(i);
+               dec_ref(j);
                return cons(from_nil(), rest);
        }
 #endif
                K_UINT_TYPE m = unquote(i)->value.u;
                K_UINT_TYPE n = unquote(j)->value.u;
                return cons(from_nil(), rest);
        }
 #endif
                K_UINT_TYPE m = unquote(i)->value.u;
                K_UINT_TYPE n = unquote(j)->value.u;
-               sexpr_free(b);
-               sexpr_free(i);
-               sexpr_free(j);
+               dec_ref(b);
+               dec_ref(i);
+               dec_ref(j);
                return cons(m > n ? from_t() : from_nil(), rest);
 }
 
                return cons(m > n ? from_t() : from_nil(), rest);
 }
 
index 7a0741d1058f28c4fc3f0bfd78d184b748b33497..e773e8a066776d366ab36be2f87951f091c6ada0 100644 (file)
@@ -15,8 +15,8 @@ Sexpr* c_i(Sexpr* b, Sexpr* rest, Sexpr* env) {
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
-       Sexpr* arg = clone(car(args));
-       sexpr_free(b);
+       Sexpr* arg = add_ref(car(args));
+       dec_ref(b);
        return cons(arg, rest);
 }
 
        return cons(arg, rest);
 }
 
@@ -25,11 +25,11 @@ Sexpr* c_s(Sexpr* b, Sexpr* rest, Sexpr* env) {
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
-       Sexpr* x = clone(car(cdr(cdr(args))));
-       Sexpr* y = clone(car(cdr(args)));
-       Sexpr* z = clone(car(args));
-       Sexpr* zclone = clone(z);
-       sexpr_free(b);
+       Sexpr* x = add_ref(car(cdr(cdr(args))));
+       Sexpr* y = add_ref(car(cdr(args)));
+       Sexpr* z = add_ref(car(args));
+       Sexpr* zclone = add_ref(z);
+       dec_ref(b);
        Sexpr* ret = cons(cons(y, cons(zclone, from_nil())), rest);
        ret = cons(z, ret);
        ret = cons(x, ret);
        Sexpr* ret = cons(cons(y, cons(zclone, from_nil())), rest);
        ret = cons(z, ret);
        ret = cons(x, ret);
@@ -42,8 +42,8 @@ Sexpr* c_k(Sexpr* b, Sexpr* rest, Sexpr* env) {
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
-       Sexpr* x = clone(car(cdr(args)));
-       sexpr_free(b);
+       Sexpr* x = add_ref(car(cdr(args)));
+       dec_ref(b);
        return cons(x, rest);
 }
 
        return cons(x, rest);
 }
 
@@ -52,10 +52,10 @@ Sexpr* c_b(Sexpr* b, Sexpr* rest, Sexpr* env) {
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
-       Sexpr* x = clone(car(cdr(cdr(args))));
-       Sexpr* y = clone(car(cdr(args)));
-       Sexpr* z = clone(car(args));
-       sexpr_free(b);
+       Sexpr* x = add_ref(car(cdr(cdr(args))));
+       Sexpr* y = add_ref(car(cdr(args)));
+       Sexpr* z = add_ref(car(args));
+       dec_ref(b);
 
        Sexpr* ret = cons(x, cons(cons(y, cons(z, from_nil())), rest));
        return ret;
 
        Sexpr* ret = cons(x, cons(cons(y, cons(z, from_nil())), rest));
        return ret;
@@ -66,10 +66,10 @@ Sexpr* c_c(Sexpr* b, Sexpr* rest, Sexpr* env) {
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
-       Sexpr* x = clone(car(cdr(cdr(args))));
-       Sexpr* y = clone(car(cdr(args)));
-       Sexpr* z = clone(car(args));
-       sexpr_free(b);
+       Sexpr* x = add_ref(car(cdr(cdr(args))));
+       Sexpr* y = add_ref(car(cdr(args)));
+       Sexpr* z = add_ref(car(args));
+       dec_ref(b);
 
        Sexpr* ret = cons(x, cons(z, cons(y, rest)));
        return ret;
 
        Sexpr* ret = cons(x, cons(z, cons(y, rest)));
        return ret;
@@ -80,10 +80,10 @@ Sexpr* c_w(Sexpr* b, Sexpr* rest, Sexpr* env) {
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
-       Sexpr* x = clone(car(cdr(args)));
-       Sexpr* y = clone(car(args));
-       Sexpr* y2 = clone(y);
-       sexpr_free(b);
+       Sexpr* x = add_ref(car(cdr(args)));
+       Sexpr* y = add_ref(car(args));
+       Sexpr* y2 = add_ref(y);
+       dec_ref(b);
        Sexpr* ret = cons(x, cons(y, cons(y2, rest)));
        return ret;
 }
        Sexpr* ret = cons(x, cons(y, cons(y2, rest)));
        return ret;
 }
@@ -93,15 +93,15 @@ Sexpr* c_phi(Sexpr* b, Sexpr* rest, Sexpr* env) {
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
-       Sexpr* d = clone(car(args));
-       Sexpr* c = clone(car(cdr(args)));
-       Sexpr* bee = clone(car(cdr(cdr(args))));
-       Sexpr* a = clone(car(cdr(cdr(cdr(args)))));
-       Sexpr* d2 = clone(d);
+       Sexpr* d = add_ref(car(args));
+       Sexpr* c = add_ref(car(cdr(args)));
+       Sexpr* bee = add_ref(car(cdr(cdr(args))));
+       Sexpr* a = add_ref(car(cdr(cdr(cdr(args)))));
+       Sexpr* d2 = add_ref(d);
        Sexpr* bd = cons(bee, cons(d, from_nil()));
        Sexpr* cd = cons(c, cons(d2, from_nil()));
        Sexpr* ret = cons(a, cons(bd, cons(cd, rest)));
        Sexpr* bd = cons(bee, cons(d, from_nil()));
        Sexpr* cd = cons(c, cons(d2, from_nil()));
        Sexpr* ret = cons(a, cons(bd, cons(cd, rest)));
-       sexpr_free(b);
+       dec_ref(b);
        return ret;
 }
 
        return ret;
 }
 
@@ -110,15 +110,15 @@ Sexpr* c_psi(Sexpr* b, Sexpr* rest, Sexpr* env) {
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
-       Sexpr* d = clone(car(args));
-       Sexpr* c = clone(car(cdr(args)));
-       Sexpr* bee = clone(car(cdr(cdr(args))));
-       Sexpr* a = clone(car(cdr(cdr(cdr(args)))));
-       Sexpr* bee2 = clone(bee);
+       Sexpr* d = add_ref(car(args));
+       Sexpr* c = add_ref(car(cdr(args)));
+       Sexpr* bee = add_ref(car(cdr(cdr(args))));
+       Sexpr* a = add_ref(car(cdr(cdr(cdr(args)))));
+       Sexpr* bee2 = add_ref(bee);
        Sexpr* bd = cons(bee, cons(d, from_nil()));
        Sexpr* bc = cons(bee2, cons(c, from_nil()));
        Sexpr* ret = cons(a, cons(bc, cons(bd, rest)));
        Sexpr* bd = cons(bee, cons(d, from_nil()));
        Sexpr* bc = cons(bee2, cons(c, from_nil()));
        Sexpr* ret = cons(a, cons(bc, cons(bd, rest)));
-       sexpr_free(b);
+       dec_ref(b);
        return ret;
 }
 
        return ret;
 }
 
@@ -128,12 +128,12 @@ Sexpr* c_z(Sexpr* b, Sexpr* rest, Sexpr* env) {
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
-       Sexpr* g = clone(car(cdr(args)));
-       Sexpr* v = eval(clone(car(args)), env);
+       Sexpr* g = add_ref(car(cdr(args)));
+       Sexpr* v = eval(add_ref(car(args)), env);
        // man that eval does a /lot/ for computation,
        // need to think about what this implies
        // man that eval does a /lot/ for computation,
        // need to think about what this implies
-       sexpr_free(b);
-       Sexpr* g2 = clone(g);
+       dec_ref(b);
+       Sexpr* g2 = add_ref(g);
        Sexpr* z = from_opcode((COMB_PREFIX << 8) | COMB_Z);
        Sexpr* zg = cons(z, cons(g2, from_nil()));
        //return cons(g, rest);
        Sexpr* z = from_opcode((COMB_PREFIX << 8) | COMB_Z);
        Sexpr* zg = cons(z, cons(g2, from_nil()));
        //return cons(g, rest);
index 6caf7ab36317bc1af883636656af7b357d0bf598..8e43291ad59fca826232e8e8c672d4a3e91a5f73 100644 (file)
@@ -14,8 +14,8 @@
 Sexpr* c_quote(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(CORE_QUOTE_ARGS != u64_get_num_args(b))
                return cons(b, rest);
 Sexpr* c_quote(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(CORE_QUOTE_ARGS != u64_get_num_args(b))
                return cons(b, rest);
-       Sexpr* arg = clone(car(b->value.b.args));
-       sexpr_free(b);
+       Sexpr* arg = add_ref(car(b->value.b.args));
+       dec_ref(b);
        return cons(from_quote(arg), rest);
 }
 
        return cons(from_quote(arg), rest);
 }
 
@@ -25,54 +25,54 @@ Sexpr* c_cons(Sexpr* b, Sexpr* rest, Sexpr* env) {
                return cons(b, rest);
        // big problem: need to rewrite to wiggle around quotes
        Sexpr* args = b->value.b.args;
                return cons(b, rest);
        // big problem: need to rewrite to wiggle around quotes
        Sexpr* args = b->value.b.args;
-       Sexpr* raw_cdr = eval(clone(car(args)), env);
+       Sexpr* raw_cdr = eval(add_ref(car(args)), env);
        Sexpr* _cdr = raw_cdr;
        if(_cdr->type == QUOTE)
                _cdr = _cdr->value.q;
        Sexpr* _cdr = raw_cdr;
        if(_cdr->type == QUOTE)
                _cdr = _cdr->value.q;
-       Sexpr* raw_car = eval(clone(car(cdr(args))), env);
+       Sexpr* raw_car = eval(add_ref(car(cdr(args))), env);
        Sexpr* _car = raw_car;
        if(_car->type == QUOTE)
                _car = _car->value.q;
        Sexpr* _car = raw_car;
        if(_car->type == QUOTE)
                _car = _car->value.q;
-       Sexpr* ret = cons(from_quote(cons(clone(_car),clone(_cdr))), rest);
-       sexpr_free(raw_car);
-       sexpr_free(raw_cdr);
-       sexpr_free(b);
+       Sexpr* ret = cons(from_quote(cons(add_ref(_car),add_ref(_cdr))), rest);
+       dec_ref(raw_car);
+       dec_ref(raw_cdr);
+       dec_ref(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;
        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* unqargev = eval(clone(car(args)), env);
+       Sexpr* unqargev = eval(add_ref(car(args)), env);
 #ifdef TYPECHECK
        if(unquote(unqargev)->type != CONS) {
                ERR(CORE_CAR_STR ": ", "argument not cons cell");
 #ifdef TYPECHECK
        if(unquote(unqargev)->type != CONS) {
                ERR(CORE_CAR_STR ": ", "argument not cons cell");
-               sexpr_free(b);
-               sexpr_free(unqargev);
+               dec_ref(b);
+               dec_ref(unqargev);
                return cons(from_nil(), rest);
        }
 #endif // typecheck
                return cons(from_nil(), rest);
        }
 #endif // typecheck
-       Sexpr* ret = cons(from_quote(clone(car(unquote(unqargev)))), rest);
-       sexpr_free(unqargev);
-       sexpr_free(b);
+       Sexpr* ret = cons(from_quote(add_ref(car(unquote(unqargev)))), rest);
+       dec_ref(unqargev);
+       dec_ref(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;
        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* unqargev = eval(clone(car(args)), env);
+       Sexpr* unqargev = eval(add_ref(car(args)), env);
 #ifdef TYPECHECK
        if(unquote(unqargev)->type != CONS) {
                ERR(CORE_CDR_STR ": ", "argument not cons cell");
 #ifdef TYPECHECK
        if(unquote(unqargev)->type != CONS) {
                ERR(CORE_CDR_STR ": ", "argument not cons cell");
-               sexpr_free(b);
-               sexpr_free(unqargev);
+               dec_ref(b);
+               dec_ref(unqargev);
                return cons(from_nil(), rest);
        }
 #endif // typecheck
                return cons(from_nil(), rest);
        }
 #endif // typecheck
-       Sexpr* ret = cons(from_quote(clone(cdr(unquote(unqargev)))), rest);
-       sexpr_free(unqargev);
-       sexpr_free(b);
+       Sexpr* ret = cons(from_quote(add_ref(cdr(unquote(unqargev)))), rest);
+       dec_ref(unqargev);
+       dec_ref(b);
        return ret;
 }
 Sexpr* c_eq(Sexpr* b, Sexpr* rest, Sexpr* env) {
        return ret;
 }
 Sexpr* c_eq(Sexpr* b, Sexpr* rest, Sexpr* env) {
@@ -80,14 +80,14 @@ Sexpr* c_eq(Sexpr* b, Sexpr* rest, Sexpr* env) {
                return cons(b, rest);
        Sexpr* args = b->value.b.args;
        // yeah eval is kinda necessary for this one I'd say
                return cons(b, rest);
        Sexpr* args = b->value.b.args;
        // yeah eval is kinda necessary for this one I'd say
-       Sexpr* lh = eval(clone(car(args)), env);
-       Sexpr* rh = eval(clone(car(cdr(args))), env);
+       Sexpr* lh = eval(add_ref(car(args)), env);
+       Sexpr* rh = eval(add_ref(car(cdr(args))), env);
        Sexpr* eq_b = equal(unquote(lh), unquote(rh));
        bool equality = eq_b->type == T;
        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);
+       dec_ref(eq_b);
+       dec_ref(lh);
+       dec_ref(rh);
+       dec_ref(b);
        if(equality)
                return cons(from_t(), rest);
        return cons(from_nil(), rest);
        if(equality)
                return cons(from_t(), rest);
        return cons(from_nil(), rest);
@@ -97,10 +97,10 @@ Sexpr* c_not(Sexpr* b, Sexpr* rest, Sexpr* env) {
                return cons(b, rest);
        Sexpr* args = b->value.b.args;
        // I guess I would need the eval to check if eventually is nil
                return cons(b, rest);
        Sexpr* args = b->value.b.args;
        // I guess I would need the eval to check if eventually is nil
-       Sexpr* crux = eval(clone(car(args)), env);
+       Sexpr* crux = eval(add_ref(car(args)), env);
        bool isnil = unquote(crux)->type == NIL;
        bool isnil = unquote(crux)->type == NIL;
-       sexpr_free(crux);
-       sexpr_free(b);
+       dec_ref(crux);
+       dec_ref(b);
        if(isnil)
                return cons(from_t(), rest);
        return cons(from_nil(), rest);
        if(isnil)
                return cons(from_t(), rest);
        return cons(from_nil(), rest);
@@ -109,18 +109,18 @@ Sexpr* c_atom(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(CORE_ATOM_ARGS != u64_get_num_args(b))
                return cons(b, rest);
        Sexpr* args = b->value.b.args;
        if(CORE_ATOM_ARGS != u64_get_num_args(b))
                return cons(b, rest);
        Sexpr* args = b->value.b.args;
-       Sexpr* argevalhead = eval(clone(car(args)), env);
+       Sexpr* argevalhead = eval(add_ref(car(args)), env);
        Sexpr* argeval = argevalhead;
        while(argeval->type == QUOTE) {
                argeval = argeval->value.q;
        }
        if(argeval->type != CONS) {
        Sexpr* argeval = argevalhead;
        while(argeval->type == QUOTE) {
                argeval = argeval->value.q;
        }
        if(argeval->type != CONS) {
-               sexpr_free(argevalhead);
-               sexpr_free(b);
+               dec_ref(argevalhead);
+               dec_ref(b);
                return cons(from_t(), rest);
        }
                return cons(from_t(), rest);
        }
-       sexpr_free(argevalhead);
-       sexpr_free(b);
+       dec_ref(argevalhead);
+       dec_ref(b);
        return cons(from_nil(), rest);
 }
 
        return cons(from_nil(), rest);
 }
 
@@ -135,10 +135,10 @@ Sexpr* c_rest(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(CORE_REST_ARGS != u64_get_num_args(b))
                return cons(b, rest);
        Sexpr* args = b->value.b.args;
        if(CORE_REST_ARGS != u64_get_num_args(b))
                return cons(b, rest);
        Sexpr* args = b->value.b.args;
-       Sexpr* first_arg = eval(clone(car(cdr(args))), env);
-       Sexpr* second_arg = clone(car(args)); // uhh no eval? nah don't think so
+       Sexpr* first_arg = eval(add_ref(car(cdr(args))), env);
+       Sexpr* second_arg = add_ref(car(args)); // uhh no eval? nah don't think so
        Sexpr* newrest = cons(second_arg, rest);
        Sexpr* newrest = cons(second_arg, rest);
-       sexpr_free(b);
+       dec_ref(b);
        return cons(first_arg, cons(from_quote(newrest), from_nil()));
 }
 
        return cons(first_arg, cons(from_quote(newrest), from_nil()));
 }
 
@@ -149,9 +149,9 @@ Sexpr* c_unquote(Sexpr* b, Sexpr* rest, Sexpr* env) {
        // huh this might need a weird cursed double-eval
        if(CORE_UNQUOTE_ARGS != u64_get_num_args(b))
                return cons(b, rest);
        // huh this might need a weird cursed double-eval
        if(CORE_UNQUOTE_ARGS != u64_get_num_args(b))
                return cons(b, rest);
-       Sexpr* first_arg = eval(clone(car(b->value.b.args)), env);
+       Sexpr* first_arg = eval(add_ref(car(b->value.b.args)), env);
        Sexpr* newthing = eval(unquote(first_arg), env);
        Sexpr* newthing = eval(unquote(first_arg), env);
-       sexpr_free(b);
+       dec_ref(b);
        return cons(newthing, rest);
 }
 
        return cons(newthing, rest);
 }
 
@@ -164,20 +164,20 @@ Sexpr* c_applyn(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(CORE_APPLYN_ARGS != u64_get_num_args(b))
                return cons(b, rest);
        Sexpr* args = b->value.b.args;
        if(CORE_APPLYN_ARGS != u64_get_num_args(b))
                return cons(b, rest);
        Sexpr* args = b->value.b.args;
-       Sexpr* arg = clone(car(args));
+       Sexpr* arg = add_ref(car(args));
        Sexpr* fun = car(cdr(args));
        Sexpr* fun = car(cdr(args));
-       Sexpr* snum = eval(clone(car(cdr(cdr(args)))), env);
+       Sexpr* snum = eval(add_ref(car(cdr(cdr(args)))), env);
        // uh yeah i'm not typechecking lol
        K_UINT_TYPE num = snum->value.u;
        // uh yeah i'm not typechecking lol
        K_UINT_TYPE num = snum->value.u;
-       sexpr_free(snum);
+       dec_ref(snum);
        // fun not cloned due since i'll be cloning it in the loop
        Sexpr* ret = cons(arg, from_nil());
        while(num > 0) {
        // fun not cloned due since i'll be cloning it in the loop
        Sexpr* ret = cons(arg, from_nil());
        while(num > 0) {
-               ret = cons(clone(fun), cons(ret, from_nil()));
+               ret = cons(add_ref(fun), cons(ret, from_nil()));
                ret = eval(ret, env);
                num--;
        }
                ret = eval(ret, env);
                num--;
        }
-       sexpr_free(b);
+       dec_ref(b);
        return cons(ret, rest);
 }
 
        return cons(ret, rest);
 }
 
@@ -185,9 +185,9 @@ Sexpr* c_evalarg(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(CORE_EVALARG_ARGS != u64_get_num_args(b))
                return cons(b, rest);
        Sexpr* args = b->value.b.args;
        if(CORE_EVALARG_ARGS != u64_get_num_args(b))
                return cons(b, rest);
        Sexpr* args = b->value.b.args;
-       Sexpr* argeval = eval(clone(car(args)), env);
-       Sexpr* fn = clone(car(cdr(args)));
-       sexpr_free(b);
+       Sexpr* argeval = eval(add_ref(car(args)), env);
+       Sexpr* fn = add_ref(car(cdr(args)));
+       dec_ref(b);
        return cons(fn, cons(argeval, rest));
 }
 
        return cons(fn, cons(argeval, rest));
 }
 
@@ -196,10 +196,10 @@ Sexpr* c_type(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(CORE_TYPE_ARGS != u64_get_num_args(b))
                return cons(b, rest);
        Sexpr* args = b->value.b.args;
        if(CORE_TYPE_ARGS != u64_get_num_args(b))
                return cons(b, rest);
        Sexpr* args = b->value.b.args;
-       Sexpr* argev = eval(clone(car(args)), env);
+       Sexpr* argev = eval(add_ref(car(args)), env);
        Sexpr_Type t = argev->type;
        Sexpr_Type t = argev->type;
-       sexpr_free(b);
-       sexpr_free(argev);
+       dec_ref(b);
+       dec_ref(argev);
        switch(t) {
        case UINT:
                return cons(from_string("uint"), rest);
        switch(t) {
        case UINT:
                return cons(from_string("uint"), rest);
@@ -228,11 +228,11 @@ Sexpr* c_def(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(CORE_DEF_ARGS != u64_get_num_args(b))
                return cons(b, rest);
        Sexpr* args = b->value.b.args;
        if(CORE_DEF_ARGS != u64_get_num_args(b))
                return cons(b, rest);
        Sexpr* args = b->value.b.args;
-       Sexpr* val = eval(clone(car(args)), env);
-       Sexpr* key = clone(car(cdr(args)));
+       Sexpr* val = eval(add_ref(car(args)), env);
+       Sexpr* key = add_ref(car(cdr(args)));
        append_to_dict(env, key, val);
        append_to_dict(env, key, val);
-       sexpr_free(key);
-       sexpr_free(b);
+       dec_ref(key);
+       dec_ref(b);
        return cons(val, rest);
 }
 Sexpr* c_exit(Sexpr* b, Sexpr* rest, Sexpr* env) {
        return cons(val, rest);
 }
 Sexpr* c_exit(Sexpr* b, Sexpr* rest, Sexpr* env) {
@@ -240,9 +240,9 @@ Sexpr* c_exit(Sexpr* b, Sexpr* rest, Sexpr* env) {
                return cons(b, rest);
        Sexpr* args = b->value.b.args;
        K_UINT_TYPE value = car(args)->value.u;
                return cons(b, rest);
        Sexpr* args = b->value.b.args;
        K_UINT_TYPE value = car(args)->value.u;
-       sexpr_free(b);
-       sexpr_free(rest);
-       sexpr_free(env);
+       dec_ref(b);
+       dec_ref(rest);
+       dec_ref(env);
        exit(value);
        return NULL;
 }
        exit(value);
        return NULL;
 }
index 3531addd8d81f58b31315e08ceff576ec5c7f2e0..57ebc5dfb39087773bb8bd00ea4cc31a99dac855 100644 (file)
@@ -14,10 +14,10 @@ Sexpr* io_print(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(IO_PRINT_ARGS != u64_get_num_args(b)) {
                return cons(b, rest);
        }
        if(IO_PRINT_ARGS != u64_get_num_args(b)) {
                return cons(b, rest);
        }
-       Sexpr* arg = eval(clone(car(b->value.b.args)), env);
-       sexpr_free(b);
+       Sexpr* arg = eval(add_ref(car(b->value.b.args)), env);
+       dec_ref(b);
        char* out = sprint_sexpr(arg);
        char* out = sprint_sexpr(arg);
-       sexpr_free(arg);
+       dec_ref(arg);
        PRINT(out);
        free(out);
        return cons(from_t(), rest);
        PRINT(out);
        free(out);
        return cons(from_t(), rest);
@@ -27,15 +27,15 @@ Sexpr* io_printstr(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(IO_PRINTSTR_ARGS != u64_get_num_args(b)) {
                return cons(b, rest);
        }
        if(IO_PRINTSTR_ARGS != u64_get_num_args(b)) {
                return cons(b, rest);
        }
-       Sexpr* arg = eval(clone(car(b->value.b.args)), env);
+       Sexpr* arg = eval(add_ref(car(b->value.b.args)), env);
        if(arg->type != STR) {
        if(arg->type != STR) {
-               sexpr_free(b);
-               sexpr_free(arg);
+               dec_ref(b);
+               dec_ref(arg);
                return cons(from_nil(), rest);
        }
        PRINT(arg->value.str);
                return cons(from_nil(), rest);
        }
        PRINT(arg->value.str);
-       sexpr_free(b);
-       sexpr_free(arg);
+       dec_ref(b);
+       dec_ref(arg);
        return cons(from_t(), rest);
 }
 
        return cons(from_t(), rest);
 }
 
@@ -43,11 +43,11 @@ Sexpr* io_print_b(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(IO_PB_ARGS != u64_get_num_args(b)) {
                return cons(b, rest);
        }
        if(IO_PB_ARGS != u64_get_num_args(b)) {
                return cons(b, rest);
        }
-       Sexpr* arg = clone(car(b->value.b.args));
-       sexpr_free(b);
+       Sexpr* arg = add_ref(car(b->value.b.args));
+       dec_ref(b);
        Sexpr* argeval = eval(arg, env);
        char* out = sprint_sexpr_builtin(argeval);
        Sexpr* argeval = eval(arg, env);
        char* out = sprint_sexpr_builtin(argeval);
-       sexpr_free(argeval);
+       dec_ref(argeval);
        // uhh do i free arg? don't think so...
        PRINT(out);
        free(out);
        // uhh do i free arg? don't think so...
        PRINT(out);
        free(out);
@@ -58,24 +58,24 @@ Sexpr* io_readfile(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(IO_READFILE_ARGS != u64_get_num_args(b)) {
                return cons(b, rest);
        }
        if(IO_READFILE_ARGS != u64_get_num_args(b)) {
                return cons(b, rest);
        }
-       Sexpr* firstarg = eval(clone(car(b->value.b.args)), env);
+       Sexpr* firstarg = eval(add_ref(car(b->value.b.args)), env);
 #ifdef TYPECHECK
        if(firstarg->type != STR) {
                ERR(IO_READFILE_STR ": ", "argument not a string");
 #ifdef TYPECHECK
        if(firstarg->type != STR) {
                ERR(IO_READFILE_STR ": ", "argument not a string");
-               sexpr_free(firstarg);
-               sexpr_free(b);
+               dec_ref(firstarg);
+               dec_ref(b);
                return cons(from_nil(), rest);
        }
 #endif
        FILE* thefile = fopen(firstarg->value.str, "r");
        if(!thefile) {
                ERR(IO_READFILE_STR ": file not found: ", firstarg->value.str);
                return cons(from_nil(), rest);
        }
 #endif
        FILE* thefile = fopen(firstarg->value.str, "r");
        if(!thefile) {
                ERR(IO_READFILE_STR ": file not found: ", firstarg->value.str);
-               sexpr_free(firstarg);
-               sexpr_free(b);
+               dec_ref(firstarg);
+               dec_ref(b);
                return cons(from_nil(), rest);
        }
                return cons(from_nil(), rest);
        }
-       sexpr_free(firstarg);
-       sexpr_free(b);
+       dec_ref(firstarg);
+       dec_ref(b);
        fseek(thefile, 0, SEEK_END);
        size_t fsz = ftell(thefile);
        fseek(thefile, 0, SEEK_SET);
        fseek(thefile, 0, SEEK_END);
        size_t fsz = ftell(thefile);
        fseek(thefile, 0, SEEK_SET);
@@ -97,14 +97,14 @@ Sexpr* io_writefile(Sexpr* b, Sexpr* rest, Sexpr* env) {
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
-       Sexpr* filearg = eval(clone(car(cdr(args))), env);
-       Sexpr* strarg = eval(clone(car(args)), env);
+       Sexpr* filearg = eval(add_ref(car(cdr(args))), env);
+       Sexpr* strarg = eval(add_ref(car(args)), env);
 #ifdef TYPECHECK
        if(filearg->type != STR || strarg->type != STR) {
                ERR(IO_WRITEFILE_STR ": ", "arguments not strings");
 #ifdef TYPECHECK
        if(filearg->type != STR || strarg->type != STR) {
                ERR(IO_WRITEFILE_STR ": ", "arguments not strings");
-               sexpr_free(filearg);
-               sexpr_free(strarg);
-               sexpr_free(b);
+               dec_ref(filearg);
+               dec_ref(strarg);
+               dec_ref(b);
                return cons(from_nil(), rest);
        }
 #endif
                return cons(from_nil(), rest);
        }
 #endif
@@ -112,16 +112,16 @@ Sexpr* io_writefile(Sexpr* b, Sexpr* rest, Sexpr* env) {
        FILE* thefile = fopen(filestring, "w");
        if(!thefile) {
                ERR(IO_WRITEFILE_STR ": file not found: ", filestring);
        FILE* thefile = fopen(filestring, "w");
        if(!thefile) {
                ERR(IO_WRITEFILE_STR ": file not found: ", filestring);
-               sexpr_free(filearg);
-               sexpr_free(strarg);
-               sexpr_free(b);
+               dec_ref(filearg);
+               dec_ref(strarg);
+               dec_ref(b);
                return cons(from_nil(), rest);
        }
        size_t num_written = fwrite(strarg->value.str, sizeof(char), strlen(strarg->value.str), thefile);
        fclose(thefile);
                return cons(from_nil(), rest);
        }
        size_t num_written = fwrite(strarg->value.str, sizeof(char), strlen(strarg->value.str), thefile);
        fclose(thefile);
-       sexpr_free(filearg);
-       sexpr_free(strarg);
-       sexpr_free(b);
+       dec_ref(filearg);
+       dec_ref(strarg);
+       dec_ref(b);
        return cons(from_uint(num_written), rest);
 }
 
        return cons(from_uint(num_written), rest);
 }
 
@@ -130,18 +130,18 @@ Sexpr* io_rand(Sexpr* b, Sexpr* rest, Sexpr* env) {
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
-       Sexpr* arg = eval(clone(car(args)), env);
+       Sexpr* arg = eval(add_ref(car(args)), env);
 #ifdef TYPECHECK
        if(arg->type != UINT) {
                ERR(IO_RAND_STR ": ", "argument not uint");
 #ifdef TYPECHECK
        if(arg->type != UINT) {
                ERR(IO_RAND_STR ": ", "argument not uint");
-               sexpr_free(arg);
-               sexpr_free(b);
+               dec_ref(arg);
+               dec_ref(b);
                return cons(from_nil(), rest);
        }
 #endif
        K_UINT_TYPE m = unquote(arg)->value.u;
                return cons(from_nil(), rest);
        }
 #endif
        K_UINT_TYPE m = unquote(arg)->value.u;
-       sexpr_free(b);
-       sexpr_free(arg);
+       dec_ref(b);
+       dec_ref(arg);
        return cons(from_uint(rand() % m), rest);
 }
 
        return cons(from_uint(rand() % m), rest);
 }
 
index 15ce7d74277a5f2e482ced537c39c17b09187c75..19d8d513942c766ad62db6fd671e8180ed775ecc 100644 (file)
@@ -14,18 +14,18 @@ Sexpr* m_utob(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(META_UTOB_ARGS != u64_get_num_args(b)) {
                return cons(b, rest);
        }
        if(META_UTOB_ARGS != u64_get_num_args(b)) {
                return cons(b, rest);
        }
-       Sexpr* arg = eval(clone(car(b->value.b.args)), env);
+       Sexpr* arg = eval(add_ref(car(b->value.b.args)), env);
 #ifdef TYPECHECK
        if(unquote(arg)->type != UINT) {
                ERR(META_UTOB_STR ": ", "argument not uint");
 #ifdef TYPECHECK
        if(unquote(arg)->type != UINT) {
                ERR(META_UTOB_STR ": ", "argument not uint");
-               sexpr_free(b);
-               sexpr_free(arg);
+               dec_ref(b);
+               dec_ref(arg);
                return cons(from_nil(), rest);
        }
 #endif // typecheck
        Sexpr* out = from_opcode(unquote(arg)->value.u);
                return cons(from_nil(), rest);
        }
 #endif // typecheck
        Sexpr* out = from_opcode(unquote(arg)->value.u);
-       sexpr_free(b);
-       sexpr_free(arg);
+       dec_ref(b);
+       dec_ref(arg);
        return cons(out, rest);
 }
 
        return cons(out, rest);
 }
 
@@ -33,18 +33,18 @@ Sexpr* m_btou(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(META_BTOU_ARGS != u64_get_num_args(b)) {
                return cons(b, rest);
        }
        if(META_BTOU_ARGS != u64_get_num_args(b)) {
                return cons(b, rest);
        }
-       Sexpr* arg = eval(clone(car(b->value.b.args)), env);
+       Sexpr* arg = eval(add_ref(car(b->value.b.args)), env);
 #ifdef TYPECHECK
        if(unquote(arg)->type != BUILTIN) {
                ERR(META_BTOU_STR ": ", "argument not builtin");
 #ifdef TYPECHECK
        if(unquote(arg)->type != BUILTIN) {
                ERR(META_BTOU_STR ": ", "argument not builtin");
-               sexpr_free(b);
-               sexpr_free(arg);
+               dec_ref(b);
+               dec_ref(arg);
                return cons(from_nil(), rest);
        }
 #endif // typecheck
        Sexpr* out = from_uint(unquote(arg)->value.b.opcode);
                return cons(from_nil(), rest);
        }
 #endif // typecheck
        Sexpr* out = from_uint(unquote(arg)->value.b.opcode);
-       sexpr_free(b);
-       sexpr_free(arg);
+       dec_ref(b);
+       dec_ref(arg);
        return cons(out, rest);
 }
 
        return cons(out, rest);
 }
 
@@ -52,18 +52,18 @@ Sexpr* m_parse(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(META_PARSE_ARGS != u64_get_num_args(b)) {
                return cons(b, rest);
        }
        if(META_PARSE_ARGS != u64_get_num_args(b)) {
                return cons(b, rest);
        }
-       Sexpr* arg = eval(clone(car(b->value.b.args)), env);
+       Sexpr* arg = eval(add_ref(car(b->value.b.args)), env);
 #ifdef TYPECHECK
        if(unquote(arg)->type != STR) {
                ERR(META_PARSE_STR ": ", "argument not string");
 #ifdef TYPECHECK
        if(unquote(arg)->type != STR) {
                ERR(META_PARSE_STR ": ", "argument not string");
-               sexpr_free(b);
-               sexpr_free(arg);
+               dec_ref(b);
+               dec_ref(arg);
                return cons(from_nil(), rest);
        }
 #endif
        Sexpr* out = parse(unquote(arg)->value.str);
                return cons(from_nil(), rest);
        }
 #endif
        Sexpr* out = parse(unquote(arg)->value.str);
-       sexpr_free(b);
-       sexpr_free(arg);
+       dec_ref(b);
+       dec_ref(arg);
        if(out == NULL) {
                ERR(META_PARSE_STR ": ", "bad input");
                return cons(from_nil(), rest);
        if(out == NULL) {
                ERR(META_PARSE_STR ": ", "bad input");
                return cons(from_nil(), rest);
@@ -75,18 +75,18 @@ Sexpr* m_getargs(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(META_GETARGS_ARGS != u64_get_num_args(b)) {
                return cons(b, rest);
        }
        if(META_GETARGS_ARGS != u64_get_num_args(b)) {
                return cons(b, rest);
        }
-       Sexpr* arg = eval(clone(car(b->value.b.args)), env);
+       Sexpr* arg = eval(add_ref(car(b->value.b.args)), env);
 #ifdef TYPECHECK
        if(unquote(arg)->type != BUILTIN) {
                ERR(META_GETARGS_STR ": ", "argument not builtin");
 #ifdef TYPECHECK
        if(unquote(arg)->type != BUILTIN) {
                ERR(META_GETARGS_STR ": ", "argument not builtin");
-               sexpr_free(b);
-               sexpr_free(arg);
+               dec_ref(b);
+               dec_ref(arg);
                return cons(from_nil(), rest);
        }
 #endif
                return cons(from_nil(), rest);
        }
 #endif
-       Sexpr* args = clone(unquote(arg)->value.b.args); // poorly named variable?
-       sexpr_free(arg);
-       sexpr_free(b);
+       Sexpr* args = add_ref(unquote(arg)->value.b.args); // poorly named variable?
+       dec_ref(arg);
+       dec_ref(b);
        return cons(from_quote(args), rest);
 }
 
        return cons(from_quote(args), rest);
 }
 
@@ -96,7 +96,7 @@ Sexpr* m_lookup(Sexpr* b, Sexpr* rest, Sexpr* env) {
        }
        Sexpr* args = b->value.b.args;
        Sexpr* lookedup = lookup(env, car(args));
        }
        Sexpr* args = b->value.b.args;
        Sexpr* lookedup = lookup(env, car(args));
-       sexpr_free(b);
+       dec_ref(b);
        return cons(from_quote(lookedup), rest);
 }
 
        return cons(from_quote(lookedup), rest);
 }
 
@@ -106,16 +106,16 @@ Sexpr* m_getenv(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(META_GETENV_ARGS != u64_get_num_args(b)) {
                return cons(b, rest);
        }
        if(META_GETENV_ARGS != u64_get_num_args(b)) {
                return cons(b, rest);
        }
-       Sexpr* arg = eval(clone(car(b->value.b.args)), env);
+       Sexpr* arg = eval(add_ref(car(b->value.b.args)), env);
        if(arg->type != T) {
                ERR(META_GETENV_STR ": ", "incorrect call");
        if(arg->type != T) {
                ERR(META_GETENV_STR ": ", "incorrect call");
-               sexpr_free(b);
-               sexpr_free(arg);
+               dec_ref(b);
+               dec_ref(arg);
                return cons(from_nil(), rest);
        }
                return cons(from_nil(), rest);
        }
-       sexpr_free(b);
-       sexpr_free(arg);
-       Sexpr* outpart = cons(from_quote(clone(env)), rest);
+       dec_ref(b);
+       dec_ref(arg);
+       Sexpr* outpart = cons(from_quote(add_ref(env)), rest);
        return outpart;
 }
 
        return outpart;
 }
 
@@ -124,19 +124,19 @@ Sexpr* m_setenv(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(META_SETENV_ARGS != u64_get_num_args(b)) {
                return cons(b, rest);
        }
        if(META_SETENV_ARGS != u64_get_num_args(b)) {
                return cons(b, rest);
        }
-       Sexpr* arg = eval(clone(car(b->value.b.args)), env);
+       Sexpr* arg = eval(add_ref(car(b->value.b.args)), env);
        if(unquote(arg)->type != CONS && cdr(unquote(arg))->type != NIL) {
                ERR(META_SETENV_STR ": ", "not well-formed");
        if(unquote(arg)->type != CONS && cdr(unquote(arg))->type != NIL) {
                ERR(META_SETENV_STR ": ", "not well-formed");
-               sexpr_free(b);
-               sexpr_free(arg);
+               dec_ref(b);
+               dec_ref(arg);
                return cons(from_nil(), rest);
        }
                return cons(from_nil(), rest);
        }
-       Sexpr* newenvbody = clone(car(unquote(arg)));
-       sexpr_free(car(env));
+       Sexpr* newenvbody = add_ref(car(unquote(arg)));
+       dec_ref(car(env));
        env->value.c->car = newenvbody;
        // todo
        env->value.c->car = newenvbody;
        // todo
-       sexpr_free(b);
-       sexpr_free(arg);
+       dec_ref(b);
+       dec_ref(arg);
        return cons(from_t(), rest);
 }
 
        return cons(from_t(), rest);
 }
 
index e94d67bff8df9dcd9f04562942bbfd2233a7b9af..d3a0f7eb4bd85bf2e78e441596d669d787b32677 100644 (file)
@@ -15,18 +15,18 @@ Sexpr* s_strlen(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(STRINGS_STRLEN_ARGS != u64_get_num_args(b)) {
                return cons(b, rest);
        }
        if(STRINGS_STRLEN_ARGS != u64_get_num_args(b)) {
                return cons(b, rest);
        }
-       Sexpr* arg = eval(clone(car(b->value.b.args)), env);
+       Sexpr* arg = eval(add_ref(car(b->value.b.args)), env);
 #ifdef TYPECHECK
        if(unquote(arg)->type != STR) {
                ERR(STRINGS_STRLEN_STR ": ", "argument not string");
 #ifdef TYPECHECK
        if(unquote(arg)->type != STR) {
                ERR(STRINGS_STRLEN_STR ": ", "argument not string");
-               sexpr_free(b);
-               sexpr_free(arg);
+               dec_ref(b);
+               dec_ref(arg);
                return cons(from_nil(), rest);
        }
 #endif // typecheck
        size_t sl = strlen(unquote(arg)->value.str);
                return cons(from_nil(), rest);
        }
 #endif // typecheck
        size_t sl = strlen(unquote(arg)->value.str);
-       sexpr_free(b);
-       sexpr_free(arg);
+       dec_ref(b);
+       dec_ref(arg);
        return cons (from_uint(sl), rest);
 }
 
        return cons (from_uint(sl), rest);
 }
 
@@ -35,14 +35,14 @@ Sexpr* s_strcat(Sexpr* b, Sexpr* rest, Sexpr* env) {
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
-       Sexpr* snd = eval(clone(car(args)), env);
-       Sexpr* fst = eval(clone(car(cdr(args))), env);
+       Sexpr* snd = eval(add_ref(car(args)), env);
+       Sexpr* fst = eval(add_ref(car(cdr(args))), env);
 #ifdef TYPECHECK
        if(unquote(snd)->type != STR || unquote(fst)->type != STR) {
                ERR(STRINGS_STRCAT_STR ": ", "arguments not string");
 #ifdef TYPECHECK
        if(unquote(snd)->type != STR || unquote(fst)->type != STR) {
                ERR(STRINGS_STRCAT_STR ": ", "arguments not string");
-               sexpr_free(snd);
-               sexpr_free(fst);
-               sexpr_free(b);
+               dec_ref(snd);
+               dec_ref(fst);
+               dec_ref(b);
                return cons(from_nil(), rest);
        }
 #endif // typecheck
                return cons(from_nil(), rest);
        }
 #endif // typecheck
@@ -51,9 +51,9 @@ Sexpr* s_strcat(Sexpr* b, Sexpr* rest, Sexpr* env) {
        char* out = malloc(sizeof(char)*(strlen(fs)+strlen(ss)+1));
        strcpy(out, fs);
        strcat(out, ss);
        char* out = malloc(sizeof(char)*(strlen(fs)+strlen(ss)+1));
        strcpy(out, fs);
        strcat(out, ss);
-       sexpr_free(snd);
-       sexpr_free(fst);
-       sexpr_free(b);
+       dec_ref(snd);
+       dec_ref(fst);
+       dec_ref(b);
        Sexpr* outval = cons(from_string(out), rest);
        free(out);
        return outval;
        Sexpr* outval = cons(from_string(out), rest);
        free(out);
        return outval;
@@ -65,14 +65,14 @@ Sexpr* s_strat(Sexpr* b, Sexpr* rest, Sexpr* env) {
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
-       Sexpr* index = eval(clone(car(cdr(args))), env);
-       Sexpr* str = eval(clone(car(args)), env);
+       Sexpr* index = eval(add_ref(car(cdr(args))), env);
+       Sexpr* str = eval(add_ref(car(args)), env);
 #ifdef TYPECHECK
        if(unquote(str)->type != STR || unquote(index)->type != UINT) {
                ERR(STRINGS_STRAT_STR ": ", "arguments not string");
 #ifdef TYPECHECK
        if(unquote(str)->type != STR || unquote(index)->type != UINT) {
                ERR(STRINGS_STRAT_STR ": ", "arguments not string");
-               sexpr_free(index);
-               sexpr_free(str);
-               sexpr_free(b);
+               dec_ref(index);
+               dec_ref(str);
+               dec_ref(b);
                return cons(from_nil(), rest);
        }
 #endif // typecheck
                return cons(from_nil(), rest);
        }
 #endif // typecheck
@@ -84,9 +84,9 @@ Sexpr* s_strat(Sexpr* b, Sexpr* rest, Sexpr* env) {
        }
        char at[] = { '\0', '\0'}; // for uh string stuff?
        at[0] = str->value.str[idx-1];
        }
        char at[] = { '\0', '\0'}; // for uh string stuff?
        at[0] = str->value.str[idx-1];
-       sexpr_free(b);
-       sexpr_free(index);
-       sexpr_free(str);
+       dec_ref(b);
+       dec_ref(index);
+       dec_ref(str);
        return cons(from_string(at), rest);
 }
 
        return cons(from_string(at), rest);
 }
 
@@ -95,12 +95,12 @@ Sexpr* s_strexpand(Sexpr* b, Sexpr* rest, Sexpr* env) {
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
-       Sexpr* arg = eval(clone(car(args)), env);
+       Sexpr* arg = eval(add_ref(car(args)), env);
 #ifdef TYPECHECK
        if(unquote(arg)->type != STR) {
                ERR(STRINGS_STREXPAND_STR ": ", "argument not string");
 #ifdef TYPECHECK
        if(unquote(arg)->type != STR) {
                ERR(STRINGS_STREXPAND_STR ": ", "argument not string");
-               sexpr_free(arg);
-               sexpr_free(b);
+               dec_ref(arg);
+               dec_ref(b);
                return cons(from_nil(), rest);
        }
 #endif // typecheck
                return cons(from_nil(), rest);
        }
 #endif // typecheck
@@ -112,8 +112,8 @@ Sexpr* s_strexpand(Sexpr* b, Sexpr* rest, Sexpr* env) {
                toret = cons(from_string(arr), toret);
                len--;
        }
                toret = cons(from_string(arr), toret);
                len--;
        }
-       sexpr_free(arg);
-       sexpr_free(b);
+       dec_ref(arg);
+       dec_ref(b);
        return cons(from_quote(toret), rest);
 }
 
        return cons(from_quote(toret), rest);
 }
 
@@ -122,14 +122,14 @@ Sexpr* s_substr(Sexpr* b, Sexpr* rest, Sexpr* env) {
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
-       Sexpr* subex = eval(clone(car(cdr(args))), env);
-       Sexpr* strex = eval(clone(car(args)), env);
+       Sexpr* subex = eval(add_ref(car(cdr(args))), env);
+       Sexpr* strex = eval(add_ref(car(args)), env);
 #ifdef TYPECHECK
        if(unquote(subex)->type != STR || unquote(strex)->type != STR) {
                ERR(STRINGS_SUBSTR_STR ": ", "arguments not strings");
 #ifdef TYPECHECK
        if(unquote(subex)->type != STR || unquote(strex)->type != STR) {
                ERR(STRINGS_SUBSTR_STR ": ", "arguments not strings");
-               sexpr_free(subex);
-               sexpr_free(strex);
-               sexpr_free(b);
+               dec_ref(subex);
+               dec_ref(strex);
+               dec_ref(b);
                return cons(from_nil(), rest);
        }
 #endif
                return cons(from_nil(), rest);
        }
 #endif
@@ -146,11 +146,11 @@ Sexpr* s_substr(Sexpr* b, Sexpr* rest, Sexpr* env) {
                // not decided if that's how I want it to be though
                currstr = res + 1;
        }
                // not decided if that's how I want it to be though
                currstr = res + 1;
        }
-       sexpr_free(subex);
-       sexpr_free(strex);
-       sexpr_free(b);
+       dec_ref(subex);
+       dec_ref(strex);
+       dec_ref(b);
        Sexpr* newres = reverse(result);
        Sexpr* newres = reverse(result);
-       sexpr_free(result);
+       dec_ref(result);
        return cons(from_quote(newres), rest);
 }
 
        return cons(from_quote(newres), rest);
 }
 
@@ -159,14 +159,14 @@ Sexpr* s_strtok(Sexpr* b, Sexpr* rest, Sexpr* env) {
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
-       Sexpr* delimex = eval(clone(car(cdr(args))), env);
-       Sexpr* strex = eval(clone(car(args)), env);
+       Sexpr* delimex = eval(add_ref(car(cdr(args))), env);
+       Sexpr* strex = eval(add_ref(car(args)), env);
 #ifdef TYPECHECK
        if(unquote(delimex)->type != STR || unquote(strex)->type != STR) {
                ERR(STRINGS_STRTOK_STR ": ", "arguments not strings");
 #ifdef TYPECHECK
        if(unquote(delimex)->type != STR || unquote(strex)->type != STR) {
                ERR(STRINGS_STRTOK_STR ": ", "arguments not strings");
-               sexpr_free(delimex);
-               sexpr_free(strex);
-               sexpr_free(b);
+               dec_ref(delimex);
+               dec_ref(strex);
+               dec_ref(b);
                return cons(from_nil(), rest);
        }
 #endif
                return cons(from_nil(), rest);
        }
 #endif
@@ -179,10 +179,10 @@ Sexpr* s_strtok(Sexpr* b, Sexpr* rest, Sexpr* env) {
                out = strtok(NULL, delim);
        }
        Sexpr* newres = reverse(result);
                out = strtok(NULL, delim);
        }
        Sexpr* newres = reverse(result);
-       sexpr_free(b);
-       sexpr_free(delimex);
-       sexpr_free(strex);
-       sexpr_free(result);
+       dec_ref(b);
+       dec_ref(delimex);
+       dec_ref(strex);
+       dec_ref(result);
        return cons(from_quote(newres), rest);
 }
 
        return cons(from_quote(newres), rest);
 }
 
@@ -191,12 +191,12 @@ Sexpr* s_tostr(Sexpr* b, Sexpr* rest, Sexpr* env) {
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
-       Sexpr* arg = eval(clone(car(args)), env);
+       Sexpr* arg = eval(add_ref(car(args)), env);
        char* thestr = sprint_sexpr(arg);
        Sexpr* out = cons(from_string(thestr), rest);
        free(thestr);
        char* thestr = sprint_sexpr(arg);
        Sexpr* out = cons(from_string(thestr), rest);
        free(thestr);
-       sexpr_free(arg);
-       sexpr_free(b);
+       dec_ref(arg);
+       dec_ref(b);
        return out;
 }
 
        return out;
 }
 
index bac1d11fa6cc95e7d919f5f8cdd37f26a050217a..ad592e2a947d8be9eb5d1615b337c6d9742fd02d 100644 (file)
@@ -162,6 +162,18 @@ void sexpr_free(Sexpr* s) {
        free(s);
 }
 
        free(s);
 }
 
+Sexpr* add_ref(Sexpr* s) {
+       s->refcount++;
+       return s;
+}
+
+void dec_ref(Sexpr* s) {
+       s->refcount--;
+       if(s->refcount == 0) {
+               sexpr_free(s);
+       }
+}
+
 Sexpr* clone(Sexpr* s) {
        s->refcount++;
        return s;
 Sexpr* clone(Sexpr* s) {
        s->refcount++;
        return s;
index b67788ae7bdab430caf4569536be574ebc2cae5b..165cae3523798b0fe8dccc4d8eb7adce1719df06 100644 (file)
@@ -15,6 +15,8 @@ Sexpr* unquote(Sexpr* s);
 
 void sexpr_free(Sexpr* s);
 Sexpr* clone(Sexpr* s);
 
 void sexpr_free(Sexpr* s);
 Sexpr* clone(Sexpr* s);
+Sexpr* add_ref(Sexpr* s);
+void dec_ref(Sexpr* s);
 
 Sexpr* cons(Sexpr* car, Sexpr* cdr);
 Sexpr* car(Sexpr* s);
 
 Sexpr* cons(Sexpr* car, Sexpr* cdr);
 Sexpr* car(Sexpr* s);
index 8f91df0581950f4d504662fc76124fe01644845b..3d78ec632b77fe6f443b7c9e1f8f912071846c5a 100644 (file)
@@ -397,7 +397,7 @@ void many_asserts() {
        // copy-paste this thing as needed
        assert_eq(env, "", "");
 
        // copy-paste this thing as needed
        assert_eq(env, "", "");
 
-       printf("basics\n");
+       printf("basics\n");
        assert_eq(env, "(+ 4 4)", "8");
        assert_eq(env, "(* 3 4)", "12");
        assert_eq(env, "((+ 3) 7)", "10");
        assert_eq(env, "(+ 4 4)", "8");
        assert_eq(env, "(* 3 4)", "12");
        assert_eq(env, "((+ 3) 7)", "10");
@@ -421,7 +421,7 @@ void many_asserts() {
        assert_eq(env, "- 100 20", "* 10 8");
        assert_eq(env, "/ 100 19", "% 13 8");
 
        assert_eq(env, "- 100 20", "* 10 8");
        assert_eq(env, "/ 100 19", "% 13 8");
 
-       printf("combinators\n");
+       printf("combinators\n");
        assert_eq(env, "I + 4 5", "9");
        assert_eq(env, "S + (+ 4) 3", "10");
        assert_eq(env, "K 5 6", "5");
        assert_eq(env, "I + 4 5", "9");
        assert_eq(env, "S + (+ 4) 3", "10");
        assert_eq(env, "K 5 6", "5");
@@ -440,7 +440,7 @@ void many_asserts() {
        assert_eq(env, "(Z (B B S (C (eq 0) 1) (B B S * (C B (C - 1)))) 6)", "720");
 
 
        assert_eq(env, "(Z (B B S (C (eq 0) 1) (B B S * (C B (C - 1)))) 6)", "720");
 
 
-       printf("strings\n");
+       printf("strings\n");
        assert_eq(env, "strlen \"hi\"", "2");
        assert_eq(env, "strcat \"hi \" \"there\"", "\"hi there\"");
        assert_eq(env, "strat 5 \"hello world\"", "\"o\"");
        assert_eq(env, "strlen \"hi\"", "2");
        assert_eq(env, "strcat \"hi \" \"there\"", "\"hi there\"");
        assert_eq(env, "strat 5 \"hello world\"", "\"o\"");
@@ -450,14 +450,14 @@ void many_asserts() {
        assert_eq(env, "strlen \"hey\"", "3");
        assert_eq(env, "strcat \"hey \" \"there\"", "\"hey there\"");
 
        assert_eq(env, "strlen \"hey\"", "3");
        assert_eq(env, "strcat \"hey \" \"there\"", "\"hey there\"");
 
-       printf("meta\n");
+       printf("meta\n");
        assert_eq(env, "utob 512", "+");
        assert_eq(env, "btou +", "512");
        assert_eq(env, "parse \"cons 4 5\"", "quote (cons 4 5)"); // PROBLEM
        assert_eq(env, "getargs +", "B car list nil"); // PROBLEM
        assert_eq(env, "getargs (+ 5)", "list 5");
 
        assert_eq(env, "utob 512", "+");
        assert_eq(env, "btou +", "512");
        assert_eq(env, "parse \"cons 4 5\"", "quote (cons 4 5)"); // PROBLEM
        assert_eq(env, "getargs +", "B car list nil"); // PROBLEM
        assert_eq(env, "getargs (+ 5)", "list 5");
 
-       printf("with demos\n");
+       printf("with demos\n");
        assert_eq(env, "fac 5", "120");
        assert_eq(env, "range 5", "list 1 2 3 4 5");
        assert_eq(env, "reverse (range 3)", "(list 3 2 1)");
        assert_eq(env, "fac 5", "120");
        assert_eq(env, "range 5", "list 1 2 3 4 5");
        assert_eq(env, "reverse (range 3)", "(list 3 2 1)");