]> git.xonotic.org Git - xonotic/gmqcc.git/blob - ast.c
style-fix
[xonotic/gmqcc.git] / ast.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #include "ast.h"
6
7 #define ast_setfunc(me, fn, what) ( *(void**)&((me)->fn) = what )
8
9 #define ast_instantiate(T, ctx, destroyfn)                    \
10     T *self = (T*)mem_a(sizeof(T));                           \
11     ast_node_init((ast_node*)self, ctx);                      \
12     ast_setfunc(&((ast_node*)self)->node, destroy, destroyfn)
13
14 /* It must not be possible to get here. */
15 static void _ast_node_destroy(ast_node *self)
16 {
17     fprintf(stderr, "ast node missing destroy()\n");
18     abort();
19 }
20
21 /* Initialize main ast node aprts */
22 static void ast_node_init(ast_node *self, lex_ctx_t ctx)
23 {
24     self->node.context = ctx;
25     self->node.destroy = &_ast_node_destroy;
26 }
27
28 /* General expression initialization */
29 static void ast_expression_init(ast_expression *self,
30                                 ast_expression_codegen *codegen)
31 {
32     ast_setfunc(&self->expression, codegen, codegen);
33 }
34
35 ast_value* ast_value_new(lex_ctx_t ctx, const char *name, qc_type_t t)
36 {
37     ast_instantiate(ast_value, ctx, ast_value_delete);
38     ast_expression_init((ast_expression*)self,
39                         (ast_expression_codegen*)&ast_value_codegen);
40
41     self->name = name ? util_strdup(name) : NULL;
42     self->vtype = t;
43     self->next = NULL;
44     MEM_VECTOR_INIT(self, params);
45     self->has_constval = ifalse;
46     memset(&self->cvalue, 0, sizeof(self->cvalue));
47
48     self->ir_v = NULL;
49
50     return self;
51 }
52 MEM_VEC_FUNCTIONS(ast_value, ast_value*, params)
53
54 void ast_value_delete(ast_value* self)
55 {
56     size_t i;
57     if (self->name)
58         mem_d((void*)self->name);
59     for (i = 0; i < self->params_count; ++i)
60         ast_delete(self->params[i]);
61     MEM_VECTOR_CLEAR(self, params);
62     if (self->next)
63         ast_delete(self->next);
64     if (self->has_constval) {
65         switch (self->vtype)
66         {
67         case qc_string:
68             mem_d((void*)self->cvalue.vstring);
69             break;
70         /* NOTE: delete function? currently collected in
71          * the parser structure
72          */
73         default:
74             break;
75         }
76     }
77     mem_d(self);
78 }
79
80 void ast_value_set_name(ast_value *self, const char *name)
81 {
82     if (self->name)
83         mem_d((void*)self->name);
84     self->name = util_strdup(name);
85 }
86
87 ast_binary* ast_binary_new(lex_ctx_t ctx, qc_op_t op,
88                            ast_value* left, ast_value* right)
89 {
90     ast_instantiate(ast_binary, ctx, ast_binary_delete);
91     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)codegen);
92
93     self->op = op;
94     self->left = left;
95     self->right = right;
96
97     return self;
98 }
99
100 void ast_binary_delete(ast_binary *self)
101 {
102     mem_d(self);
103 }
104
105 ast_block* ast_block_new(lex_ctx_t ctx)
106 {
107     ast_instantiate(ast_block, ctx, ast_block_delete);
108     ast_expression_init((ast_expression*)self,
109                         (ast_expression_codegen*)&ast_block_codegen);
110
111     MEM_VECTOR_INIT(self, locals);
112     MEM_VECTOR_INIT(self, exprs);
113
114     return self;
115 }
116 MEM_VEC_FUNCTIONS(ast_block, ast_value*, locals)
117 MEM_VEC_FUNCTIONS(ast_block, ast_expression*, exprs)
118
119 void ast_block_delete(ast_block *self)
120 {
121     size_t i;
122     for (i = 0; i < self->locals_count; ++i)
123         ast_delete(self->locals[i]);
124     MEM_VECTOR_CLEAR(self, locals);
125     for (i = 0; i < self->exprs_count; ++i)
126         ast_delete(self->exprs[i]);
127     MEM_VECTOR_CLEAR(self, exprs);
128     mem_d(self);
129 }
130
131 ast_function* ast_function_new(lex_ctx_t ctx, const char *name, ast_value *vtype)
132 {
133     ast_instantiate(ast_function, ctx, ast_function_delete);
134
135     self->vtype = vtype;
136     self->name = name ? util_strdup(name) : NULL;
137     MEM_VECTOR_INIT(self, blocks);
138
139     return self;
140 }
141
142 MEM_VEC_FUNCTIONS(ast_function, ast_block*, blocks)
143
144 void ast_function_delete(ast_function *self)
145 {
146     size_t i;
147     if (self->name)
148         mem_d((void*)self->name);
149     if (self->vtype)
150         ast_value_delete(self->vtype);
151     for (i = 0; i < self->blocks_count; ++i)
152         ast_delete(self->blocks[i]);
153     MEM_VECTOR_CLEAR(self, blocks);
154     mem_d(self);
155 }