From da9a4fef295154759ca41bf7932b52bb26432502 Mon Sep 17 00:00:00 2001 From: "Wolfgang (Blub) Bumiller" Date: Thu, 3 May 2012 12:12:22 +0200 Subject: [PATCH] Type information moved to ast_expression from ast_value, every ast node should in theory know its type - it is important for dereferencing pointers or entity fields, to figure out the output type. Eg. so that ast_entfield knows what kind of OP_LOAD it needs to use --- ast.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++--------- ast.h | 13 ++++++-- 2 files changed, 94 insertions(+), 16 deletions(-) diff --git a/ast.c b/ast.c index 22fbe7a..4b439d4 100644 --- a/ast.c +++ b/ast.c @@ -55,6 +55,52 @@ static void ast_expression_init(ast_expression *self, ast_expression_codegen *codegen) { self->expression.codegen = codegen; + self->expression.vtype = TYPE_VOID; + self->expression.next = NULL; +} + +static void ast_expression_delete(ast_expression *self) +{ + if (self->expression.next) + ast_delete(self->expression.next); +} + +static void ast_expression_delete_full(ast_expression *self) +{ + ast_expression_delete(self); + mem_d(self); +} + +static ast_expression* ast_type_copy(lex_ctx ctx, const ast_expression *ex) +{ + const ast_expression_common *cpex; + ast_expression_common *selfex; + + if (!ex) + return NULL; + else + { + ast_instantiate(ast_expression, ctx, ast_expression_delete_full); + + cpex = &ex->expression; + selfex = &self->expression; + + selfex->vtype = cpex->vtype; + if (cpex->next) + { + selfex->next = ast_type_copy(ctx, cpex->next); + if (!selfex->next) { + mem_d(self); + return NULL; + } + } + else + selfex->next = NULL; + + /* This may never be codegen()d */ + selfex->codegen = NULL; + return self; + } } ast_value* ast_value_new(lex_ctx ctx, const char *name, int t) @@ -65,8 +111,8 @@ ast_value* ast_value_new(lex_ctx ctx, const char *name, int t) self->expression.node.keep = true; /* keep */ self->name = name ? util_strdup(name) : NULL; - self->vtype = t; - self->next = NULL; + self->expression.vtype = t; + self->expression.next = NULL; MEM_VECTOR_INIT(self, params); self->isconst = false; memset(&self->constval, 0, sizeof(self->constval)); @@ -85,10 +131,8 @@ void ast_value_delete(ast_value* self) for (i = 0; i < self->params_count; ++i) ast_value_delete(self->params[i]); /* delete, the ast_function is expected to die first */ MEM_VECTOR_CLEAR(self, params); - if (self->next) /* delete, not unref, types are always copied */ - ast_delete(self->next); if (self->isconst) { - switch (self->vtype) + switch (self->expression.vtype) { case TYPE_STRING: mem_d((void*)self->constval.vstring); @@ -104,6 +148,7 @@ void ast_value_delete(ast_value* self) break; } } + ast_expression_delete((ast_expression*)self); mem_d(self); } @@ -132,14 +177,33 @@ void ast_binary_delete(ast_binary *self) { ast_unref(self->left); ast_unref(self->right); + ast_expression_delete((ast_expression*)self); mem_d(self); } ast_entfield* ast_entfield_new(lex_ctx ctx, ast_expression *entity, ast_expression *field) { + const ast_expression *outtype; + ast_instantiate(ast_entfield, ctx, ast_entfield_delete); + + if (field->expression.vtype != TYPE_FIELD) { + mem_d(self); + return NULL; + } + + outtype = field->expression.next; + if (!outtype) { + mem_d(self); + /* Error: field has no type... */ + return NULL; + } + ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_entfield_codegen); + self->expression.vtype = outtype->expression.vtype; + self->expression.next = ast_type_copy(ctx, outtype->expression.next); + self->entity = entity; self->field = field; @@ -150,6 +214,7 @@ void ast_entfield_delete(ast_entfield *self) { ast_unref(self->entity); ast_unref(self->field); + ast_expression_delete((ast_expression*)self); mem_d(self); } @@ -175,6 +240,7 @@ void ast_ifthen_delete(ast_ifthen *self) ast_unref(self->cond); ast_unref(self->on_true); ast_unref(self->on_false); + ast_expression_delete((ast_expression*)self); mem_d(self); } @@ -201,6 +267,7 @@ void ast_ternary_delete(ast_ternary *self) ast_unref(self->cond); ast_unref(self->on_true); ast_unref(self->on_false); + ast_expression_delete((ast_expression*)self); mem_d(self); } @@ -221,6 +288,7 @@ void ast_store_delete(ast_store *self) { ast_unref(self->dest); ast_unref(self->source); + ast_expression_delete((ast_expression*)self); mem_d(self); } @@ -247,6 +315,7 @@ void ast_block_delete(ast_block *self) for (i = 0; i < self->locals_count; ++i) ast_delete(self->locals[i]); MEM_VECTOR_CLEAR(self, locals); + ast_expression_delete((ast_expression*)self); mem_d(self); } @@ -256,7 +325,7 @@ ast_function* ast_function_new(lex_ctx ctx, const char *name, ast_value *vtype) if (!vtype || vtype->isconst || - vtype->vtype != TYPE_FUNCTION) + vtype->expression.vtype != TYPE_FUNCTION) { mem_d(self); return NULL; @@ -331,7 +400,7 @@ bool ast_value_codegen(ast_value *self, ast_function *func, bool lvalue, ir_valu bool ast_global_codegen(ast_value *self, ir_builder *ir) { ir_value *v = NULL; - if (self->isconst && self->vtype == TYPE_FUNCTION) + if (self->isconst && self->expression.vtype == TYPE_FUNCTION) { ir_function *func = ir_builder_create_function(ir, self->name); if (!func) @@ -342,12 +411,12 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir) return true; } - v = ir_builder_create_global(ir, self->name, self->vtype); + v = ir_builder_create_global(ir, self->name, self->expression.vtype); if (!v) return false; if (self->isconst) { - switch (self->vtype) + switch (self->expression.vtype) { case TYPE_FLOAT: if (!ir_value_set_float(v, self->constval.vfloat)) @@ -367,7 +436,7 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir) */ goto error; default: - printf("TODO: global constant type %i\n", self->vtype); + printf("TODO: global constant type %i\n", self->expression.vtype); break; } } @@ -384,7 +453,7 @@ error: /* clean up */ bool ast_local_codegen(ast_value *self, ir_function *func) { ir_value *v = NULL; - if (self->isconst && self->vtype == TYPE_FUNCTION) + if (self->isconst && self->expression.vtype == TYPE_FUNCTION) { /* Do we allow local functions? I think not... * this is NOT a function pointer atm. @@ -392,7 +461,7 @@ bool ast_local_codegen(ast_value *self, ir_function *func) return false; } - v = ir_function_create_local(func, self->name, self->vtype); + v = ir_function_create_local(func, self->name, self->expression.vtype); if (!v) return false; @@ -400,7 +469,7 @@ bool ast_local_codegen(ast_value *self, ir_function *func) * I suppose the IR will have to deal with this */ if (self->isconst) { - switch (self->vtype) + switch (self->expression.vtype) { case TYPE_FLOAT: if (!ir_value_set_float(v, self->constval.vfloat)) @@ -415,7 +484,7 @@ bool ast_local_codegen(ast_value *self, ir_function *func) goto error; break; default: - printf("TODO: global constant type %i\n", self->vtype); + printf("TODO: global constant type %i\n", self->expression.vtype); break; } } diff --git a/ast.h b/ast.h index b2d906e..2112ae4 100644 --- a/ast.h +++ b/ast.h @@ -75,6 +75,8 @@ typedef struct { ast_node_common node; ast_expression_codegen *codegen; + int vtype; + ast_expression *next; } ast_expression_common; /* Value @@ -90,8 +92,10 @@ struct ast_value_s const char *name; + /* int vtype; ast_value *next; + */ bool isconst; union { @@ -305,8 +309,13 @@ union ast_expression_u { ast_expression_common expression; - ast_binary binary; - ast_block block; + ast_value value; + ast_binary binary; + ast_block block; + ast_ternary ternary; + ast_ifthen ifthen; + ast_store store; + ast_entfield entfield; }; /* Node union -- 2.39.2