X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=ast.cpp;h=c2c3b476e51cb0d5e310ff5285af5ed42876eee1;hp=73f9b1288ae3ef55a2a83f92f728ecec64ae6bca;hb=f09c6a5d63faaad1b915868c461b658efd374a34;hpb=9535805c02ec0a27fe882d6dd16c857856858002 diff --git a/ast.cpp b/ast.cpp index 73f9b12..c2c3b47 100644 --- a/ast.cpp +++ b/ast.cpp @@ -104,7 +104,7 @@ static void ast_expression_delete(ast_expression *self) { if (self->next) ast_delete(self->next); - for (auto &it : self->params) + for (auto &it : self->type_params) ast_delete(it); if (self->varparam) ast_delete(self->varparam); @@ -118,19 +118,17 @@ static void ast_expression_delete_full(ast_expression *self) ast_value* ast_value_copy(const ast_value *self) { - const ast_expression *fromex; - ast_expression *selfex; - ast_value *cp = ast_value_new(self->expression.context, self->name, self->expression.vtype); - if (self->expression.next) { - cp->expression.next = ast_type_copy(self->expression.context, self->expression.next); + ast_value *cp = ast_value_new(self->context, self->name, self->vtype); + if (self->next) { + cp->next = ast_type_copy(self->context, self->next); } - fromex = &self->expression; - selfex = &cp->expression; + const ast_expression *fromex = self; + ast_expression *selfex = cp; selfex->count = fromex->count; selfex->flags = fromex->flags; - for (auto &it : fromex->params) { + for (auto &it : fromex->type_params) { ast_value *v = ast_value_copy(it); - selfex->params.push_back(v); + selfex->type_params.push_back(v); } return cp; } @@ -147,13 +145,13 @@ void ast_type_adopt_impl(ast_expression *self, const ast_expression *other) selfex = self; selfex->count = fromex->count; selfex->flags = fromex->flags; - for (auto &it : fromex->params) { + for (auto &it : fromex->type_params) { ast_value *v = ast_value_copy(it); - selfex->params.push_back(v); + selfex->type_params.push_back(v); } } -static ast_expression* ast_shallow_type(lex_ctx_t ctx, int vtype) +static ast_expression* ast_shallow_type(lex_ctx_t ctx, qc_type vtype) { ast_instantiate(ast_expression, ctx, ast_expression_delete_full); ast_expression_init(self, nullptr); @@ -189,9 +187,9 @@ ast_expression* ast_type_copy(lex_ctx_t ctx, const ast_expression *ex) selfex->count = fromex->count; selfex->flags = fromex->flags; - for (auto &it : fromex->params) { + for (auto &it : fromex->type_params) { ast_value *v = ast_value_copy(it); - selfex->params.push_back(v); + selfex->type_params.push_back(v); } return self; @@ -207,18 +205,18 @@ bool ast_compare_type(ast_expression *a, ast_expression *b) return false; if (!a->next != !b->next) return false; - if (a->params.size() != b->params.size()) + if (a->type_params.size() != b->type_params.size()) return false; if ((a->flags & AST_FLAG_TYPE_MASK) != (b->flags & AST_FLAG_TYPE_MASK) ) { return false; } - if (a->params.size()) { + if (a->type_params.size()) { size_t i; - for (i = 0; i < a->params.size(); ++i) { - if (!ast_compare_type((ast_expression*)a->params[i], - (ast_expression*)b->params[i])) + for (i = 0; i < a->type_params.size(); ++i) { + if (!ast_compare_type((ast_expression*)a->type_params[i], + (ast_expression*)b->type_params[i])) return false; } } @@ -267,19 +265,19 @@ static size_t ast_type_to_string_impl(ast_expression *e, char *buf, size_t bufsi pos = ast_type_to_string_impl(e->next, buf, bufsize, pos); if (pos + 2 >= bufsize) goto full; - if (e->params.empty()) { + if (e->type_params.empty()) { buf[pos++] = '('; buf[pos++] = ')'; return pos; } buf[pos++] = '('; - pos = ast_type_to_string_impl((ast_expression*)(e->params[0]), buf, bufsize, pos); - for (i = 1; i < e->params.size(); ++i) { + pos = ast_type_to_string_impl((ast_expression*)(e->type_params[0]), buf, bufsize, pos); + for (i = 1; i < e->type_params.size(); ++i) { if (pos + 2 >= bufsize) goto full; buf[pos++] = ','; buf[pos++] = ' '; - pos = ast_type_to_string_impl((ast_expression*)(e->params[i]), buf, bufsize, pos); + pos = ast_type_to_string_impl((ast_expression*)(e->type_params[i]), buf, bufsize, pos); } if (pos + 1 >= bufsize) goto full; @@ -320,16 +318,16 @@ void ast_type_to_string(ast_expression *e, char *buf, size_t bufsize) } static bool ast_value_codegen(ast_value *self, ast_function *func, bool lvalue, ir_value **out); -ast_value* ast_value_new(lex_ctx_t ctx, const char *name, int t) +ast_value* ast_value_new(lex_ctx_t ctx, const char *name, qc_type t) { ast_instantiate(ast_value, ctx, ast_value_delete); ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_value_codegen); - self->expression.keep_node = true; /* keep */ + self->keep_node = true; /* keep */ self->name = name ? util_strdup(name) : nullptr; - self->expression.vtype = t; - self->expression.next = nullptr; + self->vtype = t; + self->next = nullptr; self->isfield = false; self->cvq = CV_NONE; self->hasvalue = false; @@ -359,7 +357,7 @@ void ast_value_delete(ast_value* self) if (self->argcounter) mem_d((void*)self->argcounter); if (self->hasvalue) { - switch (self->expression.vtype) + switch (self->vtype) { case TYPE_STRING: mem_d((void*)self->constval.vstring); @@ -382,7 +380,7 @@ void ast_value_delete(ast_value* self) mem_d(self->desc); // initlist imples an array which implies .next in the expression exists. - if (self->initlist.size() && self->expression.next->vtype == TYPE_STRING) { + if (self->initlist.size() && self->next->vtype == TYPE_STRING) { for (auto &it : self->initlist) if (it.vstring) mem_d(it.vstring); @@ -394,7 +392,7 @@ void ast_value_delete(ast_value* self) void ast_value_params_add(ast_value *self, ast_value *p) { - self->expression.params.push_back(p); + self->type_params.push_back(p); } bool ast_value_set_name(ast_value *self, const char *name) @@ -438,21 +436,21 @@ ast_binary* ast_binary_new(lex_ctx_t ctx, int op, ast_propagate_effects(self, right); if (op >= INSTR_EQ_F && op <= INSTR_GT) - self->expression.vtype = TYPE_FLOAT; + self->vtype = TYPE_FLOAT; else if (op == INSTR_AND || op == INSTR_OR) { if (OPTS_FLAG(PERL_LOGIC)) ast_type_adopt(self, right); else - self->expression.vtype = TYPE_FLOAT; + self->vtype = TYPE_FLOAT; } else if (op == INSTR_BITAND || op == INSTR_BITOR) - self->expression.vtype = TYPE_FLOAT; + self->vtype = TYPE_FLOAT; else if (op == INSTR_MUL_VF || op == INSTR_MUL_FV) - self->expression.vtype = TYPE_VECTOR; + self->vtype = TYPE_VECTOR; else if (op == INSTR_MUL_V) - self->expression.vtype = TYPE_FLOAT; + self->vtype = TYPE_FLOAT; else - self->expression.vtype = left->vtype; + self->vtype = left->vtype; /* references all */ self->refs = AST_REF_ALL; @@ -525,9 +523,9 @@ ast_unary* ast_unary_new(lex_ctx_t ctx, int op, ast_propagate_effects(self, expr); if ((op >= INSTR_NOT_F && op <= INSTR_NOT_FNC) || op == VINSTR_NEG_F) { - self->expression.vtype = TYPE_FLOAT; + self->vtype = TYPE_FLOAT; } else if (op == VINSTR_NEG_V) { - self->expression.vtype = TYPE_VECTOR; + self->vtype = TYPE_VECTOR; } else { compile_error(ctx, "cannot determine type of unary operation %s", util_instr_str[op]); } @@ -617,14 +615,14 @@ ast_member* ast_member_new(lex_ctx_t ctx, ast_expression *owner, unsigned int fi } ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_member_codegen); - self->expression.keep_node = true; /* keep */ + self->keep_node = true; /* keep */ if (owner->vtype == TYPE_VECTOR) { - self->expression.vtype = TYPE_FLOAT; - self->expression.next = nullptr; + self->vtype = TYPE_FLOAT; + self->next = nullptr; } else { - self->expression.vtype = TYPE_FIELD; - self->expression.next = ast_shallow_type(ctx, TYPE_FLOAT); + self->vtype = TYPE_FIELD; + self->next = ast_shallow_type(ctx, TYPE_FLOAT); } self->rvalue = false; @@ -684,13 +682,13 @@ ast_array_index* ast_array_index_new(lex_ctx_t ctx, ast_expression *array, ast_e ast_type_adopt(self, outtype); if (array->vtype == TYPE_FIELD && outtype->vtype == TYPE_ARRAY) { - if (self->expression.vtype != TYPE_ARRAY) { + if (self->vtype != TYPE_ARRAY) { compile_error(ast_ctx(self), "array_index node on type"); ast_array_index_delete(self); return nullptr; } self->array = outtype; - self->expression.vtype = TYPE_FIELD; + self->vtype = TYPE_FIELD; } return self; @@ -711,7 +709,7 @@ ast_argpipe* ast_argpipe_new(lex_ctx_t ctx, ast_expression *index) ast_instantiate(ast_argpipe, ctx, ast_argpipe_delete); ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_argpipe_codegen); self->index = index; - self->expression.vtype = TYPE_NOEXPR; + self->vtype = TYPE_NOEXPR; return self; } @@ -890,7 +888,7 @@ ast_label* ast_label_new(lex_ctx_t ctx, const char *name, bool undefined) ast_instantiate(ast_label, ctx, ast_label_delete); ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_label_codegen); - self->expression.vtype = TYPE_NOEXPR; + self->vtype = TYPE_NOEXPR; self->name = util_strdup(name); self->irblock = nullptr; @@ -1042,8 +1040,8 @@ bool ast_call_check_types(ast_call *self, ast_expression *va_type) bool retval = true; const ast_expression *func = self->func; size_t count = self->params.size(); - if (count > func->params.size()) - count = func->params.size(); + if (count > func->type_params.size()) + count = func->type_params.size(); for (i = 0; i < count; ++i) { if (ast_istype(self->params[i], ast_argpipe)) { @@ -1052,13 +1050,13 @@ bool ast_call_check_types(ast_call *self, ast_expression *va_type) compile_error(ast_ctx(self), "argpipe must be the last parameter to a function call"); return false; } - if (!ast_call_check_vararg(self, va_type, (ast_expression*)func->params[i])) + if (!ast_call_check_vararg(self, va_type, (ast_expression*)func->type_params[i])) retval = false; } - else if (!ast_compare_type(self->params[i], (ast_expression*)(func->params[i]))) + else if (!ast_compare_type(self->params[i], (ast_expression*)(func->type_params[i]))) { ast_type_to_string(self->params[i], tgot, sizeof(tgot)); - ast_type_to_string((ast_expression*)func->params[i], texp, sizeof(texp)); + ast_type_to_string((ast_expression*)func->type_params[i], texp, sizeof(texp)); compile_error(ast_ctx(self), "invalid type for parameter %u in function call: expected %s, got %s", (unsigned int)(i+1), texp, tgot); /* we don't immediately return */ @@ -1066,7 +1064,7 @@ bool ast_call_check_types(ast_call *self, ast_expression *va_type) } } count = self->params.size(); - if (count > func->params.size() && func->varparam) { + if (count > func->type_params.size() && func->varparam) { for (; i < count; ++i) { if (ast_istype(self->params[i], ast_argpipe)) { /* warn about type safety instead */ @@ -1128,9 +1126,9 @@ bool ast_block_add_expr(ast_block *self, ast_expression *e) { ast_propagate_effects(self, e); self->exprs.push_back(e); - if (self->expression.next) { - ast_delete(self->expression.next); - self->expression.next = nullptr; + if (self->next) { + ast_delete(self->next); + self->next = nullptr; } ast_type_adopt(self, e); return true; @@ -1153,8 +1151,8 @@ void ast_block_delete(ast_block *self) void ast_block_set_type(ast_block *self, ast_expression *from) { - if (self->expression.next) - ast_delete(self->expression.next); + if (self->next) + ast_delete(self->next); ast_type_adopt(self, from); } @@ -1165,11 +1163,11 @@ ast_function* ast_function_new(lex_ctx_t ctx, const char *name, ast_value *vtype if (!vtype) { compile_error(ast_ctx(self), "internal error: ast_function_new condition 0"); goto cleanup; - } else if (vtype->hasvalue || vtype->expression.vtype != TYPE_FUNCTION) { + } else if (vtype->hasvalue || vtype->vtype != TYPE_FUNCTION) { compile_error(ast_ctx(self), "internal error: ast_function_new condition %i %i type=%i (probably 2 bodies?)", (int)!vtype, (int)vtype->hasvalue, - vtype->expression.vtype); + vtype->vtype); goto cleanup; } @@ -1268,17 +1266,17 @@ static void _ast_codegen_output_type(ast_expression *self, ir_value *out) out->outtype = self->next->vtype; } -#define codegen_output_type(a,o) (_ast_codegen_output_type(&((a)->expression),(o))) +#define codegen_output_type(a,o) (_ast_codegen_output_type(static_cast((a)),(o))) bool ast_value_codegen(ast_value *self, ast_function *func, bool lvalue, ir_value **out) { (void)func; (void)lvalue; - if (self->expression.vtype == TYPE_NIL) { + if (self->vtype == TYPE_NIL) { *out = func->ir_func->owner->nil; return true; } - /* NOTE: This is the codegen for a variable used in an expression. + /* NOTE: This is the codegen for a variable used in an * It is not the codegen to generate the value. For this purpose, * ast_local_codegen and ast_global_codegen are to be used before this * is executed. ast_function_codegen should take care of its locals, @@ -1300,18 +1298,18 @@ static bool ast_global_array_set(ast_value *self) size_t count = self->initlist.size(); size_t i; - if (count > self->expression.count) { + if (count > self->count) { compile_error(ast_ctx(self), "too many elements in initializer"); - count = self->expression.count; + count = self->count; } - else if (count < self->expression.count) { + else if (count < self->count) { /* add this? compile_warning(ast_ctx(self), "not all elements are initialized"); */ } for (i = 0; i != count; ++i) { - switch (self->expression.next->vtype) { + switch (self->next->vtype) { case TYPE_FLOAT: if (!ir_value_set_float(self->ir_values[i], self->initlist[i].vfloat)) return false; @@ -1345,7 +1343,7 @@ static bool ast_global_array_set(ast_value *self) return false; break; default: - compile_error(ast_ctx(self), "TODO: global constant type %i", self->expression.vtype); + compile_error(ast_ctx(self), "TODO: global constant type %i", self->vtype); break; } } @@ -1354,13 +1352,13 @@ static bool ast_global_array_set(ast_value *self) static bool check_array(ast_value *self, ast_value *array) { - if (array->expression.flags & AST_FLAG_ARRAY_INIT && array->initlist.empty()) { + if (array->flags & AST_FLAG_ARRAY_INIT && array->initlist.empty()) { compile_error(ast_ctx(self), "array without size: %s", self->name); return false; } /* we are lame now - considering the way QC works we won't tolerate arrays > 1024 elements */ - if (!array->expression.count || array->expression.count > OPTS_OPTION_U32(OPTION_MAX_ARRAY_SIZE)) { - compile_error(ast_ctx(self), "Invalid array of size %lu", (unsigned long)array->expression.count); + if (!array->count || array->count > OPTS_OPTION_U32(OPTION_MAX_ARRAY_SIZE)) { + compile_error(ast_ctx(self), "Invalid array of size %lu", (unsigned long)array->count); return false; } return true; @@ -1370,14 +1368,14 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield) { ir_value *v = nullptr; - if (self->expression.vtype == TYPE_NIL) { + if (self->vtype == TYPE_NIL) { compile_error(ast_ctx(self), "internal error: trying to generate a variable of TYPE_NIL"); return false; } - if (self->hasvalue && self->expression.vtype == TYPE_FUNCTION) + if (self->hasvalue && self->vtype == TYPE_FUNCTION) { - ir_function *func = ir_builder_create_function(ir, self->name, self->expression.next->vtype); + ir_function *func = ir_builder_create_function(ir, self->name, self->next->vtype); if (!func) return false; func->context = ast_ctx(self); @@ -1385,18 +1383,18 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield) self->constval.vfunc->ir_func = func; self->ir_v = func->value; - if (self->expression.flags & AST_FLAG_INCLUDE_DEF) + if (self->flags & AST_FLAG_INCLUDE_DEF) self->ir_v->flags |= IR_FLAG_INCLUDE_DEF; - if (self->expression.flags & AST_FLAG_ERASEABLE) + if (self->flags & AST_FLAG_ERASEABLE) self->ir_v->flags |= IR_FLAG_ERASABLE; - if (self->expression.flags & AST_FLAG_BLOCK_COVERAGE) + if (self->flags & AST_FLAG_BLOCK_COVERAGE) func->flags |= IR_FLAG_BLOCK_COVERAGE; /* The function is filled later on ast_function_codegen... */ return true; } - if (isfield && self->expression.vtype == TYPE_FIELD) { - ast_expression *fieldtype = self->expression.next; + if (isfield && self->vtype == TYPE_FIELD) { + ast_expression *fieldtype = self->next; if (self->hasvalue) { compile_error(ast_ctx(self), "TODO: constant field pointers with value"); @@ -1409,7 +1407,7 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield) size_t namelen; ast_expression *elemtype; - int vtype; + qc_type vtype; ast_value *array = (ast_value*)fieldtype; if (!ast_istype(fieldtype, ast_value)) { @@ -1420,7 +1418,7 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield) if (!check_array(self, array)) return false; - elemtype = array->expression.next; + elemtype = array->next; vtype = elemtype->vtype; v = ir_builder_create_field(ir, self->name, vtype); @@ -1433,18 +1431,18 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield) v->locked = true; array->ir_v = self->ir_v = v; - if (self->expression.flags & AST_FLAG_INCLUDE_DEF) + if (self->flags & AST_FLAG_INCLUDE_DEF) self->ir_v->flags |= IR_FLAG_INCLUDE_DEF; - if (self->expression.flags & AST_FLAG_ERASEABLE) + if (self->flags & AST_FLAG_ERASEABLE) self->ir_v->flags |= IR_FLAG_ERASABLE; namelen = strlen(self->name); name = (char*)mem_a(namelen + 16); util_strncpy(name, self->name, namelen); - array->ir_values = (ir_value**)mem_a(sizeof(array->ir_values[0]) * array->expression.count); + array->ir_values = (ir_value**)mem_a(sizeof(array->ir_values[0]) * array->count); array->ir_values[0] = v; - for (ai = 1; ai < array->expression.count; ++ai) { + for (ai = 1; ai < array->count; ++ai) { util_snprintf(name + namelen, 16, "[%u]", (unsigned int)ai); array->ir_values[ai] = ir_builder_create_field(ir, name, vtype); if (!array->ir_values[ai]) { @@ -1455,36 +1453,36 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield) array->ir_values[ai]->context = ast_ctx(self); array->ir_values[ai]->unique_life = true; array->ir_values[ai]->locked = true; - if (self->expression.flags & AST_FLAG_INCLUDE_DEF) + if (self->flags & AST_FLAG_INCLUDE_DEF) self->ir_values[ai]->flags |= IR_FLAG_INCLUDE_DEF; } mem_d(name); } else { - v = ir_builder_create_field(ir, self->name, self->expression.next->vtype); + v = ir_builder_create_field(ir, self->name, self->next->vtype); if (!v) return false; v->context = ast_ctx(self); self->ir_v = v; - if (self->expression.flags & AST_FLAG_INCLUDE_DEF) + if (self->flags & AST_FLAG_INCLUDE_DEF) self->ir_v->flags |= IR_FLAG_INCLUDE_DEF; - if (self->expression.flags & AST_FLAG_ERASEABLE) + if (self->flags & AST_FLAG_ERASEABLE) self->ir_v->flags |= IR_FLAG_ERASABLE; } return true; } - if (self->expression.vtype == TYPE_ARRAY) { + if (self->vtype == TYPE_ARRAY) { size_t ai; char *name; size_t namelen; - ast_expression *elemtype = self->expression.next; - int vtype = elemtype->vtype; + ast_expression *elemtype = self->next; + qc_type vtype = elemtype->vtype; - if (self->expression.flags & AST_FLAG_ARRAY_INIT && !self->expression.count) { + if (self->flags & AST_FLAG_ARRAY_INIT && !self->count) { compile_error(ast_ctx(self), "array `%s' has no size", self->name); return false; } @@ -1502,18 +1500,18 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield) v->unique_life = true; v->locked = true; - if (self->expression.flags & AST_FLAG_INCLUDE_DEF) + if (self->flags & AST_FLAG_INCLUDE_DEF) v->flags |= IR_FLAG_INCLUDE_DEF; - if (self->expression.flags & AST_FLAG_ERASEABLE) + if (self->flags & AST_FLAG_ERASEABLE) self->ir_v->flags |= IR_FLAG_ERASABLE; namelen = strlen(self->name); name = (char*)mem_a(namelen + 16); util_strncpy(name, self->name, namelen); - self->ir_values = (ir_value**)mem_a(sizeof(self->ir_values[0]) * self->expression.count); + self->ir_values = (ir_value**)mem_a(sizeof(self->ir_values[0]) * self->count); self->ir_values[0] = v; - for (ai = 1; ai < self->expression.count; ++ai) { + for (ai = 1; ai < self->count; ++ai) { util_snprintf(name + namelen, 16, "[%u]", (unsigned int)ai); self->ir_values[ai] = ir_builder_create_global(ir, name, vtype); if (!self->ir_values[ai]) { @@ -1524,7 +1522,7 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield) self->ir_values[ai]->context = ast_ctx(self); self->ir_values[ai]->unique_life = true; self->ir_values[ai]->locked = true; - if (self->expression.flags & AST_FLAG_INCLUDE_DEF) + if (self->flags & AST_FLAG_INCLUDE_DEF) self->ir_values[ai]->flags |= IR_FLAG_INCLUDE_DEF; } mem_d(name); @@ -1534,7 +1532,7 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield) /* Arrays don't do this since there's no "array" value which spans across the * whole thing. */ - v = ir_builder_create_global(ir, self->name, self->expression.vtype); + v = ir_builder_create_global(ir, self->name, self->vtype); if (!v) { compile_error(ast_ctx(self), "ir_builder_create_global failed on `%s`", self->name); return false; @@ -1547,14 +1545,14 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield) v->cvq = self->cvq; self->ir_v = v; - if (self->expression.flags & AST_FLAG_INCLUDE_DEF) + if (self->flags & AST_FLAG_INCLUDE_DEF) self->ir_v->flags |= IR_FLAG_INCLUDE_DEF; - if (self->expression.flags & AST_FLAG_ERASEABLE) + if (self->flags & AST_FLAG_ERASEABLE) self->ir_v->flags |= IR_FLAG_ERASABLE; /* initialize */ if (self->hasvalue) { - switch (self->expression.vtype) + switch (self->vtype) { case TYPE_FLOAT: if (!ir_value_set_float(v, self->constval.vfloat)) @@ -1590,14 +1588,14 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield) goto error; break; default: - compile_error(ast_ctx(self), "TODO: global constant type %i", self->expression.vtype); + compile_error(ast_ctx(self), "TODO: global constant type %i", self->vtype); break; } } return true; error: /* clean up */ - if(v) ir_value_delete(v); + if (v) delete v; return false; } @@ -1605,12 +1603,12 @@ static bool ast_local_codegen(ast_value *self, ir_function *func, bool param) { ir_value *v = nullptr; - if (self->expression.vtype == TYPE_NIL) { + if (self->vtype == TYPE_NIL) { compile_error(ast_ctx(self), "internal error: trying to generate a variable of TYPE_NIL"); return false; } - if (self->hasvalue && self->expression.vtype == TYPE_FUNCTION) + if (self->hasvalue && self->vtype == TYPE_FUNCTION) { /* Do we allow local functions? I think not... * this is NOT a function pointer atm. @@ -1618,17 +1616,17 @@ static bool ast_local_codegen(ast_value *self, ir_function *func, bool param) return false; } - if (self->expression.vtype == TYPE_ARRAY) { + if (self->vtype == TYPE_ARRAY) { size_t ai; char *name; size_t namelen; - ast_expression *elemtype = self->expression.next; - int vtype = elemtype->vtype; + ast_expression *elemtype = self->next; + qc_type vtype = elemtype->vtype; func->flags |= IR_FLAG_HAS_ARRAYS; - if (param && !(self->expression.flags & AST_FLAG_IS_VARARG)) { + if (param && !(self->flags & AST_FLAG_IS_VARARG)) { compile_error(ast_ctx(self), "array-parameters are not supported"); return false; } @@ -1637,7 +1635,7 @@ static bool ast_local_codegen(ast_value *self, ir_function *func, bool param) if (!check_array(self, self)) return false; - self->ir_values = (ir_value**)mem_a(sizeof(self->ir_values[0]) * self->expression.count); + self->ir_values = (ir_value**)mem_a(sizeof(self->ir_values[0]) * self->count); if (!self->ir_values) { compile_error(ast_ctx(self), "failed to allocate array values"); return false; @@ -1657,7 +1655,7 @@ static bool ast_local_codegen(ast_value *self, ir_function *func, bool param) util_strncpy(name, self->name, namelen); self->ir_values[0] = v; - for (ai = 1; ai < self->expression.count; ++ai) { + for (ai = 1; ai < self->count; ++ai) { util_snprintf(name + namelen, 16, "[%u]", (unsigned int)ai); self->ir_values[ai] = ir_function_create_local(func, name, vtype, param); if (!self->ir_values[ai]) { @@ -1672,7 +1670,7 @@ static bool ast_local_codegen(ast_value *self, ir_function *func, bool param) } else { - v = ir_function_create_local(func, self->name, self->expression.vtype, param); + v = ir_function_create_local(func, self->name, self->vtype, param); if (!v) return false; codegen_output_type(self, v); @@ -1683,7 +1681,7 @@ static bool ast_local_codegen(ast_value *self, ir_function *func, bool param) * I suppose the IR will have to deal with this */ if (self->hasvalue) { - switch (self->expression.vtype) + switch (self->vtype) { case TYPE_FLOAT: if (!ir_value_set_float(v, self->constval.vfloat)) @@ -1698,7 +1696,7 @@ static bool ast_local_codegen(ast_value *self, ir_function *func, bool param) goto error; break; default: - compile_error(ast_ctx(self), "TODO: global constant type %i", self->expression.vtype); + compile_error(ast_ctx(self), "TODO: global constant type %i", self->vtype); break; } } @@ -1712,7 +1710,7 @@ static bool ast_local_codegen(ast_value *self, ir_function *func, bool param) return true; error: /* clean up */ - ir_value_delete(v); + delete v; return false; } @@ -1722,7 +1720,7 @@ bool ast_generate_accessors(ast_value *self, ir_builder *ir) bool warn = OPTS_WARN(WARN_USED_UNINITIALIZED); if (!self->setter || !self->getter) return true; - for (i = 0; i < self->expression.count; ++i) { + for (i = 0; i < self->count; ++i) { if (!self->ir_values) { compile_error(ast_ctx(self), "internal error: no array values generated for `%s`", self->name); return false; @@ -1731,7 +1729,7 @@ bool ast_generate_accessors(ast_value *self, ir_builder *ir) compile_error(ast_ctx(self), "internal error: not all array values have been generated for `%s`", self->name); return false; } - if (self->ir_values[i]->life) { + if (!self->ir_values[i]->life.empty()) { compile_error(ast_ctx(self), "internal error: function containing `%s` already generated", self->name); return false; } @@ -1758,9 +1756,8 @@ bool ast_generate_accessors(ast_value *self, ir_builder *ir) return false; } } - for (i = 0; i < self->expression.count; ++i) { - vec_free(self->ir_values[i]->life); - } + for (i = 0; i < self->count; ++i) + self->ir_values[i]->life.clear(); opts_set(opts.warn, WARN_USED_UNINITIALIZED, warn); return true; } @@ -1781,12 +1778,12 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir) } /* fill the parameter list */ - ec = &self->function_type->expression; - for (auto &it : ec->params) { - if (it->expression.vtype == TYPE_FIELD) - vec_push(irf->params, it->expression.next->vtype); + ec = self->function_type; + for (auto &it : ec->type_params) { + if (it->vtype == TYPE_FIELD) + vec_push(irf->params, it->next->vtype); else - vec_push(irf->params, it->expression.vtype); + vec_push(irf->params, it->vtype); if (!self->builtin) { if (!ast_local_codegen(it, self->ir_func, true)) return false; @@ -1796,7 +1793,7 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir) if (self->varargs) { if (!ast_local_codegen(self->varargs, self->ir_func, true)) return false; - irf->max_varargs = self->varargs->expression.count; + irf->max_varargs = self->varargs->count; } if (self->builtin) { @@ -1827,10 +1824,10 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir) ir_value *sub; if (!ast_local_codegen(self->argc, self->ir_func, true)) return false; - cgen = self->argc->expression.codegen; + cgen = self->argc->codegen; if (!(*cgen)((ast_expression*)(self->argc), self, false, &va_count)) return false; - cgen = self->fixedparams->expression.codegen; + cgen = self->fixedparams->codegen; if (!(*cgen)((ast_expression*)(self->fixedparams), self, false, &fixed)) return false; sub = ir_block_create_binop(self->curblock, ast_ctx(self), @@ -1846,7 +1843,7 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir) } for (auto &it : self->blocks) { - cgen = it->expression.codegen; + cgen = it->codegen; if (!(*cgen)((ast_expression*)it, self, false, &dummy)) return false; } @@ -1854,22 +1851,22 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir) /* TODO: check return types */ if (!self->curblock->final) { - if (!self->function_type->expression.next || - self->function_type->expression.next->vtype == TYPE_VOID) + if (!self->function_type->next || + self->function_type->next->vtype == TYPE_VOID) { return ir_block_create_return(self->curblock, ast_ctx(self), nullptr); } else if (vec_size(self->curblock->entries) || self->curblock == irf->first) { if (self->return_value) { - cgen = self->return_value->expression.codegen; + cgen = self->return_value->codegen; if (!(*cgen)((ast_expression*)(self->return_value), self, false, &dummy)) return false; return ir_block_create_return(self->curblock, ast_ctx(self), dummy); } else if (compile_warning(ast_ctx(self), WARN_MISSING_RETURN_VALUES, "control reaches end of non-void function (`%s`) via %s", - self->name, self->curblock->label)) + self->name, self->curblock->label.c_str())) { return false; } @@ -1907,8 +1904,8 @@ bool ast_block_codegen(ast_block *self, ast_function *func, bool lvalue, ir_valu return false; } - if (self->expression.outr) { - *out = self->expression.outr; + if (self->outr) { + *out = self->outr; return true; } @@ -1941,7 +1938,7 @@ bool ast_block_codegen(ast_block *self, ast_function *func, bool lvalue, ir_valu return false; } - self->expression.outr = *out; + self->outr = *out; return true; } @@ -1956,13 +1953,13 @@ bool ast_store_codegen(ast_store *self, ast_function *func, bool lvalue, ir_valu ast_value *idx = 0; ast_array_index *ai = nullptr; - if (lvalue && self->expression.outl) { - *out = self->expression.outl; + if (lvalue && self->outl) { + *out = self->outl; return true; } - if (!lvalue && self->expression.outr) { - *out = self->expression.outr; + if (!lvalue && self->outr) { + *out = self->outr; return true; } @@ -1992,11 +1989,11 @@ bool ast_store_codegen(ast_store *self, ast_function *func, bool lvalue, ir_valu return false; } - cgen = idx->expression.codegen; + cgen = idx->codegen; if (!(*cgen)((ast_expression*)(idx), func, false, &iridx)) return false; - cgen = arr->setter->expression.codegen; + cgen = arr->setter->codegen; if (!(*cgen)((ast_expression*)(arr->setter), func, true, &funval)) return false; @@ -2009,7 +2006,7 @@ bool ast_store_codegen(ast_store *self, ast_function *func, bool lvalue, ir_valu return false; ir_call_param(call, iridx); ir_call_param(call, right); - self->expression.outr = right; + self->outr = right; } else { @@ -2019,7 +2016,7 @@ bool ast_store_codegen(ast_store *self, ast_function *func, bool lvalue, ir_valu /* lvalue! */ if (!(*cgen)((ast_expression*)(self->dest), func, true, &left)) return false; - self->expression.outl = left; + self->outl = left; cgen = self->source->codegen; /* rvalue! */ @@ -2028,7 +2025,7 @@ bool ast_store_codegen(ast_store *self, ast_function *func, bool lvalue, ir_valu if (!ir_block_create_store_op(func->curblock, ast_ctx(self), self->op, left, right)) return false; - self->expression.outr = right; + self->outr = right; } /* Theoretically, an assinment returns its left side as an @@ -2054,8 +2051,8 @@ bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_va return false; } - if (self->expression.outr) { - *out = self->expression.outr; + if (self->outr) { + *out = self->outr; return true; } @@ -2071,7 +2068,7 @@ bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_va size_t merge_id; /* prepare end-block */ - merge_id = vec_size(func->ir_func->blocks); + merge_id = func->ir_func->blocks.size(); merge = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "sce_merge")); /* generate the left expression */ @@ -2108,13 +2105,13 @@ bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_va if (!ir_block_create_jump(func->curblock, ast_ctx(self), merge)) return false; - vec_remove(func->ir_func->blocks, merge_id, 1); - vec_push(func->ir_func->blocks, merge); + func->ir_func->blocks.erase(func->ir_func->blocks.begin() + merge_id); + func->ir_func->blocks.emplace_back(merge); func->curblock = merge; phi = ir_block_create_phi(func->curblock, ast_ctx(self), ast_function_label(func, "sce_value"), - self->expression.vtype); + self->vtype); ir_phi_add(phi, from_left, left); ir_phi_add(phi, from_right, right); *out = ir_phi_value(phi); @@ -2156,7 +2153,7 @@ bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_va } } - self->expression.outr = *out; + self->outr = *out; codegen_output_type(self, *out); return true; } @@ -2181,7 +2178,7 @@ bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_va self->op, left, right); if (!*out) return false; - self->expression.outr = *out; + self->outr = *out; codegen_output_type(self, *out); return true; @@ -2197,13 +2194,13 @@ bool ast_binstore_codegen(ast_binstore *self, ast_function *func, bool lvalue, i ast_array_index *ai = nullptr; ir_value *iridx = nullptr; - if (lvalue && self->expression.outl) { - *out = self->expression.outl; + if (lvalue && self->outl) { + *out = self->outl; return true; } - if (!lvalue && self->expression.outr) { - *out = self->expression.outr; + if (!lvalue && self->outr) { + *out = self->outr; return true; } @@ -2220,7 +2217,7 @@ bool ast_binstore_codegen(ast_binstore *self, ast_function *func, bool lvalue, i /* for a binstore we need both an lvalue and an rvalue for the left side */ /* rvalue of destination! */ if (ai) { - cgen = idx->expression.codegen; + cgen = idx->codegen; if (!(*cgen)((ast_expression*)(idx), func, false, &iridx)) return false; } @@ -2236,8 +2233,7 @@ bool ast_binstore_codegen(ast_binstore *self, ast_function *func, bool lvalue, i /* now the binary */ bin = ir_block_create_binop(func->curblock, ast_ctx(self), ast_function_label(func, "binst"), self->opbin, leftr, right); - self->expression.outr = bin; - + self->outr = bin; if (ai) { /* we need to call the setter */ @@ -2255,7 +2251,7 @@ bool ast_binstore_codegen(ast_binstore *self, ast_function *func, bool lvalue, i return false; } - cgen = arr->setter->expression.codegen; + cgen = arr->setter->codegen; if (!(*cgen)((ast_expression*)(arr->setter), func, true, &funval)) return false; @@ -2264,18 +2260,18 @@ bool ast_binstore_codegen(ast_binstore *self, ast_function *func, bool lvalue, i return false; ir_call_param(call, iridx); ir_call_param(call, bin); - self->expression.outr = bin; + self->outr = bin; } else { /* now store them */ cgen = self->dest->codegen; /* lvalue of destination */ if (!(*cgen)((ast_expression*)(self->dest), func, true, &leftl)) return false; - self->expression.outl = leftl; + self->outl = leftl; if (!ir_block_create_store_op(func->curblock, ast_ctx(self), self->opstore, leftl, bin)) return false; - self->expression.outr = bin; + self->outr = bin; } /* Theoretically, an assinment returns its left side as an @@ -2301,8 +2297,8 @@ bool ast_unary_codegen(ast_unary *self, ast_function *func, bool lvalue, ir_valu return false; } - if (self->expression.outr) { - *out = self->expression.outr; + if (self->outr) { + *out = self->outr; return true; } @@ -2315,7 +2311,7 @@ bool ast_unary_codegen(ast_unary *self, ast_function *func, bool lvalue, ir_valu self->op, operand); if (!*out) return false; - self->expression.outr = *out; + self->outr = *out; return true; } @@ -2335,11 +2331,11 @@ bool ast_return_codegen(ast_return *self, ast_function *func, bool lvalue, ir_va return false; } - if (self->expression.outr) { + if (self->outr) { compile_error(ast_ctx(self), "internal error: ast_return cannot be reused, it bears no result!"); return false; } - self->expression.outr = (ir_value*)1; + self->outr = (ir_value*)1; if (self->operand) { cgen = self->operand->codegen; @@ -2367,13 +2363,13 @@ bool ast_entfield_codegen(ast_entfield *self, ast_function *func, bool lvalue, i * value in a temp. */ - if (lvalue && self->expression.outl) { - *out = self->expression.outl; + if (lvalue && self->outl) { + *out = self->outl; return true; } - if (!lvalue && self->expression.outr) { - *out = self->expression.outr; + if (!lvalue && self->outr) { + *out = self->outr; return true; } @@ -2391,7 +2387,7 @@ bool ast_entfield_codegen(ast_entfield *self, ast_function *func, bool lvalue, i ent, field); } else { *out = ir_block_create_load_from_ent(func->curblock, ast_ctx(self), ast_function_label(func, "efv"), - ent, field, self->expression.vtype); + ent, field, self->vtype); /* Done AFTER error checking: codegen_output_type(self, *out); */ @@ -2399,16 +2395,16 @@ bool ast_entfield_codegen(ast_entfield *self, ast_function *func, bool lvalue, i if (!*out) { compile_error(ast_ctx(self), "failed to create %s instruction (output type %s)", (lvalue ? "ADDRESS" : "FIELD"), - type_name[self->expression.vtype]); + type_name[self->vtype]); return false; } if (!lvalue) codegen_output_type(self, *out); if (lvalue) - self->expression.outl = *out; + self->outl = *out; else - self->expression.outr = *out; + self->outr = *out; /* Hm that should be it... */ return true; @@ -2424,8 +2420,8 @@ bool ast_member_codegen(ast_member *self, ast_function *func, bool lvalue, ir_va compile_error(ast_ctx(self), "not an l-value (member access)"); return false; } - if (self->expression.outl) { - *out = self->expression.outl; + if (self->outl) { + *out = self->outl; return true; } @@ -2440,7 +2436,7 @@ bool ast_member_codegen(ast_member *self, ast_function *func, bool lvalue, ir_va } *out = ir_value_vector_member(vec, self->field); - self->expression.outl = *out; + self->outl = *out; return (*out != nullptr); } @@ -2450,12 +2446,12 @@ bool ast_array_index_codegen(ast_array_index *self, ast_function *func, bool lva ast_value *arr; ast_value *idx; - if (!lvalue && self->expression.outr) { - *out = self->expression.outr; + if (!lvalue && self->outr) { + *out = self->outr; return true; } - if (lvalue && self->expression.outl) { - *out = self->expression.outl; + if (lvalue && self->outl) { + *out = self->outl; return true; } @@ -2492,7 +2488,7 @@ bool ast_array_index_codegen(ast_array_index *self, ast_function *func, bool lva if (!(*cgen)((ast_expression*)(self->index), func, false, &iridx)) return false; - cgen = arr->getter->expression.codegen; + cgen = arr->getter->codegen; if (!(*cgen)((ast_expression*)(arr->getter), func, true, &funval)) return false; @@ -2502,13 +2498,13 @@ bool ast_array_index_codegen(ast_array_index *self, ast_function *func, bool lva ir_call_param(call, iridx); *out = ir_call_value(call); - self->expression.outr = *out; - (*out)->vtype = self->expression.vtype; + self->outr = *out; + (*out)->vtype = self->vtype; codegen_output_type(self, *out); return true; } - if (idx->expression.vtype == TYPE_FLOAT) { + if (idx->vtype == TYPE_FLOAT) { unsigned int arridx = idx->constval.vfloat; if (arridx >= self->array->count) { @@ -2517,7 +2513,7 @@ bool ast_array_index_codegen(ast_array_index *self, ast_function *func, bool lva } *out = arr->ir_values[arridx]; } - else if (idx->expression.vtype == TYPE_INTEGER) { + else if (idx->vtype == TYPE_INTEGER) { unsigned int arridx = idx->constval.vint; if (arridx >= self->array->count) { @@ -2530,7 +2526,7 @@ bool ast_array_index_codegen(ast_array_index *self, ast_function *func, bool lva compile_error(ast_ctx(self), "array indexing here needs an integer constant"); return false; } - (*out)->vtype = self->expression.vtype; + (*out)->vtype = self->vtype; codegen_output_type(self, *out); return true; } @@ -2567,11 +2563,11 @@ bool ast_ifthen_codegen(ast_ifthen *self, ast_function *func, bool lvalue, ir_va (void)out; (void)lvalue; - if (self->expression.outr) { + if (self->outr) { compile_error(ast_ctx(self), "internal error: ast_ifthen cannot be reused, it bears no result!"); return false; } - self->expression.outr = (ir_value*)1; + self->outr = (ir_value*)1; /* generate the condition */ cgen = self->cond->codegen; @@ -2675,8 +2671,8 @@ bool ast_ternary_codegen(ast_ternary *self, ast_function *func, bool lvalue, ir_ * may still happen, thus we remember a created ir_value and simply return one * if it already exists. */ - if (self->expression.outr) { - *out = self->expression.outr; + if (self->outr) { + *out = self->outr; return true; } @@ -2754,7 +2750,7 @@ bool ast_ternary_codegen(ast_ternary *self, ast_function *func, bool lvalue, ir_ } /* create PHI */ - phi = ir_block_create_phi(merge, ast_ctx(self), ast_function_label(func, "phi"), self->expression.vtype); + phi = ir_block_create_phi(merge, ast_ctx(self), ast_function_label(func, "phi"), self->vtype); if (!phi) { compile_error(ast_ctx(self), "internal error: failed to generate phi node"); return false; @@ -2762,8 +2758,8 @@ bool ast_ternary_codegen(ast_ternary *self, ast_function *func, bool lvalue, ir_ ir_phi_add(phi, ontrue_out, trueval); ir_phi_add(phi, onfalse_out, falseval); - self->expression.outr = ir_phi_value(phi); - *out = self->expression.outr; + self->outr = ir_phi_value(phi); + *out = self->outr; codegen_output_type(self, *out); @@ -2800,11 +2796,11 @@ bool ast_loop_codegen(ast_loop *self, ast_function *func, bool lvalue, ir_value (void)lvalue; (void)out; - if (self->expression.outr) { + if (self->outr) { compile_error(ast_ctx(self), "internal error: ast_loop cannot be reused, it bears no result!"); return false; } - self->expression.outr = (ir_value*)1; + self->outr = (ir_value*)1; /* NOTE: * Should we ever need some kind of block ordering, better make this function @@ -2871,7 +2867,7 @@ bool ast_loop_codegen(ast_loop *self, ast_function *func, bool lvalue, ir_value bpostcond = end_bpostcond = nullptr; } - bout_id = vec_size(func->ir_func->blocks); + bout_id = func->ir_func->blocks.size(); bout = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "after_loop")); if (!bout) return false; @@ -3015,8 +3011,8 @@ bool ast_loop_codegen(ast_loop *self, ast_function *func, bool lvalue, ir_value } /* Move 'bout' to the end */ - vec_remove(func->ir_func->blocks, bout_id, 1); - vec_push(func->ir_func->blocks, bout); + func->ir_func->blocks.erase(func->ir_func->blocks.begin() + bout_id); + func->ir_func->blocks.emplace_back(bout); return true; } @@ -3032,11 +3028,11 @@ bool ast_breakcont_codegen(ast_breakcont *self, ast_function *func, bool lvalue, return false; } - if (self->expression.outr) { + if (self->outr) { compile_error(ast_ctx(self), "internal error: ast_breakcont cannot be reused!"); return false; } - self->expression.outr = (ir_value*)1; + self->outr = (ir_value*)1; if (self->is_continue) target = func->continueblocks[func->continueblocks.size()-1-self->levels]; @@ -3076,11 +3072,11 @@ bool ast_switch_codegen(ast_switch *self, ast_function *func, bool lvalue, ir_va return false; } - if (self->expression.outr) { + if (self->outr) { compile_error(ast_ctx(self), "internal error: ast_switch cannot be reused!"); return false; } - self->expression.outr = (ir_value*)1; + self->outr = (ir_value*)1; (void)lvalue; (void)out; @@ -3099,7 +3095,7 @@ bool ast_switch_codegen(ast_switch *self, ast_function *func, bool lvalue, ir_va return false; } - bout_id = vec_size(func->ir_func->blocks); + bout_id = func->ir_func->blocks.size(); bout = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "after_switch")); if (!bout) return false; @@ -3127,7 +3123,7 @@ bool ast_switch_codegen(ast_switch *self, ast_function *func, bool lvalue, ir_va return false; bcase = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "case")); - bnot_id = vec_size(func->ir_func->blocks); + bnot_id = func->ir_func->blocks.size(); bnot = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "not_case")); if (!bcase || !bnot) return false; @@ -3155,8 +3151,8 @@ bool ast_switch_codegen(ast_switch *self, ast_function *func, bool lvalue, ir_va /* enter the else and move it down */ func->curblock = bnot; - vec_remove(func->ir_func->blocks, bnot_id, 1); - vec_push(func->ir_func->blocks, bnot); + func->ir_func->blocks.erase(func->ir_func->blocks.begin() + bnot_id); + func->ir_func->blocks.emplace_back(bnot); } else { /* The default case */ /* Remember where to fall through from: */ @@ -3213,8 +3209,8 @@ bool ast_switch_codegen(ast_switch *self, ast_function *func, bool lvalue, ir_va func->breakblocks.pop_back(); /* Move 'bout' to the end, it's nicer */ - vec_remove(func->ir_func->blocks, bout_id, 1); - vec_push(func->ir_func->blocks, bout); + func->ir_func->blocks.erase(func->ir_func->blocks.begin() + bout_id); + func->ir_func->blocks.emplace_back(bout); return true; } @@ -3306,7 +3302,7 @@ bool ast_state_codegen(ast_state *self, ast_function *func, bool lvalue, ir_valu compile_error(ast_ctx(self), "not an l-value (state operation)"); return false; } - if (self->expression.outr) { + if (self->outr) { compile_error(ast_ctx(self), "internal error: ast_state cannot be reused!"); return false; } @@ -3329,7 +3325,7 @@ bool ast_state_codegen(ast_state *self, ast_function *func, bool lvalue, ir_valu return false; } - self->expression.outr = (ir_value*)1; + self->outr = (ir_value*)1; return true; } @@ -3347,8 +3343,8 @@ bool ast_call_codegen(ast_call *self, ast_function *func, bool lvalue, ir_value return false; } - if (self->expression.outr) { - *out = self->expression.outr; + if (self->outr) { + *out = self->outr; return true; } @@ -3393,7 +3389,7 @@ bool ast_call_codegen(ast_call *self, ast_function *func, bool lvalue, ir_value ir_call_param(callinstr, it); *out = ir_call_value(callinstr); - self->expression.outr = *out; + self->outr = *out; codegen_output_type(self, *out);