]> git.xonotic.org Git - xonotic/gmqcc.git/blob - test/ast-test.c
Testing CALLs in test-ast
[xonotic/gmqcc.git] / test / ast-test.c
1 #include "gmqcc.h"
2 #include "ast.h"
3
4 /* NOTE: it's a test - I'll abort() on epic-failure */
5
6 #ifdef assert
7 #   undef assert
8 #endif
9 /* (note: 'do {} while(0)' forces the need for a semicolon after assert() */
10 #define assert(x) do { if ( !(x) ) { printf("Assertion failed: %s\n", #x); abort(); } } while(0)
11
12 VECTOR_MAKE(ast_value*, globals);
13 VECTOR_MAKE(ast_function*, functions);
14
15 #include "ast-macros.h"
16
17 int main()
18 {
19     size_t i;
20
21     ir_builder     *ir;
22
23     TESTVARS();
24
25     DEFVAR(vi);
26     DEFVAR(vx);
27     DEFVAR(f0);
28     DEFVAR(f1);
29     DEFVAR(f5);
30     DEFVAR(sHello);
31     DEFVAR(print);
32
33     /* opts_debug = true; */
34
35 BUILTIN(print, TYPE_VOID, -1);
36 PARAM(TYPE_STRING, text);
37 ENDBUILTIN();
38
39     TESTINIT();
40 VAR(TYPE_FLOAT, f0);
41 VAR(TYPE_FLOAT, f1);
42 VAR(TYPE_FLOAT, f5);
43 VAR(TYPE_STRING, sHello);
44 MKCONSTFLOAT(f0, 0.0);
45 MKCONSTFLOAT(f1, 1.0);
46 MKCONSTFLOAT(f5, 5.0);
47 MKCONSTSTRING(sHello, "Hello, World\n");
48
49 FUNCTION(foo, TYPE_VOID);
50 ENDFUNCTION(foo);
51
52 FUNCTION(main, TYPE_VOID);
53
54     VAR(TYPE_FLOAT, vi);
55     VAR(TYPE_FLOAT, vx);
56
57     MKLOCAL(vi);
58     MKLOCAL(vx);
59
60     STATE(ASSIGN(STORE_F, vi, f0));
61     WHILE(BIN(LT, vi, f5));
62         STATE(ASSIGN(STORE_F, vx, BIN(MUL_F, vi, f5)));
63         STATE(ASSIGN(STORE_F, vi, BIN(ADD_F, vi, f1)));
64     ENDWHILE();
65
66     CALL(print)
67     CALLPARAM(sHello)
68     ENDCALL();
69
70 ENDFUNCTION(main);
71
72     ir = ir_builder_new("ast_test");
73     assert(ir);
74
75     /* gen globals */
76     for (i = 0; i < globals_elements; ++i) {
77         if (!ast_global_codegen(globals_data[i], ir)) {
78             assert(!"failed to generate global");
79         }
80     }
81
82     /* gen functions */
83     for (i = 0; i < functions_elements; ++i) {
84         if (!ast_function_codegen(functions_data[i], ir)) {
85             assert(!"failed to generate function");
86         }
87         if (!ir_function_finalize(functions_data[i]->ir_func))
88             assert(!"finalize on function failed...");
89     }
90
91
92     /* dump */
93     ir_builder_dump(ir, printf);
94
95     /* Now create a file */
96     if (!ir_builder_generate(ir, "test_ast.dat"))
97         printf("*** failed to generate code\n");
98
99     /* ir cleanup */
100     ir_builder_delete(ir);
101
102     /* cleanup */
103     /* Functions must be deleted FIRST since their expressions
104      * reference global variables.
105      */
106     for (i = 0; i < functions_elements; ++i) {
107         ast_function_delete(functions_data[i]);
108     }
109     if (functions_data)
110         mem_d(functions_data);
111
112     /* We must delete not only globals, but also the functions'
113      * ast_values (their type and name), that's why we added them to the globals vector.
114      */
115     for (i = 0; i < globals_elements; ++i) {
116         ast_value_delete(globals_data[i]);
117     }
118     if (globals_data)
119         mem_d(globals_data);
120     return 0;
121 }