]> git.xonotic.org Git - xonotic/gmqcc.git/blob - ast.c
Importing ast.c
[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 #if 0
45         self->array = -1;
46 #endif
47         VEC_INIT(self, params);
48         self->has_constval = ifalse;
49         memset(&self->cvalue, 0, sizeof(self->cvalue));
50
51         self->ir_v = NULL;
52
53         return self;
54 }
55 MEM_VEC_FUNCTIONS(ast_value, ast_value*, params)
56
57 void ast_value_delete(ast_value* self)
58 {
59         size_t i;
60         if (self->_name)
61                 mem_d((void*)self->_name);
62         for (i = 0; i < self->params_count; ++i)
63                 ast_delete(self->params[i]);
64         VEC_CLEAR(self, params);
65         if (self->next)
66                 ast_delete(self->next);
67         if (self->has_constval) {
68                 switch (self->vtype)
69                 {
70                 case qc_string:
71                         mem_d((void*)self->cvalue.vstring);
72                         break;
73                 /* NOTE: delete function? currently collected in
74                  * the parser structure
75                  */
76                 default:
77                         break;
78                 }
79         }
80         mem_d(self);
81 }
82
83 void ast_value_set_name(ast_value *self, const char *name)
84 {
85         if (self->_name)
86                 mem_d((void*)self->_name);
87         self->_name = strdup(name);
88 }
89
90 ast_binary* ast_binary_new(filecontext_t ctx, qc_op_t op,
91                            ast_value* left, ast_value* right)
92 {
93         ast_instantiate(ast_binary, ctx, ast_binary_delete);
94         ast_expression_init((ast_expression*)self, (ast_expression_codegen*)codegen);
95
96         self->op = op;
97         self->left = left;
98         self->right = right;
99
100         return self;
101 }
102
103 void ast_binary_delete(ast_binary *self)
104 {
105         mem_d(self);
106 }
107
108 ast_block* ast_block_new(filecontext_t ctx)
109 {
110         ast_instantiate(ast_block, ctx, ast_block_delete);
111         ast_expression_init((ast_expression*)self,
112                             (ast_expression_codegen*)&ast_block_codegen);
113
114         VEC_INIT(self, locals);
115         VEC_INIT(self, exprs);
116
117         return self;
118 }
119 MEM_VEC_FUNCTIONS(ast_block, ast_value*, locals)
120 MEM_VEC_FUNCTIONS(ast_block, ast_expression*, exprs)
121
122 void ast_block_delete(ast_block *self)
123 {
124         size_t i;
125         for (i = 0; i < self->locals_count; ++i)
126                 ast_delete(self->locals[i]);
127         VEC_CLEAR(self, locals);
128         for (i = 0; i < self->exprs_count; ++i)
129                 ast_delete(self->exprs[i]);
130         VEC_CLEAR(self, exprs);
131         mem_d(self);
132 }
133
134 ast_function* ast_function_new(filecontext_t ctx, const char *name, ast_value *vtype)
135 {
136         ast_instantiate(ast_function, ctx, ast_function_delete);
137
138         self->vtype = vtype;
139         self->_name = name ? strdup(name) : NULL;
140         VEC_INIT(self, blocks);
141
142         return self;
143 }
144
145 MEM_VEC_FUNCTIONS(ast_function, ast_block*, blocks)
146
147 void ast_function_delete(ast_function *self)
148 {
149         size_t i;
150         if (self->_name)
151                 mem_d((void*)self->_name);
152         if (self->vtype)
153                 ast_value_delete(self->vtype);
154         for (i = 0; i < self->blocks_count; ++i)
155                 ast_delete(self->blocks[i]);
156         VEC_CLEAR(self, blocks);
157         mem_d(self);
158 }