aboutsummaryrefslogtreecommitdiff
path: root/test/test.c
blob: a2f8a34b4955fb3f01a27c530740e02607c24218 (plain)
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");
}