From: Wolfgang (Blub) Bumiller Date: Wed, 25 Apr 2012 11:17:37 +0000 (+0200) Subject: Importing ast.c X-Git-Tag: 0.1-rc1~631 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=40f70d075ea77b80cc35d23cff3aa9d619c95578;p=xonotic%2Fgmqcc.git Importing ast.c --- diff --git a/ast.c b/ast.c new file mode 100644 index 0000000..d976d80 --- /dev/null +++ b/ast.c @@ -0,0 +1,158 @@ +#include +#include +#include + +#include "ast.h" + +#define ast_setfunc(me, fn, what) ( *(void**)&((me)->fn) = what ) + +#define ast_instantiate(T, ctx, destroyfn) \ + T *self = (T*)mem_a(sizeof(T)); \ + ast_node_init((ast_node*)self, ctx); \ + ast_setfunc(&((ast_node*)self)->node, destroy, destroyfn) + +/* It must not be possible to get here. */ +static void _ast_node_destroy(ast_node *self) +{ + fprintf(stderr, "ast node missing destroy()\n"); + abort(); +} + +/* Initialize main ast node aprts */ +static void ast_node_init(ast_node *self, lex_ctx_t ctx) +{ + self->node.context = ctx; + self->node.destroy = &_ast_node_destroy; +} + +/* General expression initialization */ +static void ast_expression_init(ast_expression *self, + ast_expression_codegen *codegen) +{ + ast_setfunc(&self->expression, codegen, codegen); +} + +ast_value* ast_value_new(lex_ctx_t ctx, const char *name, qc_type_t t) +{ + ast_instantiate(ast_value, ctx, ast_value_delete); + ast_expression_init((ast_expression*)self, + (ast_expression_codegen*)&ast_value_codegen); + + self->name = name ? util_strdup(name) : NULL; + self->vtype = t; + self->next = NULL; +#if 0 + self->array = -1; +#endif + VEC_INIT(self, params); + self->has_constval = ifalse; + memset(&self->cvalue, 0, sizeof(self->cvalue)); + + self->ir_v = NULL; + + return self; +} +MEM_VEC_FUNCTIONS(ast_value, ast_value*, params) + +void ast_value_delete(ast_value* self) +{ + size_t i; + if (self->_name) + mem_d((void*)self->_name); + for (i = 0; i < self->params_count; ++i) + ast_delete(self->params[i]); + VEC_CLEAR(self, params); + if (self->next) + ast_delete(self->next); + if (self->has_constval) { + switch (self->vtype) + { + case qc_string: + mem_d((void*)self->cvalue.vstring); + break; + /* NOTE: delete function? currently collected in + * the parser structure + */ + default: + break; + } + } + mem_d(self); +} + +void ast_value_set_name(ast_value *self, const char *name) +{ + if (self->_name) + mem_d((void*)self->_name); + self->_name = strdup(name); +} + +ast_binary* ast_binary_new(filecontext_t ctx, qc_op_t op, + ast_value* left, ast_value* right) +{ + ast_instantiate(ast_binary, ctx, ast_binary_delete); + ast_expression_init((ast_expression*)self, (ast_expression_codegen*)codegen); + + self->op = op; + self->left = left; + self->right = right; + + return self; +} + +void ast_binary_delete(ast_binary *self) +{ + mem_d(self); +} + +ast_block* ast_block_new(filecontext_t ctx) +{ + ast_instantiate(ast_block, ctx, ast_block_delete); + ast_expression_init((ast_expression*)self, + (ast_expression_codegen*)&ast_block_codegen); + + VEC_INIT(self, locals); + VEC_INIT(self, exprs); + + return self; +} +MEM_VEC_FUNCTIONS(ast_block, ast_value*, locals) +MEM_VEC_FUNCTIONS(ast_block, ast_expression*, exprs) + +void ast_block_delete(ast_block *self) +{ + size_t i; + for (i = 0; i < self->locals_count; ++i) + ast_delete(self->locals[i]); + VEC_CLEAR(self, locals); + for (i = 0; i < self->exprs_count; ++i) + ast_delete(self->exprs[i]); + VEC_CLEAR(self, exprs); + mem_d(self); +} + +ast_function* ast_function_new(filecontext_t ctx, const char *name, ast_value *vtype) +{ + ast_instantiate(ast_function, ctx, ast_function_delete); + + self->vtype = vtype; + self->_name = name ? strdup(name) : NULL; + VEC_INIT(self, blocks); + + return self; +} + +MEM_VEC_FUNCTIONS(ast_function, ast_block*, blocks) + +void ast_function_delete(ast_function *self) +{ + size_t i; + if (self->_name) + mem_d((void*)self->_name); + if (self->vtype) + ast_value_delete(self->vtype); + for (i = 0; i < self->blocks_count; ++i) + ast_delete(self->blocks[i]); + VEC_CLEAR(self, blocks); + mem_d(self); +}