]> git.xonotic.org Git - xonotic/gmqcc.git/blob - test/ast-macros.h
ast macros to create a field, generating fields in ast-test
[xonotic/gmqcc.git] / test / ast-macros.h
1 #ifndef TEST_AST_MACROS_HDR
2 #define TEST_AST_MACROS_HDR
3
4 #define TESTVARS()   \
5 ast_block *curblock; \
6 lex_ctx    ctx
7
8 #define TESTINIT()   \
9 ctx.file = NULL;     \
10 ctx.line = 1;
11
12 #define DEFVAR(name) \
13 ast_value *name
14
15 #define VAR(type, name) \
16 name = ast_value_new(ctx, #name, type)
17
18 #define VARnamed(type, name, varname) \
19 name = ast_value_new(ctx, #varname, type)
20
21 #define MKGLOBAL(name) \
22 assert(globals_add(name) >= 0)
23
24 #define FIELD(type, name) \
25 name = ast_value_new(ctx, #name, TYPE_FIELD);                  \
26 do {                                                           \
27     ast_value *field_##name = ast_value_new(ctx, #name, type); \
28     name->expression.next = (ast_expression*)field_##name;     \
29     MKFIELD(name);                                             \
30 } while (0)
31
32 #define MKFIELD(name) \
33 assert(fields_add(name) >= 0)
34
35 #define MKCONSTFLOAT(name, value)  \
36 do {                               \
37     name->isconst = true;          \
38     name->constval.vfloat = value; \
39     MKGLOBAL(name);                \
40 } while(0)
41
42 #define MKCONSTSTRING(name, value)               \
43 do {                                             \
44     name->isconst = true;                        \
45     name->constval.vstring = util_strdup(value); \
46     MKGLOBAL(name);                              \
47 } while(0)
48
49 #define STATE(a)                                 \
50 do {                                             \
51     ast_expression *exp = (ast_expression*)(a);  \
52     assert(ast_block_exprs_add(curblock, exp)); \
53 } while(0)
54
55 #define ASSIGN(op, a, b) \
56 (ast_expression*)ast_store_new(ctx, INSTR_##op, (ast_expression*)(a), (ast_expression*)(b))
57
58 #define BIN(op, a, b) \
59 (ast_expression*)ast_binary_new(ctx, INSTR_##op, (ast_expression*)(a), (ast_expression*)(b))
60
61 #define CALL(what)                                             \
62 do {                                                           \
63     ast_call *call = ast_call_new(ctx, (ast_expression*)what); \
64
65 #define CALLPARAM(x)                                       \
66     assert(ast_call_params_add(call, (ast_expression*)x));
67
68 #define ENDCALL()                                \
69     STATE(call);                                 \
70 } while(0)
71
72 #define WHILE(cond)                                    \
73 do {                                                   \
74     ast_expression *wh_cond = (ast_expression*)(cond); \
75     ast_block *wh_body = ast_block_new(ctx);           \
76     ast_block *oldcur = curblock;                      \
77     ast_loop  *loop;                                   \
78     curblock = wh_body;
79
80 #define ENDWHILE()                                             \
81     curblock = oldcur;                                         \
82     loop = ast_loop_new(ctx, NULL, (ast_expression*)wh_cond,   \
83                         NULL, NULL, (ast_expression*)wh_body); \
84     assert(loop);                                              \
85     STATE(loop);                                               \
86 } while(0)
87
88 #define BUILTIN(name, outtype, number)                              \
89 do {                                                                \
90     ast_function *func_##name;                                      \
91     ast_value    *thisfuncval;                                      \
92     ast_function *thisfunc;                                         \
93     DEFVAR(return_##name);                                          \
94     VARnamed(TYPE_FUNCTION, name, name);                            \
95     VARnamed(outtype, return_##name, "#returntype");                \
96     name->expression.next = (ast_expression*)return_##name;         \
97     MKGLOBAL(name);                                                 \
98     func_##name = ast_function_new(ctx, #name, name);               \
99     thisfunc = func_##name;                                         \
100     (void)thisfunc;                                                 \
101     thisfuncval = name;                                             \
102     (void)thisfuncval;                                              \
103     assert(functions_add(func_##name) >= 0);                        \
104     func_##name->builtin = number;
105
106 #define ENDBUILTIN() } while(0)
107
108 #define PARAM(ptype, name)                           \
109 do {                                                 \
110     DEFVAR(parm);                                    \
111     VARnamed(ptype, parm, name);                     \
112     assert(ast_value_params_add(thisfuncval, parm)); \
113 } while(0)
114
115 #define FUNCTION(name, outtype)                                   \
116 do {                                                              \
117     ast_function *thisfunc;                                       \
118     ast_function *func_##name;                                    \
119     ast_block    *my_funcblock;                                   \
120     DEFVAR(var_##name);                                           \
121     DEFVAR(return_##name);                                        \
122     VARnamed(TYPE_FUNCTION, var_##name, name);                    \
123     VARnamed(outtype, return_##name, "#returntype");              \
124     var_##name->expression.next = (ast_expression*)return_##name; \
125     MKGLOBAL(var_##name);                                         \
126     func_##name = ast_function_new(ctx, #name, var_##name);       \
127     thisfunc = func_##name;                                       \
128     (void)thisfunc;                                               \
129     assert(functions_add(func_##name) >= 0);                      \
130     my_funcblock = ast_block_new(ctx);                            \
131     assert(my_funcblock);                                         \
132     assert(ast_function_blocks_add(func_##name, my_funcblock));   \
133     curblock = my_funcblock;
134
135 #define MKLOCAL(var) \
136     assert(ast_block_locals_add(curblock, var))
137
138 #define ENDFUNCTION(name) \
139 } while(0)
140
141 #endif