enum lambda_which {lambda_ident, lambda_abs, lambda_app};
struct lambda {
enum lambda_which which;
- unsigned int refcount;
union {
struct {
char *ident;
struct lambda *make_lambda()
{
- struct lambda *t = malloc(sizeof (struct lambda));
- t->refcount = 1;
- return t;
+ return malloc(sizeof (struct lambda));
}
struct lambda *make_ident(char *i)
struct lambda *t = $1;
printf(" ");
for(unsigned int i = 0; i<999; i++)
- if(!lambda_reduce(&t, &t, false))
+ if(!lambda_reduce(&t, &t, true))
break;
lambda_print(t, NULL);
putchar('\n');
void lambda_free(struct lambda *t)
{
if(t != NULL){
- 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--;
+ 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);
}
}
case lambda_ident:
if((*body)->data.identifier.binding == binding){
lambda_free(*body);
- *body = target;
- target->refcount++;
+ *body = copy(target);
}
break;
case lambda_abs:
if(lhs(t)->data.abstraction.strict)
lambda_reduce(&rhs(t), total, true);
- if(lhs(t) == rhs(t)){
- lhs(t)->refcount--;
- rhs(t) = copy(rhs(t));
- }
-
//In this abstraction we substitute the result with the rhs
lambda_print(*total, *t);
lambda_beta(lhs(t), &lhs(t)->data.abstraction.expr, rhs(t), *total);
- struct lambda *newt = lhs(t)->data.abstraction.expr;
- lhs(t)->data.abstraction.expr->refcount++;
+ struct lambda *newt = copy(lhs(t)->data.abstraction.expr);
lambda_free(*t);
*t = newt;