]> git.eli173.com Git - klapaucius/commitdiff
plugged memory leaks in all current builtins
authorElijah Cohen <cohen@eli173.com>
Sat, 17 Aug 2024 04:17:22 +0000 (04:17 +0000)
committerElijah Cohen <cohen@eli173.com>
Sat, 17 Aug 2024 04:17:22 +0000 (04:17 +0000)
src/builtins/core.c
src/sexpr.c
src/test.c

index 5565c335b719af942275d37753c082fb655faa67..d7b97e1027d71ac517dc93b2c9e25ad4dc039887 100644 (file)
@@ -26,50 +26,78 @@ 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;
-       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);
 }
@@ -78,7 +106,11 @@ 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
-       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);
 }
@@ -86,13 +118,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;
-       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);
 }
 
@@ -101,9 +138,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;
-       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) {
index 8eb7d6a784cd795213996df071af03ccda16f56c..890255559b139775f9e61aef69de71c80cee7420 100644 (file)
@@ -99,9 +99,14 @@ Sexpr* equal(Sexpr* a, Sexpr* b) {
                        return equal(a->value.b.args, b->value.b.args);
        if(t == QUOTE)
                return equal(a->value.q, b->value.q);
-       if(t == CONS)
-               if(equal(car(a), car(b))->type == T)
+       if(t == CONS) {
+               Sexpr* careq = equal(car(a), car(b));
+               bool ist = careq->type == T;
+               sexpr_free(careq);
+               if(ist) {
                        return equal(cdr(a), cdr(b));
+               }
+       }
        // leaving everything else off for... reasons
        return from_nil();
 }
index 8a5b96502311db4c255b4584e798ba9adfeb89e7..6eabb6d45f32496de31f41a3f340a3fc892964cf 100644 (file)
@@ -273,6 +273,21 @@ void eval_tests() {
        run_eval_test("(quote abcd)");
        run_eval_test("(+ 3 6)");
        run_eval_test("((+ 3) 7)");
+       run_eval_test("(atom 55)");
+       run_eval_test("(atom (quote (1 2 3)))");
+       run_eval_test("(cons 1 2)");
+       run_eval_test("(car (cons 1 2))");
+       run_eval_test("(cdr (cons 1 2))");
+       run_eval_test("(if t (cons 1 2) (cons 2 1))");
+       run_eval_test("(if nil (cons 1 2) (cons 2 1))");
+       run_eval_test("(eq 1 1)");
+       run_eval_test("(eq 1 2)");
+       run_eval_test("(eq 1 (quote 1))");
+       run_eval_test("(eq (cons 1 2) (cons 1 3))");
+       run_eval_test("(eq (quote (1 2)) (cons 1 (cons 2 nil)))");
+       run_eval_test("(not 4326)");
+       run_eval_test("(not nil)");
+       run_eval_test("(def asdf 545)");
 }