-
Notifications
You must be signed in to change notification settings - Fork 0
/
eval.c
52 lines (50 loc) · 1.34 KB
/
eval.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <stdbool.h>
#include <stdio.h>
#include "ast.h"
#include "eval.h"
struct ast_node *rebind_placeholder(
char placeholder,
struct ast_node *node,
struct ast_node *val,
unsigned debruijn
) {
struct ast_node *res;
res = node;
switch (node->type) {
case A_APP:
res = ast_new_app(
rebind_placeholder(placeholder, node->val.app.left, val, debruijn),
rebind_placeholder(placeholder, node->val.app.right, val, debruijn)
);
break;
case A_FUNC:
if (placeholder != node->val.func.param) {
res = ast_new_func(
node->val.func.param,
rebind_placeholder(placeholder, node->val.func.body, val, debruijn + 1)
);
}
break;
case A_IDENT:
if (node->val.var.debruijn == debruijn)
res = ast_new_var(val->val.var.chr, 0);
break;
}
return res;
}
// reduce an expression by a single beta-reduction
struct ast_node *single_reduction(struct ast_node *node) {
if (node->type == A_APP) {
if (node->val.app.left->type == A_FUNC) {
return rebind_placeholder(
node->val.app.left->val.func.param,
node->val.app.left->val.func.body,
node->val.app.right,
1
);
}
struct ast_node *sub = single_reduction(node->val.app.left);
if (sub) return ast_new_app(sub, node->val.app.right);
}
return NULL;
}