change printing
[lambda.git] / mem.c
diff --git a/mem.c b/mem.c
index 19c5c8e..270679b 100644 (file)
--- a/mem.c
+++ b/mem.c
@@ -1,12 +1,13 @@
 #include <stdlib.h>
 #include "lambda.h"
+#include "print.h"
 
 void lambda_free(struct lambda *t)
 {
        if(t != NULL){
                switch(t->which){
                case lambda_ident:
-                       free(t->data.identifier);
+                       free(t->data.identifier.ident);
                        break;
                case lambda_abs:
                        free(t->data.abstraction.ident);
@@ -17,6 +18,46 @@ void lambda_free(struct lambda *t)
                        lambda_free(t->data.application.expr2);
                        break;
                }
+               free(t);
        }
-       free(t);
+}
+
+void binding_replace(struct lambda *b, struct lambda *from, struct lambda *to)
+{
+       switch(b->which){
+       case lambda_ident:
+               if(b->data.identifier.binding == from)
+                       b->data.identifier.binding = to;
+               break;
+       case lambda_abs:
+               binding_replace(b->data.abstraction.expr, from, to);
+               break;
+       case lambda_app:
+               binding_replace(b->data.application.expr1, from, to);
+               binding_replace(b->data.application.expr2, from, to);
+               break;
+       }
+}
+
+struct lambda *copy(struct lambda *t)
+{
+       struct lambda *c = make_lambda();
+       c->which = t->which;
+       switch(t->which){
+       case lambda_ident:
+               c->data.identifier.ident = strdup(t->data.identifier.ident);
+               c->data.identifier.binding = t->data.identifier.binding;
+               break;
+       case lambda_abs:
+               c->data.abstraction.ident = strdup(t->data.abstraction.ident);
+               c->data.abstraction.strict = t->data.abstraction.strict;
+               c->data.abstraction.expr = copy(t->data.abstraction.expr);
+               binding_replace(c->data.abstraction.expr, t, c);
+               break;
+       case lambda_app:
+               c->data.application.expr1 = copy(t->data.application.expr1);
+               c->data.application.expr2 = copy(t->data.application.expr2);
+               break;
+       }
+       return c;
 }