]> git.eli173.com Git - klapaucius/commitdiff
plugged leaks in eval
authorElijah Cohen <cohen@eli173.com>
Fri, 16 Aug 2024 23:45:20 +0000 (23:45 +0000)
committerElijah Cohen <cohen@eli173.com>
Fri, 16 Aug 2024 23:45:20 +0000 (23:45 +0000)
ideas.org
src/builtins/arithmetic.c
src/builtins/core.c
src/eval.c
src/repl.c
src/test.c

index d27dcddbad62e1f4bf68a0838942692857879ed5..6ac79f06f40a501a9bf2ec0db6536237c0ee542f 100644 (file)
--- a/ideas.org
+++ b/ideas.org
@@ -1,6 +1,11 @@
 MEMORY MANAGEMENT
 okay gonna start with making sure the parser is good... how?
 
+bad thing about this:
+i have to dealloc each builtin when they're called,
+unless i wanna move where I figure out how many args I want
+
+
 parser checklist:
 tokenize ok
 vals_parse ok
index 4a686c40ca64ac27c3c16b08fa370339bf0893e2..18327c1f272aa5d46cd9a98f3c1494bb23c052af 100644 (file)
@@ -15,8 +15,13 @@ Sexpr* a_plus(Sexpr* b, Sexpr* rest, Sexpr* env) {
                return cons(b, rest);
        }
        Sexpr* args = b->value.b.args;
-       uint64_t m = unquote(eval(car(args), env))->value.u;
-       uint64_t n = unquote(eval(car(cdr(args)), env))->value.u;
+       Sexpr* i = eval(clone(car(args)), env);
+       Sexpr* j = eval(clone(car(cdr(args))), env);
+       uint64_t m = unquote(i)->value.u;
+       uint64_t n = unquote(j)->value.u;
+       sexpr_free(b);
+       sexpr_free(i);
+       sexpr_free(j);
        return cons(from_uint(m + n), rest);
 }
 
index 7b1ff6229dcc35f8456f2bfe9c6879accd76d4ae..69aced7fd409a5c563800e621486e1776ce8128a 100644 (file)
@@ -16,7 +16,9 @@ Sexpr* c_quote(Sexpr* b, Sexpr* rest, Sexpr* env) {
        if(CORE_QUOTE_ARGS != u64_get_num_args(b))
                return cons(b, rest);
        //return car(b->value.b.args);
-       return cons(from_quote(car(b->value.b.args)), rest);
+       Sexpr* arg = clone(car(b->value.b.args));
+       sexpr_free(b);
+       return cons(from_quote(arg), rest);
 }
 
 // redo the rest of these...
@@ -110,6 +112,9 @@ Sexpr* c_exit(Sexpr* b, Sexpr* rest, Sexpr* env) {
                return cons(b, rest);
        Sexpr* args = b->value.b.args;
        uint64_t value = car(args)->value.u;
+       sexpr_free(b);
+       sexpr_free(rest);
+       sexpr_free(env);
        exit(value);
        return NULL;
 }
index f5f25632b56fb68193b3111bf81b135d90a75f00..4f98b5b7fb5f79e8f16c394fe07a814aeda8e757 100644 (file)
 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?
@@ -20,33 +28,68 @@ Sexpr* eval(Sexpr* s, Sexpr* dict) {
                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");
@@ -55,8 +98,9 @@ Sexpr* apply_builtin(Sexpr* func, Sexpr* rest, Sexpr* env) {
        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
 }
index d72271569ba20c1af0580f3d639714309483227f..019c602269ef38b44b859e3ec81187dc36964924 100644 (file)
@@ -33,9 +33,11 @@ int main(int argc, char** argv) {
                }
                else {
                        //printf("- -%s\n", sprint_sexpr(in));
-                       Sexpr* out = eval(car(in), env);
+                       Sexpr* out = eval(clone(car(in)), env);
                        char* outstr = sprint_sexpr(out);
                        printf(" - %s\n", outstr);
+                       sexpr_free(in);
+                       sexpr_free(out);
                        free(outstr);
                }
                free(input);
index eb24d9879e106e2dec0c6a5e1c3bddc69b2dad7a..0c59b12834089a74dcc7de0f38307b066005d136 100644 (file)
@@ -210,16 +210,35 @@ void memtest_eval() {
        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);
 }