fix memory leak
[lambda.git] / mem.c
1 #include <stdlib.h>
2 #include "lambda.h"
3 #include "print.h"
4
5 void lambda_free(struct lambda *t)
6 {
7 if(t != NULL){
8 if(t->refcount == 1){
9 switch(t->which){
10 case lambda_ident:
11 free(t->data.identifier.ident);
12 break;
13 case lambda_abs:
14 free(t->data.abstraction.ident);
15 lambda_free(t->data.abstraction.expr);
16 break;
17 case lambda_app:
18 lambda_free(t->data.application.expr1);
19 lambda_free(t->data.application.expr2);
20 break;
21 }
22 free(t);
23 } else {
24 t->refcount--;
25 }
26 }
27 }
28
29 void binding_replace(struct lambda *b, struct lambda *from, struct lambda *to)
30 {
31 switch(b->which){
32 case lambda_ident:
33 if(b->data.identifier.binding == from)
34 b->data.identifier.binding = to;
35 break;
36 case lambda_abs:
37 binding_replace(b->data.abstraction.expr, from, to);
38 break;
39 case lambda_app:
40 binding_replace(b->data.application.expr1, from, to);
41 binding_replace(b->data.application.expr2, from, to);
42 break;
43 }
44 }
45
46 struct lambda *copy(struct lambda *t)
47 {
48 struct lambda *c = make_lambda();
49 c->which = t->which;
50 switch(t->which){
51 case lambda_ident:
52 c->data.identifier.ident = strdup(t->data.identifier.ident);
53 c->data.identifier.binding = t->data.identifier.binding;
54 break;
55 case lambda_abs:
56 c->data.abstraction.ident = strdup(t->data.abstraction.ident);
57 c->data.abstraction.strict = t->data.abstraction.strict;
58 c->data.abstraction.expr = copy(t->data.abstraction.expr);
59 binding_replace(c->data.abstraction.expr, t, c);
60 break;
61 case lambda_app:
62 c->data.application.expr1 = copy(t->data.application.expr1);
63 c->data.application.expr2 = copy(t->data.application.expr2);
64 break;
65 }
66 return c;
67 }