add reference counter for future smarter allocations
authorMart Lubbers <mart@martlubbers.net>
Tue, 22 May 2018 10:39:28 +0000 (12:39 +0200)
committerMart Lubbers <mart@martlubbers.net>
Tue, 22 May 2018 10:39:28 +0000 (12:39 +0200)
lambda.h
lambda.y
mem.c
reduce.c
reduce.h

index ab28375..3eaa247 100644 (file)
--- a/lambda.h
+++ b/lambda.h
@@ -9,6 +9,7 @@
 enum lambda_which {lambda_ident, lambda_abs, lambda_app};
 struct lambda {
        enum lambda_which which;
+       unsigned int refcount;
        union {
                struct {
                        char *ident;
index 07c6b80..388693d 100644 (file)
--- a/lambda.y
+++ b/lambda.y
@@ -31,7 +31,9 @@ int yywrap()
 
 struct lambda *make_lambda()
 {
-       return malloc(sizeof (struct lambda));
+       struct lambda *t = malloc(sizeof (struct lambda));
+       t->refcount = 1;
+       return t;
 }
 
 struct lambda *make_ident(char *i)
@@ -119,7 +121,7 @@ lambda
                {
                        int maxdepth = 1000;
                        printf("     ");
-                       lambda_reduce($1, $1, &maxdepth);
+                       lambda_reduce(&$1, &$1, &maxdepth);
                        lambda_print($1, NULL);
                        lambda_free($1);
                }
diff --git a/mem.c b/mem.c
index 333038b..a0b18da 100644 (file)
--- a/mem.c
+++ b/mem.c
@@ -4,21 +4,25 @@
 void lambda_free(struct lambda *t)
 {
        if(t != NULL){
-               switch(t->which){
-               case lambda_ident:
-                       free(t->data.identifier.ident);
-                       break;
-               case lambda_abs:
-                       free(t->data.abstraction.ident);
-                       lambda_free(t->data.abstraction.expr);
-                       break;
-               case lambda_app:
-                       lambda_free(t->data.application.expr1);
-                       lambda_free(t->data.application.expr2);
-                       break;
+               if(t->refcount == 1){
+                       switch(t->which){
+                       case lambda_ident:
+                               free(t->data.identifier.ident);
+                               break;
+                       case lambda_abs:
+                               free(t->data.abstraction.ident);
+                               lambda_free(t->data.abstraction.expr);
+                               break;
+                       case lambda_app:
+                               lambda_free(t->data.application.expr1);
+                               lambda_free(t->data.application.expr2);
+                               break;
+                       }
+                       free(t);
+               } else {
+                       t->refcount--;
                }
        }
-       free(t);
 }
 
 struct lambda *copy(struct lambda *t)
index 19c193c..b5e64e1 100644 (file)
--- a/reduce.c
+++ b/reduce.c
@@ -71,27 +71,27 @@ void lambda_beta(struct lambda *ident, struct lambda *body, struct lambda *targe
        }
 }
 
-void lambda_reduce(struct lambda *t, struct lambda *total, int *maxdepth)
+void lambda_reduce(struct lambda **t, struct lambda **total, int *maxdepth)
 {
        if(*maxdepth == 0)
                return;
        struct lambda *t1, *t2;
-       if(t->which == lambda_app){
-               t1 = t->data.application.expr1;
-               t2 = t->data.application.expr2;
-               lambda_reduce(t1, total, maxdepth);
+       if((*t)->which == lambda_app){
+               t1 = (*t)->data.application.expr1;
+               t2 = (*t)->data.application.expr2;
+               lambda_reduce(&t1, total, maxdepth);
                if(t1->which == lambda_abs){
                        if(t1->data.abstraction.strict)
-                               lambda_reduce(t2, total, maxdepth);
-                       lambda_print(total, t);
+                               lambda_reduce(&t2, total, maxdepth);
+                       lambda_print(*total, *t);
                        printf("β -> ");
-                       lambda_beta(t1, t1->data.abstraction.expr, t2, total);
+                       lambda_beta(t1, t1->data.abstraction.expr, t2, *total);
                        lambda_free(t2);
                        t2 = copy(t1->data.abstraction.expr);
                        if(total == t)
-                               *total = *t2;
+                               **total = *t2;
                        lambda_free(t1);
-                       *t = *t2;
+                       **t = *t2;
                        free(t2);
                        (*maxdepth)--;
                        lambda_reduce(t, total, maxdepth);
index 9d9fa54..833c7a9 100644 (file)
--- a/reduce.h
+++ b/reduce.h
@@ -3,5 +3,5 @@
 
 #include "lambda.h"
 
-void lambda_reduce(struct lambda *t, struct lambda *total, int *maxdepth);
+void lambda_reduce(struct lambda **t, struct lambda **total, int *maxdepth);
 #endif