From: Wolfgang Bumiller Date: Mon, 19 Jan 2015 13:00:04 +0000 (+0100) Subject: making ast nodes derive from ast_expression X-Git-Tag: xonotic-v0.8.2~25 X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=commitdiff_plain;h=794396df792a4eba46ebbcfb364d4311c3a4ca72 making ast nodes derive from ast_expression --- diff --git a/ast.cpp b/ast.cpp index d71c471..948e254 100644 --- a/ast.cpp +++ b/ast.cpp @@ -118,14 +118,12 @@ 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->type_params) { @@ -325,11 +323,11 @@ ast_value* ast_value_new(lex_ctx_t ctx, const char *name, int 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.type_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; @@ -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"); @@ -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; + ast_expression *elemtype = self->next; int 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,7 +1588,7 @@ 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; } } @@ -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; + ast_expression *elemtype = self->next; int 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; } } @@ -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; @@ -1758,7 +1756,7 @@ bool ast_generate_accessors(ast_value *self, ir_builder *ir) return false; } } - for (i = 0; i < self->expression.count; ++i) { + for (i = 0; i < self->count; ++i) { vec_free(self->ir_values[i]->life); } opts_set(opts.warn, WARN_USED_UNINITIALIZED, warn); @@ -1781,12 +1779,12 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir) } /* fill the parameter list */ - ec = &self->function_type->expression; + ec = self->function_type; for (auto &it : ec->type_params) { - if (it->expression.vtype == TYPE_FIELD) - vec_push(irf->params, it->expression.next->vtype); + 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 +1794,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 +1825,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 +1844,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,15 +1852,15 @@ 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); @@ -1907,8 +1905,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 +1939,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 +1954,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 +1990,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 +2007,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 +2017,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 +2026,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 +2052,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; } @@ -2114,7 +2112,7 @@ bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_va 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 +2154,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 +2179,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 +2195,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 +2218,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 +2234,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 +2252,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 +2261,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 +2298,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 +2312,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 +2332,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 +2364,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 +2388,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 +2396,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 +2421,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 +2437,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 +2447,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 +2489,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 +2499,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 +2514,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 +2527,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 +2564,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 +2672,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 +2751,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 +2759,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 +2797,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 @@ -3032,11 +3029,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 +3073,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; @@ -3306,7 +3303,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 +3326,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 +3344,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 +3390,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); diff --git a/ast.h b/ast.h index 69e0392..a6ff49b 100644 --- a/ast.h +++ b/ast.h @@ -182,10 +182,8 @@ union basic_value_t { ast_value *vfield; }; -struct ast_value +struct ast_value : ast_expression { - ast_expression expression; - const char *name; const char *desc; @@ -252,9 +250,8 @@ enum ast_binary_ref { * * A value-returning binary expression. */ -struct ast_binary +struct ast_binary : ast_expression { - ast_expression expression; int op; ast_expression *left; ast_expression *right; @@ -271,9 +268,8 @@ ast_binary* ast_binary_new(lex_ctx_t ctx, * An assignment including a binary expression with the source as left operand. * Eg. a += b; is a binstore { INSTR_STORE, INSTR_ADD, a, b } */ -struct ast_binstore +struct ast_binstore : ast_expression { - ast_expression expression; int opstore; int opbin; ast_expression *dest; @@ -291,9 +287,8 @@ ast_binstore* ast_binstore_new(lex_ctx_t ctx, * * Regular unary expressions: not,neg */ -struct ast_unary +struct ast_unary : ast_expression { - ast_expression expression; int op; ast_expression *operand; }; @@ -307,9 +302,8 @@ ast_unary* ast_unary_new(lex_ctx_t ctx, * will refuse to create further instructions. * This should be honored by the parser. */ -struct ast_return +struct ast_return : ast_expression { - ast_expression expression; ast_expression *operand; }; ast_return* ast_return_new(lex_ctx_t ctx, @@ -328,9 +322,8 @@ ast_return* ast_return_new(lex_ctx_t ctx, * For this we will have to extend the codegen() functions with * a flag saying whether or not we need an L or an R-value. */ -struct ast_entfield +struct ast_entfield : ast_expression { - ast_expression expression; /* The entity can come from an expression of course. */ ast_expression *entity; /* As can the field, it just must result in a value of TYPE_FIELD */ @@ -344,9 +337,8 @@ ast_entfield* ast_entfield_new_force(lex_ctx_t ctx, ast_expression *entity, ast_ * For now used for vectors. If we get structs or unions * we can have them handled here as well. */ -struct ast_member +struct ast_member : ast_expression { - ast_expression expression; ast_expression *owner; unsigned int field; const char *name; @@ -367,9 +359,8 @@ bool ast_member_set_name(ast_member*, const char *name); * In any case, accessing an element via a compiletime-constant index will * result in quick access to that variable. */ -struct ast_array_index +struct ast_array_index : ast_expression { - ast_expression expression; ast_expression *array; ast_expression *index; }; @@ -379,9 +370,8 @@ ast_array_index* ast_array_index_new(lex_ctx_t ctx, ast_expression *array, ast_e * * copy all varargs starting from a specific index */ -struct ast_argpipe +struct ast_argpipe : ast_expression { - ast_expression expression; ast_expression *index; }; ast_argpipe* ast_argpipe_new(lex_ctx_t ctx, ast_expression *index); @@ -391,9 +381,8 @@ ast_argpipe* ast_argpipe_new(lex_ctx_t ctx, ast_expression *index); * Stores left<-right and returns left. * Specialized binary expression node */ -struct ast_store +struct ast_store : ast_expression { - ast_expression expression; int op; ast_expression *dest; ast_expression *source; @@ -412,9 +401,8 @@ ast_store* ast_store_new(lex_ctx_t ctx, int op, * output field though. For ternary expressions an ast_ternary will be * added. */ -struct ast_ifthen +struct ast_ifthen : ast_expression { - ast_expression expression; ast_expression *cond; /* It's all just 'expressions', since an ast_block is one too. */ ast_expression *on_true; @@ -435,9 +423,8 @@ ast_ifthen* ast_ifthen_new(lex_ctx_t ctx, ast_expression *cond, ast_expression * * This is the only ast_node beside ast_value which contains * an ir_value. Theoretically we don't need to remember it though. */ -struct ast_ternary +struct ast_ternary : ast_expression { - ast_expression expression; ast_expression *cond; /* It's all just 'expressions', since an ast_block is one too. */ ast_expression *on_true; @@ -468,9 +455,8 @@ continue: // a 'continue' will jump here {inc}; } */ -struct ast_loop +struct ast_loop : ast_expression { - ast_expression expression; ast_expression *initexpr; ast_expression *precond; ast_expression *postcond; @@ -494,10 +480,9 @@ ast_loop* ast_loop_new(lex_ctx_t ctx, /* Break/Continue */ -struct ast_breakcont +struct ast_breakcont : ast_expression { - ast_expression expression; - bool is_continue; + bool is_continue; unsigned int levels; }; ast_breakcont* ast_breakcont_new(lex_ctx_t ctx, bool iscont, unsigned int levels); @@ -517,9 +502,8 @@ struct ast_switch_case { ast_expression *code; }; -struct ast_switch +struct ast_switch : ast_expression { - ast_expression expression; ast_expression *operand; std::vector cases; }; @@ -530,9 +514,8 @@ ast_switch* ast_switch_new(lex_ctx_t ctx, ast_expression *op); * * Introduce a label which can be used together with 'goto' */ -struct ast_label +struct ast_label : ast_expression { - ast_expression expression; const char *name; ir_block *irblock; std::vector gotos; @@ -547,9 +530,8 @@ ast_label* ast_label_new(lex_ctx_t ctx, const char *name, bool undefined); * * Go to a label, the label node is filled in at a later point! */ -struct ast_goto +struct ast_goto : ast_expression { - ast_expression expression; const char *name; ast_label *target; ir_block *irblock_from; @@ -562,9 +544,8 @@ void ast_goto_set_label(ast_goto*, ast_label*); * * For frame/think state updates: void foo() [framenum, nextthink] {} */ -struct ast_state +struct ast_state : ast_expression { - ast_expression expression; ast_expression *framenum; ast_expression *nextthink; }; @@ -581,9 +562,8 @@ void ast_state_delete(ast_state*); * Additionally it contains a list of ast_expressions as parameters. * Since calls can return values, an ast_call is also an ast_expression. */ -struct ast_call +struct ast_call : ast_expression { - ast_expression expression; ast_expression *func; std::vector params; ast_expression *va_count; @@ -595,11 +575,9 @@ bool ast_call_check_types(ast_call*, ast_expression *this_func_va_type); /* Blocks * */ -struct ast_block +struct ast_block : ast_expression { - ast_expression expression; - - std::vector locals; + std::vector locals; std::vector exprs; std::vector collect; }; diff --git a/fold.cpp b/fold.cpp index d8f9de1..d2d6b6f 100644 --- a/fold.cpp +++ b/fold.cpp @@ -878,7 +878,7 @@ lex_ctx_t fold::ctx() { } bool fold::immediate_true(ast_value *v) { - switch (v->expression.vtype) { + switch (v->vtype) { case TYPE_FLOAT: return !!v->constval.vfloat; case TYPE_INTEGER: @@ -998,7 +998,7 @@ ast_expression *fold::constgen_string(const char *str, bool translate) { char name[32]; util_snprintf(name, sizeof(name), "dotranslate_%zu", m_parser->translated++); out = ast_value_new(ctx(), name, TYPE_STRING); - out->expression.flags |= AST_FLAG_INCLUDE_DEF; /* def needs to be included for translatables */ + out->flags |= AST_FLAG_INCLUDE_DEF; /* def needs to be included for translatables */ } else { out = ast_value_new(ctx(), "#IMMEDIATE", TYPE_STRING); } diff --git a/intrin.cpp b/intrin.cpp index 80fa2ea..fd7fa73 100644 --- a/intrin.cpp +++ b/intrin.cpp @@ -19,9 +19,9 @@ ast_function *intrin::value(ast_value **out, const char *name, qcint_t vtype) { value = ast_value_new(ctx(), buffer, TYPE_FUNCTION); value->intrinsic = true; - value->expression.next = (ast_expression*)ast_value_new(ctx(), stype, vtype); + value->next = (ast_expression*)ast_value_new(ctx(), stype, vtype); func = ast_function_new(ctx(), buffer, value); - value->expression.flags |= AST_FLAG_ERASEABLE; + value->flags |= AST_FLAG_ERASEABLE; *out = value; return func; @@ -55,7 +55,7 @@ ast_expression *intrin::isfinite_() { ast_block *block = ast_block_new(ctx()); /* float x; */ - val->expression.type_params.push_back(x); + val->type_params.push_back(x); /* = isnan(x); */ callisnan->params.push_back((ast_expression*)x); @@ -124,7 +124,7 @@ ast_expression *intrin::isinf_() { ) ); - val->expression.type_params.push_back(x); + val->type_params.push_back(x); func->blocks.push_back(body); reg(val, func); @@ -169,7 +169,7 @@ ast_expression *intrin::isnan_() { ) ); - val->expression.type_params.push_back(arg1); + val->type_params.push_back(arg1); func->blocks.push_back(body); reg(val, func); @@ -189,7 +189,7 @@ ast_expression *intrin::isnormal_() { ast_block *body = ast_block_new(ctx()); ast_function *func = value(&val, "isnormal", TYPE_FLOAT); - val->expression.type_params.push_back(x); + val->type_params.push_back(x); callisfinite->params.push_back((ast_expression*)x); /* return */ @@ -216,7 +216,7 @@ ast_expression *intrin::signbit_() { ast_block *body = ast_block_new(ctx()); ast_function *func = value(&val, "signbit", TYPE_FLOAT); - val->expression.type_params.push_back(x); + val->type_params.push_back(x); /* return (x < 0); */ body->exprs.push_back( @@ -254,7 +254,7 @@ ast_expression *intrin::acosh_() { ast_block *body = ast_block_new(ctx()); ast_function *func = value(&val, "acosh", TYPE_FLOAT); - val->expression.type_params.push_back(x); + val->type_params.push_back(x); /* = sqrt((x * x) - 1); */ callsqrt->params.push_back( @@ -307,7 +307,7 @@ ast_expression *intrin::asinh_() { ast_block *body = ast_block_new(ctx()); ast_function *func = value(&val, "asinh", TYPE_FLOAT); - val->expression.type_params.push_back(x); + val->type_params.push_back(x); /* = sqrt((x * x) + 1); */ callsqrt->params.push_back( @@ -359,7 +359,7 @@ ast_expression *intrin::atanh_() { ast_block *body = ast_block_new(ctx()); ast_function *func = value(&val, "atanh", TYPE_FLOAT); - val->expression.type_params.push_back(x); + val->type_params.push_back(x); /* = log((1 + x) / (1 - x)); */ calllog->params.push_back( @@ -416,7 +416,7 @@ ast_expression *intrin::exp_() { ast_block *body = ast_block_new(ctx()); ast_function *func = value(&val, "exp", TYPE_FLOAT); - val->expression.type_params.push_back(x); + val->type_params.push_back(x); body->locals.push_back(sum); body->locals.push_back(acc); @@ -521,7 +521,7 @@ ast_expression *intrin::exp2_() { ast_block *body = ast_block_new(ctx()); ast_function *func = value(&val, "exp2", TYPE_FLOAT); - val->expression.type_params.push_back(arg1); + val->type_params.push_back(arg1); callpow->params.push_back((ast_expression*)m_fold->m_imm_float[3]); callpow->params.push_back((ast_expression*)arg1); @@ -551,7 +551,7 @@ ast_expression *intrin::expm1_() { ast_block *body = ast_block_new(ctx()); ast_function *func = value(&val, "expm1", TYPE_FLOAT); - val->expression.type_params.push_back(x); + val->type_params.push_back(x); /* = exp(x); */ callexp->params.push_back((ast_expression*)x); @@ -659,8 +659,8 @@ ast_expression *intrin::pow_() { body->locals.push_back(accumulate); body->locals.push_back(mid); - val->expression.type_params.push_back(base); - val->expression.type_params.push_back(exp); + val->type_params.push_back(base); + val->type_params.push_back(exp); /* * if (exp == 0.0) @@ -1036,8 +1036,8 @@ ast_expression *intrin::mod_() { ast_block *body = ast_block_new(ctx()); ast_function *func = value(&val, "mod", TYPE_FLOAT); - val->expression.type_params.push_back(a); - val->expression.type_params.push_back(b); + val->type_params.push_back(a); + val->type_params.push_back(b); body->locals.push_back(div); body->locals.push_back(sign); @@ -1147,7 +1147,7 @@ ast_expression *intrin::fabs_() { ) ); - val->expression.type_params.push_back(arg1); + val->type_params.push_back(arg1); func->blocks.push_back(body); reg(val, func); @@ -1406,8 +1406,8 @@ ast_expression *intrin::ln_() { ast_function *func = value(&val, "ln", TYPE_FLOAT); size_t i; - val->expression.type_params.push_back(power); - val->expression.type_params.push_back(base); + val->type_params.push_back(power); + val->type_params.push_back(base); block->locals.push_back(whole); block->locals.push_back(nth); @@ -1864,7 +1864,7 @@ ast_expression *intrin::log_variant(const char *name, float base) { ast_block *body = ast_block_new(ctx()); ast_function *func = value(&val, name, TYPE_FLOAT); - val->expression.type_params.push_back(arg1); + val->type_params.push_back(arg1); callln->params.push_back((ast_expression*)arg1); callln->params.push_back((ast_expression*)m_fold->constgen_float(base, false)); @@ -1908,8 +1908,8 @@ ast_expression *intrin::shift_variant(const char *name, size_t instr) { ast_block *body = ast_block_new(ctx()); ast_function *func = value(&val, name, TYPE_FLOAT); - val->expression.type_params.push_back(a); - val->expression.type_params.push_back(b); + val->type_params.push_back(a); + val->type_params.push_back(b); /* = pow(2, b) */ callpow->params.push_back((ast_expression*)m_fold->m_imm_float[3]); @@ -2025,7 +2025,7 @@ ast_expression *intrin::func_try(size_t offset, const char *compare) { ast_expression *intrin::func_self(const char *name, const char *from) { ast_expression *find; /* try current first */ - if ((find = parser_find_global(m_parser, name)) && ((ast_value*)find)->expression.vtype == TYPE_FUNCTION) + if ((find = parser_find_global(m_parser, name)) && ((ast_value*)find)->vtype == TYPE_FUNCTION) for (auto &it : m_parser->functions) if (((ast_value*)find)->name && !strcmp(it->name, ((ast_value*)find)->name) && it->builtin < 0) return find; diff --git a/parser.cpp b/parser.cpp index b5c63a3..70c81f2 100644 --- a/parser.cpp +++ b/parser.cpp @@ -103,7 +103,7 @@ static ast_expression* parser_find_param(parser_t *parser, const char *name) if (!parser->function) return nullptr; fun = parser->function->function_type; - for (auto &it : fun->expression.type_params) { + for (auto &it : fun->type_params) { if (!strcmp(it->name, name)) return (ast_expression*)it; } @@ -1269,7 +1269,7 @@ static bool parser_close_call(parser_t *parser, shunt *sy) for (i = 0; i < paramcount; ++i) call->params.push_back(sy->out[fid+1 + i].out); sy->out.erase(sy->out.end() - paramcount, sy->out.end()); - (void)!ast_call_check_types(call, parser->function->function_type->expression.varparam); + (void)!ast_call_check_types(call, parser->function->function_type->varparam); if (parser->max_param_count < paramcount) parser->max_param_count = paramcount; @@ -1283,7 +1283,7 @@ static bool parser_close_call(parser_t *parser, shunt *sy) } /* overwrite fid, the function, with a call */ - sy->out[fid] = syexp(call->expression.context, (ast_expression*)call); + sy->out[fid] = syexp(call->context, (ast_expression*)call); if (fun->vtype != TYPE_FUNCTION) { parseerror(parser, "not a function (%s)", type_name[fun->vtype]); @@ -1456,13 +1456,13 @@ static ast_expression* parse_vararg_do(parser_t *parser) return nullptr; } - if (funtype->expression.varparam && - !ast_compare_type((ast_expression*)typevar, (ast_expression*)funtype->expression.varparam)) + if (funtype->varparam && + !ast_compare_type((ast_expression*)typevar, (ast_expression*)funtype->varparam)) { char ty1[1024]; char ty2[1024]; ast_type_to_string((ast_expression*)typevar, ty1, sizeof(ty1)); - ast_type_to_string((ast_expression*)funtype->expression.varparam, ty2, sizeof(ty2)); + ast_type_to_string((ast_expression*)funtype->varparam, ty2, sizeof(ty2)); compile_error(ast_ctx(typevar), "function was declared to take varargs of type `%s`, requested type is: %s", ty2, ty1); @@ -1890,7 +1890,7 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma if (ast_istype(lexpr, ast_value)) { ast_value *last = (ast_value*)lexpr; if (last->isimm == true && last->cvq == CV_CONST && - last->hasvalue && last->expression.vtype == TYPE_STRING) + last->hasvalue && last->vtype == TYPE_STRING) { char *newstr = nullptr; util_asprintf(&newstr, "%s%s", last->constval.vstring, parser_tokval(parser)); @@ -2580,9 +2580,9 @@ static bool parse_return(parser_t *parser, ast_block *block, ast_expression **ou return false; } - if (type_store_instr[expected->expression.next->vtype] == VINSTR_END) { + if (type_store_instr[expected->next->vtype] == VINSTR_END) { char ty1[1024]; - ast_type_to_string(expected->expression.next, ty1, sizeof(ty1)); + ast_type_to_string(expected->next, ty1, sizeof(ty1)); parseerror(parser, "invalid return type: `%s'", ty1); return false; } @@ -2598,21 +2598,21 @@ static bool parse_return(parser_t *parser, ast_block *block, ast_expression **ou /* prepare the return value */ if (!retval) { retval = ast_value_new(ctx, "#LOCAL_RETURN", TYPE_VOID); - ast_type_adopt(retval, expected->expression.next); + ast_type_adopt(retval, expected->next); parser->function->return_value = retval; } if (!ast_compare_type(exp, (ast_expression*)retval)) { char ty1[1024], ty2[1024]; ast_type_to_string(exp, ty1, sizeof(ty1)); - ast_type_to_string(&retval->expression, ty2, sizeof(ty2)); + ast_type_to_string(retval, ty2, sizeof(ty2)); parseerror(parser, "invalid type for return value: `%s', expected `%s'", ty1, ty2); } /* store to 'return' local variable */ var = (ast_expression*)ast_store_new( ctx, - type_store_instr[expected->expression.next->vtype], + type_store_instr[expected->next->vtype], (ast_expression*)retval, exp); if (!var) { @@ -2649,7 +2649,7 @@ static bool parse_return(parser_t *parser, ast_block *block, ast_expression **ou if (!parser_next(parser)) parseerror(parser, "parse error"); - if (!retval && expected->expression.next->vtype != TYPE_VOID) + if (!retval && expected->next->vtype != TYPE_VOID) { (void)!parsewarning(parser, WARN_MISSING_RETURN_VALUES, "return without value"); } @@ -3784,7 +3784,7 @@ static bool parse_function_body(parser_t *parser, ast_value *var) has_frame_think = false; old = parser->function; - if (var->expression.flags & AST_FLAG_ALIAS) { + if (var->flags & AST_FLAG_ALIAS) { parseerror(parser, "function aliases cannot have bodies"); return false; } @@ -3794,7 +3794,7 @@ static bool parse_function_body(parser_t *parser, ast_value *var) return false; } - if (!OPTS_FLAG(VARIADIC_ARGS) && var->expression.flags & AST_FLAG_VARIADIC) { + if (!OPTS_FLAG(VARIADIC_ARGS) && var->flags & AST_FLAG_VARIADIC) { if (parsewarning(parser, WARN_VARIADIC_FUNCTION, "variadic function with implementation will not be able to access additional parameters (try -fvariadic-args)")) { @@ -4007,7 +4007,7 @@ static bool parse_function_body(parser_t *parser, ast_value *var) } if (var->hasvalue) { - if (!(var->expression.flags & AST_FLAG_ACCUMULATE)) { + if (!(var->flags & AST_FLAG_ACCUMULATE)) { parseerror(parser, "function `%s` declared with multiple bodies", var->name); ast_block_delete(block); goto enderr; @@ -4032,13 +4032,13 @@ static bool parse_function_body(parser_t *parser, ast_value *var) parser_enterblock(parser); - for (auto &it : var->expression.type_params) { + for (auto &it : var->type_params) { size_t e; ast_member *me[3]; - if (it->expression.vtype != TYPE_VECTOR && - (it->expression.vtype != TYPE_FIELD || - it->expression.next->vtype != TYPE_VECTOR)) + if (it->vtype != TYPE_VECTOR && + (it->vtype != TYPE_FIELD || + it->next->vtype != TYPE_VECTOR)) { continue; } @@ -4060,12 +4060,12 @@ static bool parse_function_body(parser_t *parser, ast_value *var) func->argc = argc; } - if (OPTS_FLAG(VARIADIC_ARGS) && var->expression.flags & AST_FLAG_VARIADIC && !func->varargs) { + if (OPTS_FLAG(VARIADIC_ARGS) && var->flags & AST_FLAG_VARIADIC && !func->varargs) { char name[1024]; ast_value *varargs = ast_value_new(ast_ctx(var), "reserved:va_args", TYPE_ARRAY); - varargs->expression.flags |= AST_FLAG_IS_VARARG; - varargs->expression.next = (ast_expression*)ast_value_new(ast_ctx(var), nullptr, TYPE_VECTOR); - varargs->expression.count = 0; + varargs->flags |= AST_FLAG_IS_VARARG; + varargs->next = (ast_expression*)ast_value_new(ast_ctx(var), nullptr, TYPE_VECTOR); + varargs->count = 0; util_snprintf(name, sizeof(name), "%s##va##SET", var->name); if (!parser_create_array_setter_proto(parser, varargs, name)) { ast_delete(varargs); @@ -4073,13 +4073,13 @@ static bool parse_function_body(parser_t *parser, ast_value *var) goto enderrfn; } util_snprintf(name, sizeof(name), "%s##va##GET", var->name); - if (!parser_create_array_getter_proto(parser, varargs, varargs->expression.next, name)) { + if (!parser_create_array_getter_proto(parser, varargs, varargs->next, name)) { ast_delete(varargs); ast_block_delete(block); goto enderrfn; } func->varargs = varargs; - func->fixedparams = (ast_value*)parser->m_fold.constgen_float(var->expression.type_params.size(), false); + func->fixedparams = (ast_value*)parser->m_fold.constgen_float(var->type_params.size(), false); } parser->function = func; @@ -4165,9 +4165,9 @@ static ast_expression *array_setter_node(parser_t *parser, ast_value *array, ast ast_return *ret; ast_array_index *subscript; ast_store *st; - int assignop = type_store_instr[value->expression.vtype]; + int assignop = type_store_instr[value->vtype]; - if (value->expression.vtype == TYPE_FIELD && value->expression.next->vtype == TYPE_VECTOR) + if (value->vtype == TYPE_FIELD && value->next->vtype == TYPE_VECTOR) assignop = INSTR_STORE_V; subscript = ast_array_index_new(ctx, (ast_expression*)array, (ast_expression*)parser->m_fold.constgen_float(from, false)); @@ -4231,17 +4231,17 @@ static ast_expression *array_field_setter_node( ast_entfield *entfield; ast_array_index *subscript; ast_store *st; - int assignop = type_storep_instr[value->expression.vtype]; + int assignop = type_storep_instr[value->vtype]; - if (value->expression.vtype == TYPE_FIELD && value->expression.next->vtype == TYPE_VECTOR) + if (value->vtype == TYPE_FIELD && value->next->vtype == TYPE_VECTOR) assignop = INSTR_STOREP_V; subscript = ast_array_index_new(ctx, (ast_expression*)array, (ast_expression*)parser->m_fold.constgen_float(from, false)); if (!subscript) return nullptr; - subscript->expression.next = ast_type_copy(ast_ctx(subscript), (ast_expression*)subscript); - subscript->expression.vtype = TYPE_FIELD; + subscript->next = ast_type_copy(ast_ctx(subscript), (ast_expression*)subscript); + subscript->vtype = TYPE_FIELD; entfield = ast_entfield_new_force(ctx, (ast_expression*)entity, @@ -4331,7 +4331,7 @@ static bool parser_create_array_accessor(parser_t *parser, ast_value *array, con parseerror(parser, "failed to create accessor function value"); return false; } - fval->expression.flags &= ~(AST_FLAG_COVERAGE_MASK); + fval->flags &= ~(AST_FLAG_COVERAGE_MASK); func = ast_function_new(ast_ctx(array), funcname, fval); if (!func) { @@ -4363,7 +4363,7 @@ static ast_value* parser_create_array_setter_proto(parser_t *parser, ast_value * ast_function *func; ast_value *fval; - if (!ast_istype(array->expression.next, ast_value)) { + if (!ast_istype(array->next, ast_value)) { parseerror(parser, "internal error: array accessor needs to build an ast_value with a copy of the element type"); return nullptr; } @@ -4371,18 +4371,18 @@ static ast_value* parser_create_array_setter_proto(parser_t *parser, ast_value * if (!parser_create_array_accessor(parser, array, funcname, &fval)) return nullptr; func = fval->constval.vfunc; - fval->expression.next = (ast_expression*)ast_value_new(ast_ctx(array), "", TYPE_VOID); + fval->next = (ast_expression*)ast_value_new(ast_ctx(array), "", TYPE_VOID); index = ast_value_new(ast_ctx(array), "index", TYPE_FLOAT); - value = ast_value_copy((ast_value*)array->expression.next); + value = ast_value_copy((ast_value*)array->next); if (!index || !value) { parseerror(parser, "failed to create locals for array accessor"); goto cleanup; } (void)!ast_value_set_name(value, "value"); /* not important */ - fval->expression.type_params.push_back(index); - fval->expression.type_params.push_back(value); + fval->type_params.push_back(index); + fval->type_params.push_back(value); array->setter = fval; return fval; @@ -4398,9 +4398,9 @@ static bool parser_create_array_setter_impl(parser_t *parser, ast_value *array) { ast_expression *root = nullptr; root = array_setter_node(parser, array, - array->setter->expression.type_params[0], - array->setter->expression.type_params[1], - 0, array->expression.count); + array->setter->type_params[0], + array->setter->type_params[1], + 0, array->count); if (!root) { parseerror(parser, "failed to build accessor search tree"); return false; @@ -4428,7 +4428,7 @@ static bool parser_create_array_field_setter(parser_t *parser, ast_value *array, ast_function *func; ast_value *fval; - if (!ast_istype(array->expression.next, ast_value)) { + if (!ast_istype(array->next, ast_value)) { parseerror(parser, "internal error: array accessor needs to build an ast_value with a copy of the element type"); return false; } @@ -4436,21 +4436,21 @@ static bool parser_create_array_field_setter(parser_t *parser, ast_value *array, if (!parser_create_array_accessor(parser, array, funcname, &fval)) return false; func = fval->constval.vfunc; - fval->expression.next = (ast_expression*)ast_value_new(ast_ctx(array), "", TYPE_VOID); + fval->next = (ast_expression*)ast_value_new(ast_ctx(array), "", TYPE_VOID); entity = ast_value_new(ast_ctx(array), "entity", TYPE_ENTITY); index = ast_value_new(ast_ctx(array), "index", TYPE_FLOAT); - value = ast_value_copy((ast_value*)array->expression.next); + value = ast_value_copy((ast_value*)array->next); if (!entity || !index || !value) { parseerror(parser, "failed to create locals for array accessor"); goto cleanup; } (void)!ast_value_set_name(value, "value"); /* not important */ - fval->expression.type_params.push_back(entity); - fval->expression.type_params.push_back(index); - fval->expression.type_params.push_back(value); + fval->type_params.push_back(entity); + fval->type_params.push_back(index); + fval->type_params.push_back(value); - root = array_field_setter_node(parser, array, entity, index, value, 0, array->expression.count); + root = array_field_setter_node(parser, array, entity, index, value, 0, array->count); if (!root) { parseerror(parser, "failed to build accessor search tree"); goto cleanup; @@ -4474,10 +4474,10 @@ static ast_value* parser_create_array_getter_proto(parser_t *parser, ast_value * ast_value *fval; ast_function *func; - /* NOTE: checking array->expression.next rather than elemtype since + /* NOTE: checking array->next rather than elemtype since * for fields elemtype is a temporary fieldtype. */ - if (!ast_istype(array->expression.next, ast_value)) { + if (!ast_istype(array->next, ast_value)) { parseerror(parser, "internal error: array accessor needs to build an ast_value with a copy of the element type"); return nullptr; } @@ -4485,7 +4485,7 @@ static ast_value* parser_create_array_getter_proto(parser_t *parser, ast_value * if (!parser_create_array_accessor(parser, array, funcname, &fval)) return nullptr; func = fval->constval.vfunc; - fval->expression.next = ast_type_copy(ast_ctx(array), elemtype); + fval->next = ast_type_copy(ast_ctx(array), elemtype); index = ast_value_new(ast_ctx(array), "index", TYPE_FLOAT); @@ -4493,7 +4493,7 @@ static ast_value* parser_create_array_getter_proto(parser_t *parser, ast_value * parseerror(parser, "failed to create locals for array accessor"); goto cleanup; } - fval->expression.type_params.push_back(index); + fval->type_params.push_back(index); array->getter = fval; return fval; @@ -4508,7 +4508,7 @@ static bool parser_create_array_getter_impl(parser_t *parser, ast_value *array) { ast_expression *root = nullptr; - root = array_getter_node(parser, array, array->getter->expression.type_params[0], 0, array->expression.count); + root = array_getter_node(parser, array, array->getter->type_params[0], 0, array->count); if (!root) { parseerror(parser, "failed to build accessor search tree"); return false; @@ -4580,7 +4580,7 @@ static ast_value *parse_parameter_list(parser_t *parser, ast_value *var) } } else { params.push_back(param); - if (param->expression.vtype >= TYPE_VARIANT) { + if (param->vtype >= TYPE_VARIANT) { char tname[1024]; /* typename is reserved in C++ */ ast_type_to_string((ast_expression*)param, tname, sizeof(tname)); parseerror(parser, "type not supported as part of a parameter list: %s", tname); @@ -4611,7 +4611,7 @@ static ast_value *parse_parameter_list(parser_t *parser, ast_value *var) } } - if (params.size() == 1 && params[0]->expression.vtype == TYPE_VOID) + if (params.size() == 1 && params[0]->vtype == TYPE_VOID) params.clear(); /* sanity check */ @@ -4626,13 +4626,13 @@ static ast_value *parse_parameter_list(parser_t *parser, ast_value *var) /* now turn 'var' into a function type */ fval = ast_value_new(ctx, "", TYPE_FUNCTION); - fval->expression.next = (ast_expression*)var; + fval->next = (ast_expression*)var; if (variadic) - fval->expression.flags |= AST_FLAG_VARIADIC; + fval->flags |= AST_FLAG_VARIADIC; var = fval; - var->expression.type_params = move(params); - var->expression.varparam = (ast_expression*)varparam; + var->type_params = move(params); + var->varparam = (ast_expression*)varparam; var->argcounter = argcounter; return var; @@ -4680,14 +4680,14 @@ static ast_value *parse_arraysize(parser_t *parser, ast_value *var) } tmp = ast_value_new(ctx, "", TYPE_ARRAY); - tmp->expression.next = (ast_expression*)var; + tmp->next = (ast_expression*)var; var = tmp; if (cval) { - if (cval->expression.vtype == TYPE_INTEGER) - tmp->expression.count = cval->constval.vint; - else if (cval->expression.vtype == TYPE_FLOAT) - tmp->expression.count = cval->constval.vfloat; + if (cval->vtype == TYPE_INTEGER) + tmp->count = cval->constval.vint; + else if (cval->vtype == TYPE_FLOAT) + tmp->count = cval->constval.vfloat; else { ast_unref(cexp); ast_delete(var); @@ -4697,8 +4697,8 @@ static ast_value *parse_arraysize(parser_t *parser, ast_value *var) ast_unref(cexp); } else { - var->expression.count = -1; - var->expression.flags |= AST_FLAG_ARRAY_INIT; + var->count = -1; + var->flags |= AST_FLAG_ARRAY_INIT; } if (parser->tok != ']') { @@ -4795,7 +4795,7 @@ static ast_value *parse_typename(parser_t *parser, ast_value **storebase, ast_va for (; morefields; --morefields) { tmp = ast_value_new(ctx, "<.type>", TYPE_FIELD); - tmp->expression.next = (ast_expression*)var; + tmp->next = (ast_expression*)var; var = tmp; } @@ -4827,7 +4827,7 @@ static ast_value *parse_typename(parser_t *parser, ast_value **storebase, ast_va *storebase = ast_value_copy(var); if (isfield) { tmp = ast_value_new(ctx, "", TYPE_FIELD); - tmp->expression.next = (ast_expression*)*storebase; + tmp->next = (ast_expression*)*storebase; *storebase = tmp; } } @@ -4865,7 +4865,7 @@ static ast_value *parse_typename(parser_t *parser, ast_value **storebase, ast_va if (isfield) { /* turn it into a field if desired */ tmp = ast_value_new(ctx, "", TYPE_FIELD); - tmp->expression.next = (ast_expression*)var; + tmp->next = (ast_expression*)var; var = tmp; } @@ -4969,8 +4969,8 @@ static bool parser_check_qualifiers(parser_t *parser, const ast_value *var, cons cvq_to_str(proto->cvq)); } } - av = (var ->expression.flags & AST_FLAG_NORETURN); - ao = (proto->expression.flags & AST_FLAG_NORETURN); + av = (var ->flags & AST_FLAG_NORETURN); + ao = (proto->flags & AST_FLAG_NORETURN); if (!av != !ao) { return !parsewarning(parser, WARN_DIFFERENT_ATTRIBUTES, "`%s` declared with different attributes%s\n" @@ -4989,7 +4989,7 @@ static bool create_array_accessors(parser_t *parser, ast_value *var) if (!parser_create_array_setter(parser, var, name)) return false; util_snprintf(name, sizeof(name), "%s##GET", var->name); - if (!parser_create_array_getter(parser, var, var->expression.next, name)) + if (!parser_create_array_getter(parser, var, var->next, name)) return false; return true; } @@ -5016,7 +5016,7 @@ static bool parse_array(parser_t *parser, ast_value *array) return false; } array->initlist.push_back(v->constval); - if (v->expression.vtype == TYPE_STRING) { + if (v->vtype == TYPE_STRING) { array->initlist[i].vstring = util_strdupe(array->initlist[i].vstring); ++i; } @@ -5039,12 +5039,12 @@ static bool parse_array(parser_t *parser, ast_value *array) } */ - if (array->expression.flags & AST_FLAG_ARRAY_INIT) { - if (array->expression.count != (size_t)-1) { + if (array->flags & AST_FLAG_ARRAY_INIT) { + if (array->count != (size_t)-1) { parseerror(parser, "array `%s' has already been initialized with %u elements", - array->name, (unsigned)array->expression.count); + array->name, (unsigned)array->count); } - array->expression.count = array->initlist.size(); + array->count = array->initlist.size(); if (!create_array_accessors(parser, array)) return false; } @@ -5128,18 +5128,18 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield var->cvq = qualifier; if (qflags & AST_FLAG_COVERAGE) /* specified in QC, drop our default */ - var->expression.flags &= ~(AST_FLAG_COVERAGE_MASK); - var->expression.flags |= qflags; + var->flags &= ~(AST_FLAG_COVERAGE_MASK); + var->flags |= qflags; /* * store the vstring back to var for alias and * deprecation messages. */ - if (var->expression.flags & AST_FLAG_DEPRECATED || - var->expression.flags & AST_FLAG_ALIAS) + if (var->flags & AST_FLAG_DEPRECATED || + var->flags & AST_FLAG_ALIAS) var->desc = vstring; - if (parser_find_global(parser, var->name) && var->expression.flags & AST_FLAG_ALIAS) { + if (parser_find_global(parser, var->name) && var->flags & AST_FLAG_ALIAS) { parseerror(parser, "function aliases cannot be forward declared"); retval = false; goto cleanup; @@ -5171,7 +5171,7 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield parser->crc_fields = parser->fields.size(); was_end = true; } - if (was_end && var->expression.vtype == TYPE_FIELD) { + if (was_end && var->vtype == TYPE_FIELD) { if (parsewarning(parser, WARN_END_SYS_FIELDS, "global '%s' hint should not be a field", parser_tokval(parser))) @@ -5181,7 +5181,7 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield } } - if (!nofields && var->expression.vtype == TYPE_FIELD) + if (!nofields && var->vtype == TYPE_FIELD) { /* deal with field declarations */ old = parser_find_field(parser, var->name); @@ -5216,7 +5216,7 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield { /* deal with other globals */ old = parser_find_global(parser, var->name); - if (old && var->expression.vtype == TYPE_FUNCTION && old->vtype == TYPE_FUNCTION) + if (old && var->vtype == TYPE_FUNCTION && old->vtype == TYPE_FUNCTION) { /* This is a function which had a prototype */ if (!ast_istype(old, ast_value)) { @@ -5234,8 +5234,8 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield goto cleanup; } /* we need the new parameter-names */ - for (i = 0; i < proto->expression.type_params.size(); ++i) - ast_value_set_name(proto->expression.type_params[i], var->expression.type_params[i]->name); + for (i = 0; i < proto->type_params.size(); ++i) + ast_value_set_name(proto->type_params[i], var->type_params[i]->name); if (!parser_check_qualifiers(parser, var, proto)) { retval = false; if (proto->desc) @@ -5243,7 +5243,7 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield proto = nullptr; goto cleanup; } - proto->expression.flags |= var->expression.flags; + proto->flags |= var->flags; ast_delete(var); var = proto; } @@ -5276,11 +5276,11 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield proto = nullptr; goto cleanup; } - proto->expression.flags |= var->expression.flags; + proto->flags |= var->flags; /* copy the context for finals, * so the error can show where it was actually made 'final' */ - if (proto->expression.flags & AST_FLAG_FINAL_DECL) + if (proto->flags & AST_FLAG_FINAL_DECL) ast_ctx(old) = ast_ctx(var); ast_delete(var); var = proto; @@ -5337,10 +5337,10 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield * Create the global/local, and deal with vector types. */ if (!proto) { - if (var->expression.vtype == TYPE_VECTOR) + if (var->vtype == TYPE_VECTOR) isvector = true; - else if (var->expression.vtype == TYPE_FIELD && - var->expression.next->vtype == TYPE_VECTOR) + else if (var->vtype == TYPE_FIELD && + var->next->vtype == TYPE_VECTOR) isvector = true; if (isvector) { @@ -5352,7 +5352,7 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield if (!localblock) { /* deal with global variables, fields, functions */ - if (!nofields && var->expression.vtype == TYPE_FIELD && parser->tok != '=') { + if (!nofields && var->vtype == TYPE_FIELD && parser->tok != '=') { var->isfield = true; parser->fields.push_back((ast_expression*)var); util_htset(parser->htfields, var->name, var); @@ -5364,7 +5364,7 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield } } else { - if (!(var->expression.flags & AST_FLAG_ALIAS)) { + if (!(var->flags & AST_FLAG_ALIAS)) { parser_addglobal(parser, var->name, (ast_expression*)var); if (isvector) { for (i = 0; i < 3; ++i) { @@ -5489,22 +5489,22 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield /* Part 2.2 * deal with arrays */ - if (var->expression.vtype == TYPE_ARRAY) { - if (var->expression.count != (size_t)-1) { + if (var->vtype == TYPE_ARRAY) { + if (var->count != (size_t)-1) { if (!create_array_accessors(parser, var)) goto cleanup; } } else if (!localblock && !nofields && - var->expression.vtype == TYPE_FIELD && - var->expression.next->vtype == TYPE_ARRAY) + var->vtype == TYPE_FIELD && + var->next->vtype == TYPE_ARRAY) { char name[1024]; ast_expression *telem; ast_value *tfield; - ast_value *array = (ast_value*)var->expression.next; + ast_value *array = (ast_value*)var->next; - if (!ast_istype(var->expression.next, ast_value)) { + if (!ast_istype(var->next, ast_value)) { parseerror(parser, "internal error: field element type must be an ast_value"); goto cleanup; } @@ -5513,9 +5513,9 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield if (!parser_create_array_field_setter(parser, array, name)) goto cleanup; - telem = ast_type_copy(ast_ctx(var), array->expression.next); + telem = ast_type_copy(ast_ctx(var), array->next); tfield = ast_value_new(ast_ctx(var), "<.type>", TYPE_FIELD); - tfield->expression.next = telem; + tfield->next = telem; util_snprintf(name, sizeof(name), "%s##GETFP", var->name); if (!parser_create_array_getter(parser, array, (ast_expression*)tfield, name)) { ast_delete(tfield); @@ -5538,7 +5538,7 @@ skipvar: goto another; /* - if (!var || (!localblock && !nofields && basetype->expression.vtype == TYPE_FIELD)) { + if (!var || (!localblock && !nofields && basetype->vtype == TYPE_FIELD)) { */ if (!var) { parseerror(parser, "missing comma or semicolon while parsing variables"); @@ -5554,7 +5554,7 @@ skipvar: } } - if (parser->tok != '{' || var->expression.vtype != TYPE_FUNCTION) { + if (parser->tok != '{' || var->vtype != TYPE_FUNCTION) { if (parser->tok != '=') { parseerror(parser, "missing semicolon or initializer, got: `%s`", parser_tokval(parser)); break; @@ -5580,7 +5580,7 @@ skipvar: parseerror(parser, "cannot declare builtins within functions"); break; } - if (var->expression.vtype != TYPE_FUNCTION) { + if (var->vtype != TYPE_FUNCTION) { parseerror(parser, "unexpected builtin number, '%s' is not a function", var->name); break; } @@ -5601,9 +5601,9 @@ skipvar: parseerror(parser, "builtin number must be a compile time constant"); break; } - if (number->expression.vtype == TYPE_INTEGER) + if (number->vtype == TYPE_INTEGER) builtin_num = number->constval.vint; - else if (number->expression.vtype == TYPE_FLOAT) + else if (number->vtype == TYPE_FLOAT) builtin_num = number->constval.vfloat; else { ast_unref(number); @@ -5656,7 +5656,7 @@ skipvar: break; } } - else if (var->expression.vtype == TYPE_ARRAY && parser->tok == '{') + else if (var->vtype == TYPE_ARRAY && parser->tok == '{') { if (localblock) { /* Note that fteqcc and most others don't even *have* @@ -5670,7 +5670,7 @@ skipvar: if (!parse_array(parser, var)) break; } - else if (var->expression.vtype == TYPE_FUNCTION && (parser->tok == '{' || parser->tok == '[')) + else if (var->vtype == TYPE_FUNCTION && (parser->tok == '{' || parser->tok == '[')) { if (localblock) { parseerror(parser, "cannot declare functions within functions"); @@ -5740,13 +5740,13 @@ skipvar: var->cvq = CV_CONST; } if (cval == parser->nil) - var->expression.flags |= AST_FLAG_INITIALIZED; + var->flags |= AST_FLAG_INITIALIZED; else { var->hasvalue = true; - if (cval->expression.vtype == TYPE_STRING) + if (cval->vtype == TYPE_STRING) var->constval.vstring = parser_strdup(cval->constval.vstring); - else if (cval->expression.vtype == TYPE_FIELD) + else if (cval->vtype == TYPE_FIELD) var->constval.vfield = cval; else memcpy(&var->constval, &cval->constval, sizeof(var->constval)); @@ -5774,7 +5774,7 @@ skipvar: /* a constant initialized to an inexact value should be marked inexact: * const float x = ; should propagate the inexact flag */ - if (var->cvq == CV_CONST && var->expression.vtype == TYPE_FLOAT) { + if (var->cvq == CV_CONST && var->vtype == TYPE_FLOAT) { if (cval && cval->hasvalue && cval->cvq == CV_CONST) var->inexact = cval->inexact; } @@ -5929,7 +5929,7 @@ static void generate_checksum(parser_t *parser, ir_builder *ir) if (!ast_istype(parser->globals[i], ast_value)) continue; value = (ast_value*)(parser->globals[i]); - switch (value->expression.vtype) { + switch (value->vtype) { case TYPE_FLOAT: crc = progdefs_crc_both(crc, "\tfloat\t"); break; case TYPE_VECTOR: crc = progdefs_crc_both(crc, "\tvec3_t\t"); break; case TYPE_STRING: crc = progdefs_crc_both(crc, "\tstring_t\t"); break; @@ -5946,7 +5946,7 @@ static void generate_checksum(parser_t *parser, ir_builder *ir) if (!ast_istype(parser->fields[i], ast_value)) continue; value = (ast_value*)(parser->fields[i]); - switch (value->expression.next->vtype) { + switch (value->next->vtype) { case TYPE_FLOAT: crc = progdefs_crc_both(crc, "\tfloat\t"); break; case TYPE_VECTOR: crc = progdefs_crc_both(crc, "\tvec3_t\t"); break; case TYPE_STRING: crc = progdefs_crc_both(crc, "\tstring_t\t"); break; @@ -6014,7 +6014,7 @@ parser_t *parser_create() parser->reserved_version = ast_value_new(empty_ctx, "reserved:version", TYPE_STRING); parser->reserved_version->cvq = CV_CONST; parser->reserved_version->hasvalue = true; - parser->reserved_version->expression.flags |= AST_FLAG_INCLUDE_DEF; + parser->reserved_version->flags |= AST_FLAG_INCLUDE_DEF; parser->reserved_version->constval.vstring = util_strdup(GMQCC_FULL_VERSION_STRING); } else { parser->reserved_version = nullptr; @@ -6197,7 +6197,7 @@ bool parser_finish(parser_t *parser, const char *output) ir_value *ifld; ast_expression *subtype; field->hasvalue = true; - subtype = field->expression.next; + subtype = field->next; ifld = ir_builder_create_field(ir, field->name, subtype->vtype); if (subtype->vtype == TYPE_FIELD) ifld->fieldtype = subtype->next->vtype; @@ -6211,7 +6211,7 @@ bool parser_finish(parser_t *parser, const char *output) if (!ast_istype(it, ast_value)) continue; asvalue = (ast_value*)it; - if (!asvalue->uses && !asvalue->hasvalue && asvalue->expression.vtype != TYPE_FUNCTION) { + if (!asvalue->uses && !asvalue->hasvalue && asvalue->vtype != TYPE_FUNCTION) { retval = retval && !compile_warning(ast_ctx(asvalue), WARN_UNUSED_VARIABLE, "unused global: `%s`", asvalue->name); } @@ -6226,8 +6226,8 @@ bool parser_finish(parser_t *parser, const char *output) */ for (auto &f : parser->functions) { if (f->varargs) { - if (parser->max_param_count > f->function_type->expression.type_params.size()) { - f->varargs->expression.count = parser->max_param_count - f->function_type->expression.type_params.size(); + if (parser->max_param_count > f->function_type->type_params.size()) { + f->varargs->count = parser->max_param_count - f->function_type->type_params.size(); if (!parser_create_array_setter_impl(parser, f->varargs)) { con_out("failed to generate vararg setter for %s\n", f->name); ir_builder_delete(ir); @@ -6255,7 +6255,7 @@ bool parser_finish(parser_t *parser, const char *output) if (!ast_istype(it, ast_value)) continue; ast_value *asvalue = (ast_value*)it; - if (!(asvalue->expression.flags & AST_FLAG_INITIALIZED)) + if (!(asvalue->flags & AST_FLAG_INITIALIZED)) { if (asvalue->cvq == CV_CONST && !asvalue->hasvalue) (void)!compile_warning(ast_ctx(asvalue), WARN_UNINITIALIZED_CONSTANT, @@ -6275,7 +6275,7 @@ bool parser_finish(parser_t *parser, const char *output) ast_value *asvalue = (ast_value*)it->next; if (!ast_istype((ast_expression*)asvalue, ast_value)) continue; - if (asvalue->expression.vtype != TYPE_ARRAY) + if (asvalue->vtype != TYPE_ARRAY) continue; if (!ast_generate_accessors(asvalue, ir)) { ir_builder_delete(ir);