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)
{
int maxdepth = 1000;
printf(" ");
- lambda_reduce($1, $1, &maxdepth);
+ lambda_reduce(&$1, &$1, &maxdepth);
lambda_print($1, NULL);
lambda_free($1);
}
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)
}
}
-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);