%define parse.error verbose %{ #include "lambda.h" #include "lambda.tab.h" #include "mem.h" #include "print.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.ident = strdup(i); r->data.identifier.revision = 0; 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.revision = 0; 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 = strdup(ident); head->value = value; printf("Declared %s as ", ident); lambda_print(value, NULL); 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); } void decls_free() { struct decllist *t; while(decls != NULL){ free(decls->ident); lambda_free(decls->value); t = decls->next; free(decls); decls = t; } } %} %token LAMBDA DOT OBRACE CBRACE IDENT FUNC SEMICOLON ASSIGN %% lambda : decl lambda | term { result = $$; } decl : FUNC ASSIGN term SEMICOLON { decls_prepend($1->data.identifier.ident, $3); lambda_free($1); } term : term appterm { $$ = make_application($1, $2); } | appterm { $$ = $1; } appterm : FUNC { $$ = decls_lookup($1->data.identifier.ident); lambda_free($1); } | IDENT { $$ = make_ident($1->data.identifier.ident); lambda_free($1); } | LAMBDA abstraction { $$ = $2; } | OBRACE term CBRACE { $$ = $2; } abstraction : IDENT abstraction { $$ = make_abstraction($1->data.identifier.ident, $2); lambda_free($1); } | DOT term { $$ = $2; }