-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.c
122 lines (116 loc) · 3.34 KB
/
main.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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/* Usage examples */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stddef.h>
#include "inference.h"
static void
print_term(Term *t)
{
if(!t) {
printf("NULL\n");
return;
}
switch(t->type) {
case IDENTIFIER:
printf("%d | %s\n", t->type, t->name ? t->name : NULL);
break;
case APPLY:
printf("%d | apply\n", t->type);
break;
case LAMBDA:
printf("%d | fn %s\n", t->type, t->v ? t->v : NULL);
break;
case LET:
printf("%d | let %s\n", t->type, t->v ? t->v : NULL);
break;
case LETREC:
printf("%d | letrec %s\n", t->type, t->v ? t->v : NULL);
break;
}
return;
}
#define MAX_TYPES 200
int
main(void)
{
Type types[MAX_TYPES];
Inferencer ctx = make_ctx(types, MAX_TYPES);
Type *var1 = Var(&ctx);
Type *var2 = Var(&ctx);
Type *pair_type = make_type(&ctx);
*pair_type = (Type){.type = OPERATOR,
.name = "*",
.args = 2,
.types = {var1, var2}};
Type *var3 = Var(&ctx);
Env envs[7] = {
{.name = "pair",
.node = Function(&ctx, var1, Function(&ctx, var2, pair_type)),
.next = &envs[1]},
{.name = "true", .node = Bool(&ctx), .next = &envs[2]},
{
.name = "cond",
.node = Function(&ctx, Bool(&ctx),
Function(&ctx, var3,
Function(&ctx, var3, var3))),
.next = &envs[3],
},
{.name = "zero",
.node = Function(&ctx, Integer(&ctx), Bool(&ctx)),
.next = &envs[4]},
{.name = "pred",
.node = Function(&ctx, Integer(&ctx), Integer(&ctx)),
.next = &envs[5]},
{.name = "times",
.node = Function(&ctx, Integer(&ctx),
Function(&ctx, Integer(&ctx), Integer(&ctx))),
.next = &envs[6]},
{.name = "factorial",
.node = Function(&ctx, Integer(&ctx), Integer(&ctx)),
.next = NULL}};
Env *my_env = envs;
Term factorial = {
.type = LETREC,
.v = "factorial",
.defn = &(Term){
.type = LAMBDA,
.v = "n",
.body = &(Term){
.type = APPLY,
.fn = &(Term){
.type = APPLY,
.fn = &(Term){
.type = APPLY,
.fn = &(Term){
.type = IDENTIFIER,
.name = "cond"},
.arg = &(Term){.type = APPLY, .fn = &(Term){.type = IDENTIFIER, .name = "zero"}, .arg = &(Term){.type = IDENTIFIER, .name = "n"}}},
.arg = &(Term){.type = IDENTIFIER, .name = "1"}},
.arg = &(Term){.type = APPLY, .fn = &(Term){.type = APPLY, .fn = &(Term){.type = IDENTIFIER, .name = "times"}, .arg = &(Term){.type = IDENTIFIER, .name = "n"}}, .arg = &(Term){.type = APPLY, .fn = &(Term){.type = IDENTIFIER, .name = "factorial"}, .arg = &(Term){.type = APPLY, .fn = &(Term){.type = IDENTIFIER, .name = "pred"}, .arg = &(Term){.type = IDENTIFIER, .name = "n"}}}}}},
.body = &(Term){.type = APPLY, .fn = &(Term){.type = IDENTIFIER, .name = "factorial"}, .arg = &(Term){.type = IDENTIFIER, .name = "5"}}};
Type *t = NULL;
printf("ctx.use before stuff: %d locals: %d\n", ctx.use, ctx.locals);
clock_t total = 0;
#define ITERATIONS 1000000
for(int i = 0; i < ITERATIONS; ++i) {
ctx.use = 17; /* Experimentally determined */
ctx.locals = 0;
clock_t tic = clock();
(void)analyze(&ctx, &factorial, my_env);
clock_t toc = clock();
total += toc - tic;
if(ctx.error)
break;
}
if(ctx.error) {
print_error(&factorial, ctx.error, ctx.error_msg);
return 1;
}
t = get_result(&ctx);
fprintf(stdout, "Iterations: %d Total time: %f ns\n", ITERATIONS,
(double)(total / CLOCKS_PER_SEC * 1000000));
print(&factorial, t);
printf("DEBUG: %d\n", ctx.use);
return 0;
}