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