%{ #include "lambda.h" #include "lambda.tab.h" #include "mem.h" struct lambda *result; struct decllist *decls = NULL; extern int yylex(); int yydebug=1; void yyerror(const char *str) { fprintf(stderr, "parse error: %s\n", str); } int yywrap() { return 1; } struct lambda *make_lambda() { return malloc(sizeof (struct lambda)); } struct lambda *make_ident(char *i) { struct lambda *r = make_lambda(); r->which = lambda_ident; r->data.identifier = strdup(i); return r; } struct lambda *make_abstraction(char *i, struct lambda *t) { struct lambda *r = make_lambda(); r->which = lambda_abs; r->data.abstraction.ident = strdup(i); r->data.abstraction.expr = t; return r; } struct lambda *make_application(struct lambda *t1, struct lambda *t2) { struct lambda *r = make_lambda(); r->which = lambda_app; r->data.application.expr1 = t1; r->data.application.expr2 = t2; return r; } void decls_prepend(char *ident, struct lambda *value) { struct decllist *head = malloc(sizeof (struct decllist)); head->next = decls; head->ident = ident; head->value = value; decls = head; } struct lambda *decls_lookup(char *ident) { struct decllist *c = decls; while(c != NULL){ if(strcmp(c->ident, ident) == 0) return copy(c->value); c = c->next; } return make_ident(ident); } %} %token LAMBDA DOT OBRACE CBRACE IDENT FUNC SEMICOLON ASSIGN %% lambda : decl lambda | term { result = $$; } decl : FUNC ASSIGN term SEMICOLON { decls_prepend($1->data.identifier, $3); } term : term appterm { $$ = make_application($1, $2); } | appterm { $$ = $1; } appterm : FUNC { $$ = decls_lookup($1->data.identifier); lambda_free($1); } | IDENT { $$ = make_ident($1->data.identifier); lambda_free($1); } | LAMBDA abstraction { $$ = $2; } | OBRACE term CBRACE { $$ = $2; } abstraction : IDENT abstraction { $$ = make_abstraction($1->data.identifier, $2); lambda_free($1); } | DOT term { $$ = $2; }