X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=ast.c;h=3639168c5b9ef3105490856404fdd22c33a2e4a7;hb=434bf4b5b2df2e7ca4717ce2da6651f90256e7ad;hp=23790f8dde7ab14da2382dfbd0a686ee16118701;hpb=a82083bc78686e566f8d3a200473be230a31166b;p=xonotic%2Fgmqcc.git diff --git a/ast.c b/ast.c index 23790f8..3639168 100644 --- a/ast.c +++ b/ast.c @@ -1,7 +1,30 @@ +/* + * Copyright (C) 2012 + * Wolfgang Bumiller + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ #include #include #include +#include "gmqcc.h" #include "ast.h" #define ast_setfunc(me, fn, what) ( *(void**)&((me)->fn) = what ) @@ -23,6 +46,7 @@ static void ast_node_init(ast_node *self, lex_ctx_t ctx) { self->node.context = ctx; self->node.destroy = &_ast_node_destroy; + self->node.keep = false; } /* General expression initialization */ @@ -32,18 +56,19 @@ static void ast_expression_init(ast_expression *self, ast_setfunc(&self->expression, codegen, codegen); } -ast_value* ast_value_new(lex_ctx_t ctx, const char *name, qc_type_t t) +ast_value* ast_value_new(lex_ctx_t ctx, const char *name, int t, bool keep) { ast_instantiate(ast_value, ctx, ast_value_delete); ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_value_codegen); + self->expression.node.keep = keep; self->name = name ? util_strdup(name) : NULL; self->vtype = t; self->next = NULL; MEM_VECTOR_INIT(self, params); - self->has_constval = false; - memset(&self->cvalue, 0, sizeof(self->cvalue)); + self->isconst = false; + memset(&self->constval, 0, sizeof(self->constval)); self->ir_v = NULL; @@ -57,15 +82,15 @@ void ast_value_delete(ast_value* self) if (self->name) mem_d((void*)self->name); for (i = 0; i < self->params_count; ++i) - ast_delete(self->params[i]); + ast_unref(self->params[i]); MEM_VECTOR_CLEAR(self, params); - if (self->next) + if (self->next) /* delete, not unref, types are always copied */ ast_delete(self->next); - if (self->has_constval) { + if (self->isconst) { switch (self->vtype) { - case qc_string: - mem_d((void*)self->cvalue.vstring); + case TYPE_STRING: + mem_d((void*)self->constval.vstring); break; /* NOTE: delete function? currently collected in * the parser structure @@ -77,18 +102,19 @@ void ast_value_delete(ast_value* self) mem_d(self); } -void ast_value_set_name(ast_value *self, const char *name) +bool ast_value_set_name(ast_value *self, const char *name) { if (self->name) mem_d((void*)self->name); self->name = util_strdup(name); + return !!self->name; } -ast_binary* ast_binary_new(lex_ctx_t ctx, qc_op_t op, +ast_binary* ast_binary_new(lex_ctx_t ctx, int 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); + ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_binary_codegen); self->op = op; self->left = left; @@ -99,6 +125,28 @@ ast_binary* ast_binary_new(lex_ctx_t ctx, qc_op_t op, void ast_binary_delete(ast_binary *self) { + ast_unref(self->left); + ast_unref(self->right); + mem_d(self); +} + +ast_store* ast_store_new(lex_ctx_t ctx, int op, + ast_value *dest, ast_value *source) +{ + ast_instantiate(ast_store, ctx, ast_store_delete); + ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_store_codegen); + + self->op = op; + self->dest = dest; + self->source = source; + + return self; +} + +void ast_store_delete(ast_store *self) +{ + ast_unref(self->dest); + ast_unref(self->source); mem_d(self); } @@ -123,7 +171,7 @@ void ast_block_delete(ast_block *self) ast_delete(self->locals[i]); MEM_VECTOR_CLEAR(self, locals); for (i = 0; i < self->exprs_count; ++i) - ast_delete(self->exprs[i]); + ast_unref(self->exprs[i]); MEM_VECTOR_CLEAR(self, exprs); mem_d(self); } @@ -158,72 +206,23 @@ void ast_function_delete(ast_function *self) /* AST codegen aprt */ -static qbool ast_value_gen_global(ir_builder *ir, ast_value *self, ir_value **out) +/* Some dummies so it compiles... */ +bool ast_value_codegen(ast_value *self, ast_function *func, ir_value **out) { - ir_value *v; - *out = NULL; - - /* Generate functions */ - if (self->vtype == qc_function && self->has_constval) - { - /* Without has_constval it would be invalid... function pointers actually have - * type qc_pointer and next with type qc_function - */ - ast_function *func = self->cvalue.vfunc; - (void)func; - if (!ast_function_codegen(func, ir)) - return false; - - /* Here we do return NULL anyway */ - return true; - } - else if (self->vtype == qc_function && !self->has_constval) { - fprintf(stderr, - "!v->has_constval <- qc_function body missing - FIXME: remove when implementing prototypes\n"); - fprintf(stderr, "Value: %s\n", self->_name); - abort(); - } - - v = ir_builder_create_global(ir, self->_name, self->vtype); - self->ir_v = v; - - *out = v; - return true; -} - -qbool ast_value_codegen(ast_value *self, ast_function *func, ir_value **out) -{ - if (!func) - return ast_value_gen_global(parser.ir, self, out); - return false; + return false; } -qbool ast_function_codegen(ast_function *self, ir_builder *builder) +bool ast_block_codegen(ast_block *self, ast_function *func, ir_value **out) { - size_t i; - for (i = 0; i < self->blocks_count; ++i) - { - ast_expression *expr; - ir_value *out; - - expr = (ast_expression*)self->blocks[i]; - - if (!(expr->expression.codegen)(expr, self, &out)) - { - /* there was an error while building this expression... */ - return false; - } - (void)out; - } - return true; + return false; } -qbool ast_block_codegen(ast_block *self, ir_function *func, ir_value **out) +bool ast_store_codegen(ast_store *self, ast_function *func, ir_value **out) { return false; } -qbool ast_bin_store_codegen(ast_binary *self, ir_function *func, ir_value **out) +bool ast_binary_codegen(ast_binary *self, ast_function *func, ir_value **out) { return false; }