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 *r = make_lambda();
r->which = lambda_ident;
r->data.identifier.ident = strdup(i);
- r->data.identifier.revision = 0;
+ r->data.identifier.binding = NULL;
return r;
}
+void lambda_bind(struct lambda *tob, struct lambda *binding, char *ident)
+{
+ switch(tob->which){
+ case lambda_ident:
+ if(strcmp(ident, tob->data.identifier.ident) == 0 && tob->data.identifier.binding == NULL)
+ tob->data.identifier.binding = binding;
+ break;
+ case lambda_abs:
+ lambda_bind(tob->data.abstraction.expr, binding, ident);
+ break;
+ case lambda_app:
+ lambda_bind(tob->data.application.expr1, binding, ident);
+ lambda_bind(tob->data.application.expr2, binding, ident);
+ break;
+ }
+}
+
struct lambda *make_abstraction(char *i, bool strict, struct lambda *t)
{
struct lambda *r = make_lambda();
r->which = lambda_abs;
r->data.abstraction.ident = strdup(i);
- r->data.abstraction.revision = 0;
r->data.abstraction.strict = strict;
r->data.abstraction.expr = t;
+ lambda_bind(t, r, i);
return r;
}
struct lambda *make_bool(bool b)
{
- return b
- ? make_abstraction("a", false, make_abstraction("b", false, make_ident("a")))
- : make_abstraction("a", false, make_abstraction("b", false, make_ident("b")));
+ return make_abstraction("a", false,
+ make_abstraction("b", false, make_ident(b ? "a" : "b")));
}
void decls_prepend(char *ident, struct lambda *value)
struct lambda *decls_lookup(char *ident)
{
- struct decllist *c = decls;
- while(c != NULL){
+ for(struct decllist *c = decls; c != NULL; c = c->next)
if(strcmp(c->ident, ident) == 0)
return copy(c->value);
- c = c->next;
- }
return make_ident(ident);
}
:
| lambda SEMICOLON program
lambda
- : term
- {
- int maxdepth = 1000;
- printf(" ");
- lambda_reduce(&$1, &$1, &maxdepth);
- lambda_print($1, NULL);
- lambda_free($1);
- }
- | FUNC func
+ : FUNC func
{
decls_prepend($1->data.identifier.ident, $2);
printf("%s = ", $1->data.identifier.ident);
lambda_print($2, NULL);
lambda_free($1);
}
+ | term
+ {
+ struct lambda *t = $1;
+ printf(" ");
+ for(unsigned int i = 0; i<999; i++)
+ if(!lambda_reduce(&t, &t, false))
+ break;
+ lambda_print(t, NULL);
+ lambda_free(t);
+ }
func
: ASSIGN term
{ $$ = $2; }