]> git.eli173.com Git - klapaucius/commitdiff
work on memory safety in parser
authorElijah Cohen <eli@eli173.com>
Thu, 15 Aug 2024 03:43:26 +0000 (22:43 -0500)
committerElijah Cohen <eli@eli173.com>
Thu, 15 Aug 2024 03:43:26 +0000 (22:43 -0500)
ideas.org
src/Makefile
src/parser.c
src/repl.c
src/sexpr.c
src/test.c

index 1f8dd5056f4fd4d8f789e87de687a487c22fa5fa..d27dcddbad62e1f4bf68a0838942692857879ed5 100644 (file)
--- a/ideas.org
+++ b/ideas.org
@@ -1,6 +1,15 @@
 MEMORY MANAGEMENT
 okay gonna start with making sure the parser is good... how?
 
+parser checklist:
+tokenize ok
+vals_parse ok
+balance_checker ok
+what if balance checker is unbalanced?
+cons_parse ?
+
+cons parse is tricky and needs lots of thinking about, but after that I think it's good
+
 let's think about every single allocation needed for some statements:
 (+ 4 6)
 eval structure:
index 7117825e2ba6fafe3e8918436037c2366a60fa90..325e039c2cbde77bd083537c573bc2c30c05d801 100644 (file)
@@ -1,5 +1,5 @@
 
-CC:=llvm-gcc
+#CC:=llvm-gcc
 
 # okay what the fuck am i doing with lex yacc generated stuff? just do it once? okay
 
index edd166a5e3e5fdd5e5e2b916a1341b54c0a10d9f..277796e0b565ad41a213d63a0e8be64fbe69bd3e 100644 (file)
 
 Sexpr* append_fragment(Sexpr* tokens, char* tok_start, size_t currlen) {
        // helper so that i dont repeat code
-                                       char* newsym = malloc(sizeof(char)*currlen);
-                               strncpy(newsym, tok_start, currlen);
-                               Sexpr* newtok = from_sym(newsym);
-                               free(newsym);
-                               return cons(newtok, tokens);
+       char* newsym = malloc(sizeof(char)*currlen);
+       strncpy(newsym, tok_start, currlen);
+       Sexpr* newtok = from_sym(newsym);
+       free(newsym);
+       return cons(newtok, tokens);
 }
 
+
 Sexpr* tokenize(char* s) {
        // note: also reverses
-       Sexpr* openparen = from_sym("(");
-       Sexpr* closeparen = from_sym(")");
        Sexpr* tokens = from_nil();
        char* tok_start = NULL;
        // returns a list of every token
@@ -32,10 +31,10 @@ Sexpr* tokenize(char* s) {
                                tokens = append_fragment(tokens, tok_start, currlen);
                        }
                        if(*s=='(') {
-                               tokens = cons(openparen, tokens);
+                               tokens = cons(from_sym("("), tokens);
                        }
                        else {
-                               tokens = cons(closeparen, tokens);
+                               tokens = cons(from_sym(")"), tokens);
                        }
                        already_in_sym = false;
                        currlen = 0;
@@ -113,13 +112,14 @@ bool balance_checker(Sexpr* tokens) {
 }
 
 Sexpr* cons_parse(Sexpr* tokens) {
-       Sexpr* reversed = reverse(tokens);
+       Sexpr* reversedptr = reverse(tokens);
+       Sexpr* reversed = reversedptr;
        // takes results from previous parsing ops, aka the forward-facing?
        Sexpr* heads_stack = from_nil();
        Sexpr* curr_head = from_nil();
        Sexpr* curr_car;
        while(reversed->type != NIL) {
-               curr_car = car(reversed);
+               curr_car = clone(car(reversed));
                Sexpr_Type cartype = curr_car->type;
                if(cartype == SYM && strcmp(")", curr_car->value.s)==0) {
                        heads_stack = cons(curr_head, heads_stack);
@@ -135,6 +135,9 @@ Sexpr* cons_parse(Sexpr* tokens) {
                }
                reversed = cdr(reversed);
        }
+       sexpr_free(reversedptr);
+       sexpr_free(heads_stack);
+       sexpr_free(curr_car);
        return curr_head;
 }
 
@@ -142,14 +145,21 @@ Sexpr* cons_parse(Sexpr* tokens) {
 Sexpr* parse(char* s) {
        //printf("s: %s\n", s);
        Sexpr* tokens = tokenize(s);
-       //printf("t: %s\n", sprint_sexpr(*tokens));
+       //printf("t: %s\n", sprint_sexpr(tokens));
        Sexpr* vals = vals_parse(tokens);
+       sexpr_free(vals);
+       vals = vals_parse(tokens);
+       sexpr_free(tokens);
        //printf("v: %s\n", sprint_sexpr(vals));
        if(!balance_checker(vals)) {
                printf("unbalanced parenthesis\n");
+               sexpr_free(vals);
                return NULL;
        }
+       //printf("v1: %s\n", sprint_sexpr(vals));
        Sexpr* done = cons_parse(vals);
+       //printf("v2: %s\n", sprint_sexpr(vals));
+       sexpr_free(vals);
        //printf("c: %s\n", sprint_sexpr(*done));
        return done;
 }
index 5123b07c544b800c940f3506cdec17e8113bb957..94420d8bbdb24cf7843b52b8da2d036c1a0ae42f 100644 (file)
@@ -34,7 +34,9 @@ int main(int argc, char** argv) {
                else {
                        //printf("- -%s\n", sprint_sexpr(in));
                        Sexpr* out = eval(car(in), env);
-                       printf(" - %s\n", sprint_sexpr(out));
+                       char* outstr = sprint_sexpr(out);
+                       printf(" - %s\n", outstr);
+                       free(outstr);
                }
                free(input);
        }
index 593283b08602f0e7978966f3bb95d6867391cc98..69c37c57585684198bde9ebfa2e888d6347d34ea 100644 (file)
@@ -159,11 +159,11 @@ Sexpr* clone(Sexpr* s) {
 Sexpr* reverse(Sexpr* s) {
        if(s->type != CONS) {
                // uhh this probably should never happen...
-               return s;
+               return clone(s);
        }
        Sexpr* out = from_nil();
        while(s->type != NIL) {
-               out = cons(car(s), out);
+               out = cons(clone(car(s)), out);
                s = cdr(s);
        }
        return out;
index 268d79ef7106888d85f505f6f630d072944e22d6..f77eca6ebec42149b5cf13d1ebc8cf5327da0728 100644 (file)
@@ -88,11 +88,19 @@ void test_dict() {
 void mem_parser() {
        printf("starting parser memory testing\n");
        char* toparse = "(car (cons 1 (cons 2 nil)))";
+       char* out;
        Sexpr* parsed;
-       while(1) {
+       unsigned long l = 0;
+       while(l < 10000) {
                parsed = parse(toparse);
+               out = sprint_sexpr(parsed);
                sexpr_free(parsed);
+               //printf("%s\n", out);
+               free(out);
+               //getchar();
+               l++;
        }
+       //sexpr_free(parsed);
 }
 
 void mem_hammer() {