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