Fix memory leaks and verbosify reduction
[lambda.git] / lambda.y
1 %define parse.error verbose
2 %{
3 #include "lambda.h"
4 #include "lambda.tab.h"
5 #include "mem.h"
6 #include "print.h"
7
8 struct lambda *result;
9 struct decllist *decls = NULL;
10 extern int yylex();
11
12 int yydebug=1;
13 void yyerror(const char *str)
14 {
15 fprintf(stderr, "parse error: %s\n", str);
16 }
17
18 int yywrap()
19 {
20 return 1;
21 }
22
23 struct lambda *make_lambda()
24 {
25 return malloc(sizeof (struct lambda));
26 }
27
28 struct lambda *make_ident(char *i)
29 {
30 struct lambda *r = make_lambda();
31 r->which = lambda_ident;
32 r->data.identifier.ident = strdup(i);
33 r->data.identifier.revision = 0;
34 return r;
35 }
36
37 struct lambda *make_abstraction(char *i, struct lambda *t)
38 {
39 struct lambda *r = make_lambda();
40 r->which = lambda_abs;
41 r->data.abstraction.ident = strdup(i);
42 r->data.abstraction.revision = 0;
43 r->data.abstraction.expr = t;
44 return r;
45 }
46
47 struct lambda *make_application(struct lambda *t1, struct lambda *t2)
48 {
49 struct lambda *r = make_lambda();
50 r->which = lambda_app;
51 r->data.application.expr1 = t1;
52 r->data.application.expr2 = t2;
53 return r;
54 }
55
56 void decls_prepend(char *ident, struct lambda *value)
57 {
58 struct decllist *head = malloc(sizeof (struct decllist));
59 head->next = decls;
60 head->ident = strdup(ident);
61 head->value = value;
62 printf("Declared %s as ", ident);
63 lambda_print(value, NULL);
64 decls = head;
65 }
66
67 struct lambda *decls_lookup(char *ident)
68 {
69 struct decllist *c = decls;
70 while(c != NULL){
71 if(strcmp(c->ident, ident) == 0)
72 return copy(c->value);
73 c = c->next;
74 }
75 return make_ident(ident);
76 }
77
78 void decls_free()
79 {
80 struct decllist *t;
81 while(decls != NULL){
82 free(decls->ident);
83 lambda_free(decls->value);
84 t = decls->next;
85 free(decls);
86 decls = t;
87 }
88 }
89
90 %}
91
92 %token LAMBDA DOT OBRACE CBRACE IDENT FUNC SEMICOLON ASSIGN
93
94 %%
95
96 lambda
97 : decl lambda
98 | term
99 { result = $$; }
100 decl
101 : FUNC ASSIGN term SEMICOLON
102 {
103 decls_prepend($1->data.identifier.ident, $3);
104 lambda_free($1);
105 }
106 term
107 : term appterm
108 { $$ = make_application($1, $2); }
109 | appterm
110 { $$ = $1; }
111 appterm
112 : FUNC
113 {
114 $$ = decls_lookup($1->data.identifier.ident);
115 lambda_free($1);
116 }
117 | IDENT
118 {
119 $$ = make_ident($1->data.identifier.ident);
120 lambda_free($1);
121 }
122 | LAMBDA abstraction
123 { $$ = $2; }
124 | OBRACE term CBRACE
125 { $$ = $2; }
126 abstraction
127 : IDENT abstraction
128 {
129 $$ = make_abstraction($1->data.identifier.ident, $2);
130 lambda_free($1);
131 }
132 | DOT term
133 { $$ = $2; }