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
123
124
125
126
127
128
129
130
131
|
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "ast.h"
#include "interpreter_context.h"
#include "interpreter.h"
static void test_interpreter_context(void) {
IMP_InterpreterContext *context = imp_interpreter_context_create();
assert(context);
int value;
value = imp_interpreter_context_var_get(context, "a");
assert(value == 0);
imp_interpreter_context_var_set(context, "a", 1);
value = imp_interpreter_context_var_get(context, "a");
assert(value == 1);
imp_interpreter_context_var_set(context, "b", 2);
value = imp_interpreter_context_var_get(context, "b");
assert(value == 2);
imp_interpreter_context_var_set(context, "c", 3);
value = imp_interpreter_context_var_get(context, "c");
assert(value == 3);
imp_interpreter_context_var_set(context, "a", 4);
value = imp_interpreter_context_var_get(context, "a");
assert(value == 4);
imp_interpreter_context_var_set(context, "b", 0);
value = imp_interpreter_context_var_get(context, "b");
assert(value == 0);
IMP_InterpreterContextVarIter *var_iter = imp_interpreter_context_var_iter_create(context);
IMP_InterpreterContextVarTableEntry *var_entry;
while ((var_entry = imp_interpreter_context_var_iter_next(var_iter))) {
if (strcmp(var_entry->key, "a") == 0) assert(var_entry->value == 4);
else if (strcmp(var_entry->key, "c") == 0) assert(var_entry->value == 3);
else assert(0);
}
imp_interpreter_context_var_iter_destroy(var_iter);
IMP_ASTNode *proc_a = imp_ast_procdecl("a", NULL, NULL, imp_ast_skip());
IMP_ASTNode *proc_b = imp_ast_procdecl("b", NULL, NULL, imp_ast_skip());
const IMP_ASTNode *proc;
proc = imp_interpreter_context_proc_get(context, "a");
assert(proc == NULL);
imp_interpreter_context_proc_set(context, "a", proc_a);
proc = imp_interpreter_context_proc_get(context, "a");
assert(proc != NULL);
imp_interpreter_context_proc_set(context, "b", proc_b);
proc = imp_interpreter_context_proc_get(context, "b");
assert(proc != NULL);
imp_interpreter_context_proc_set(context, "b", NULL);
proc = imp_interpreter_context_proc_get(context, "b");
assert(proc == NULL);
IMP_InterpreterContextProcIter *proc_iter = imp_interpreter_context_proc_iter_create(context);
IMP_InterpreterContextProcTableEntry *proc_entry;
while ((proc_entry = imp_interpreter_context_proc_iter_next(proc_iter))) {
if (strcmp(proc_entry->key, "a") == 0) assert(proc_entry->value != NULL);
else assert(0);
}
imp_interpreter_context_proc_iter_destroy(proc_iter);
imp_ast_destroy(proc_a);
imp_ast_destroy(proc_b);
imp_interpreter_context_destroy(context);
}
static void test_interpreter(void) {
IMP_ASTNode *factorial_procdecl = imp_ast_procdecl(
"factorial",
imp_ast_list(imp_ast_var("n"), NULL),
imp_ast_list(imp_ast_var("r"), NULL),
imp_ast_if(
imp_ast_rop(IMP_AST_ROP_LE, imp_ast_var("n"), imp_ast_int(0)),
imp_ast_assign(imp_ast_var("r"), imp_ast_int(1)),
imp_ast_seq(
imp_ast_assign(imp_ast_var("m"), imp_ast_aop(IMP_AST_AOP_SUB, imp_ast_var("n"), imp_ast_int(1))),
imp_ast_seq(
imp_ast_proccall(
"factorial",
imp_ast_list(imp_ast_var("m"), NULL),
imp_ast_list(imp_ast_var("r"), NULL)
),
imp_ast_assign(imp_ast_var("r"), imp_ast_aop(IMP_AST_AOP_MUL, imp_ast_var("r"), imp_ast_var("n")))
)
)
)
);
IMP_ASTNode *main = imp_ast_seq(
factorial_procdecl,
imp_ast_seq(
imp_ast_assign(imp_ast_var("n"), imp_ast_int(5)),
imp_ast_proccall(
"factorial",
imp_ast_list(imp_ast_var("n"), NULL),
imp_ast_list(imp_ast_var("r"), NULL)
)
)
);
IMP_InterpreterContext *context = imp_interpreter_context_create();
int result = imp_interpreter_interpret_ast(context, main);
assert(result == 0);
int factorial_result = imp_interpreter_context_var_get(context, "r");
assert(factorial_result == 120);
const IMP_ASTNode *proc = imp_interpreter_context_proc_get(context, "factorial");
assert(proc != NULL);
imp_ast_destroy(main);
imp_interpreter_context_destroy(context);
}
int main(void) {
printf("Starting tests...\n");
test_interpreter_context();
test_interpreter();
printf("All tests passed\n");
}
|