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