X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=ast.cpp;h=10356bead71e9afd692dc05a9121d561b3988502;hp=29e298ab817a2b551ca5fc7abee7063d7d2c72bd;hb=5968e3faa02ce4b23a9b9980fde7e5021943f3d8;hpb=65362d93aa4678209bfeeba92fb5aa41f5955777 diff --git a/ast.cpp b/ast.cpp index 29e298a..10356be 100644 --- a/ast.cpp +++ b/ast.cpp @@ -1,15 +1,21 @@ +#include + #include #include #include "gmqcc.h" #include "ast.h" -#include "parser.h" +#include "fold.h" +//#include "parser.h" + +#include "algo.h" #define ast_instantiate(T, ctx, destroyfn) \ T* self = (T*)mem_a(sizeof(T)); \ if (!self) { \ - return NULL; \ + return nullptr; \ } \ + new (self) T(); \ ast_node_init((ast_node*)self, ctx, TYPE_##T); \ ( (ast_node*)self )->destroy = (ast_node_delete*)destroyfn @@ -63,12 +69,12 @@ static GMQCC_NORETURN void _ast_node_destroy(ast_node *self) } /* Initialize main ast node aprts */ -static void ast_node_init(ast_node *self, lex_ctx_t ctx, int nodetype) +static void ast_node_init(ast_node *self, lex_ctx_t ctx, int node_type) { self->context = ctx; - self->destroy = &_ast_node_destroy; - self->keep = false; - self->nodetype = nodetype; + self->destroy = &_ast_node_destroy; + self->keep_node = false; + self->node_type = node_type; self->side_effects = false; } @@ -86,12 +92,11 @@ static void ast_expression_init(ast_expression *self, { self->codegen = codegen; self->vtype = TYPE_VOID; - self->next = NULL; - self->outl = NULL; - self->outr = NULL; - self->params = NULL; + self->next = nullptr; + self->outl = nullptr; + self->outr = nullptr; self->count = 0; - self->varparam = NULL; + self->varparam = nullptr; self->flags = 0; if (OPTS_OPTION_BOOL(OPTION_COVERAGE)) self->flags |= AST_FLAG_BLOCK_COVERAGE; @@ -99,13 +104,10 @@ static void ast_expression_init(ast_expression *self, static void ast_expression_delete(ast_expression *self) { - size_t i; if (self->next) ast_delete(self->next); - for (i = 0; i < vec_size(self->params); ++i) { - ast_delete(self->params[i]); - } - vec_free(self->params); + for (auto &it : self->type_params) + ast_delete(it); if (self->varparam) ast_delete(self->varparam); } @@ -118,83 +120,78 @@ static void ast_expression_delete_full(ast_expression *self) ast_value* ast_value_copy(const ast_value *self) { - size_t i; - const ast_expression *fromex; - ast_expression *selfex; - ast_value *cp = ast_value_new(self->expression.node.context, self->name, self->expression.vtype); - if (self->expression.next) { - cp->expression.next = ast_type_copy(self->expression.node.context, self->expression.next); - } - fromex = &self->expression; - selfex = &cp->expression; - selfex->count = fromex->count; - selfex->flags = fromex->flags; - for (i = 0; i < vec_size(fromex->params); ++i) { - ast_value *v = ast_value_copy(fromex->params[i]); - vec_push(selfex->params, v); + ast_value *cp = ast_value_new(self->context, self->name, self->vtype); + if (self->next) { + cp->next = ast_type_copy(self->context, self->next); + } + const ast_expression *fromex = self; + ast_expression *selfex = cp; + selfex->count = fromex->count; + selfex->flags = fromex->flags; + for (auto &it : fromex->type_params) { + ast_value *v = ast_value_copy(it); + selfex->type_params.push_back(v); } return cp; } void ast_type_adopt_impl(ast_expression *self, const ast_expression *other) { - size_t i; const ast_expression *fromex; - ast_expression *selfex; + ast_expression *selfex; self->vtype = other->vtype; if (other->next) { self->next = (ast_expression*)ast_type_copy(ast_ctx(self), other->next); } fromex = other; selfex = self; - selfex->count = fromex->count; - selfex->flags = fromex->flags; - for (i = 0; i < vec_size(fromex->params); ++i) { - ast_value *v = ast_value_copy(fromex->params[i]); - vec_push(selfex->params, v); + selfex->count = fromex->count; + selfex->flags = fromex->flags; + for (auto &it : fromex->type_params) { + ast_value *v = ast_value_copy(it); + 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, NULL); - self->codegen = NULL; - self->next = NULL; + ast_expression_init(self, nullptr); + self->codegen = nullptr; + self->next = nullptr; self->vtype = vtype; return self; } ast_expression* ast_type_copy(lex_ctx_t ctx, const ast_expression *ex) { - size_t i; const ast_expression *fromex; ast_expression *selfex; if (!ex) - return NULL; + return nullptr; else { ast_instantiate(ast_expression, ctx, ast_expression_delete_full); - ast_expression_init(self, NULL); + ast_expression_init(self, nullptr); fromex = ex; selfex = self; /* This may never be codegen()d */ - selfex->codegen = NULL; + selfex->codegen = nullptr; selfex->vtype = fromex->vtype; if (fromex->next) selfex->next = ast_type_copy(ctx, fromex->next); else - selfex->next = NULL; + selfex->next = nullptr; - selfex->count = fromex->count; - selfex->flags = fromex->flags; - for (i = 0; i < vec_size(fromex->params); ++i) { - ast_value *v = ast_value_copy(fromex->params[i]); - vec_push(selfex->params, v); + selfex->count = fromex->count; + selfex->flags = fromex->flags; + for (auto &it : fromex->type_params) { + ast_value *v = ast_value_copy(it); + selfex->type_params.push_back(v); } return self; @@ -210,18 +207,18 @@ bool ast_compare_type(ast_expression *a, ast_expression *b) return false; if (!a->next != !b->next) return false; - if (vec_size(a->params) != vec_size(b->params)) + 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 (vec_size(a->params)) { + if (a->type_params.size()) { size_t i; - for (i = 0; i < vec_size(a->params); ++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; } } @@ -270,19 +267,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 (!vec_size(e->params)) { + 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 < vec_size(e->params); ++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; @@ -323,16 +320,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.node.keep = true; /* keep */ + self->keep_node = true; /* keep */ - self->name = name ? util_strdup(name) : NULL; - self->expression.vtype = t; - self->expression.next = NULL; + self->name = name ? util_strdup(name) : nullptr; + self->vtype = t; + self->next = nullptr; self->isfield = false; self->cvq = CV_NONE; self->hasvalue = false; @@ -340,17 +337,16 @@ ast_value* ast_value_new(lex_ctx_t ctx, const char *name, int t) self->inexact = false; self->uses = 0; memset(&self->constval, 0, sizeof(self->constval)); - self->initlist = NULL; - self->ir_v = NULL; - self->ir_values = NULL; + self->ir_v = nullptr; + self->ir_values = nullptr; self->ir_value_count = 0; - self->setter = NULL; - self->getter = NULL; - self->desc = NULL; + self->setter = nullptr; + self->getter = nullptr; + self->desc = nullptr; - self->argcounter = NULL; + self->argcounter = nullptr; self->intrinsic = false; return self; @@ -363,14 +359,14 @@ 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); break; case TYPE_FUNCTION: /* unlink us from the function node */ - self->constval.vfunc->vtype = NULL; + self->constval.vfunc->function_type = nullptr; break; /* NOTE: delete function? currently collected in * the parser structure @@ -385,27 +381,21 @@ void ast_value_delete(ast_value* self) if (self->desc) mem_d(self->desc); - if (self->initlist) { - if (self->expression.next->vtype == TYPE_STRING) { - /* strings are allocated, free them */ - size_t i, len = vec_size(self->initlist); - /* in theory, len should be expression.count - * but let's not take any chances */ - for (i = 0; i < len; ++i) { - if (self->initlist[i].vstring) - mem_d(self->initlist[i].vstring); - } - } - vec_free(self->initlist); + // initlist imples an array which implies .next in the expression exists. + if (self->initlist.size() && self->next->vtype == TYPE_STRING) { + for (auto &it : self->initlist) + if (it.vstring) + mem_d(it.vstring); } ast_expression_delete((ast_expression*)self); + self->~ast_value(); mem_d(self); } void ast_value_params_add(ast_value *self, ast_value *p) { - vec_push(self->expression.params, p); + self->type_params.push_back(p); } bool ast_value_set_name(ast_value *self, const char *name) @@ -449,21 +439,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; @@ -477,6 +467,7 @@ void ast_binary_delete(ast_binary *self) if (self->refs & AST_REF_RIGHT) ast_unref(self->right); ast_expression_delete((ast_expression*)self); + self->~ast_binary(); mem_d(self); } @@ -505,6 +496,7 @@ void ast_binstore_delete(ast_binstore *self) ast_unref(self->dest); ast_unref(self->source); ast_expression_delete((ast_expression*)self); + self->~ast_binstore(); mem_d(self); } @@ -536,9 +528,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]); } @@ -550,6 +542,7 @@ void ast_unary_delete(ast_unary *self) { if (self->operand) ast_unref(self->operand); ast_expression_delete((ast_expression*)self); + self->~ast_unary(); mem_d(self); } @@ -571,6 +564,7 @@ void ast_return_delete(ast_return *self) if (self->operand) ast_unref(self->operand); ast_expression_delete((ast_expression*)self); + self->~ast_return(); mem_d(self); } @@ -578,7 +572,7 @@ ast_entfield* ast_entfield_new(lex_ctx_t ctx, ast_expression *entity, ast_expres { if (field->vtype != TYPE_FIELD) { compile_error(ctx, "ast_entfield_new with expression not of type field"); - return NULL; + return nullptr; } return ast_entfield_new_force(ctx, entity, field, field->next); } @@ -590,7 +584,7 @@ ast_entfield* ast_entfield_new_force(lex_ctx_t ctx, ast_expression *entity, ast_ if (!outtype) { mem_d(self); /* Error: field has no type... */ - return NULL; + return nullptr; } ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_entfield_codegen); @@ -609,6 +603,7 @@ void ast_entfield_delete(ast_entfield *self) ast_unref(self->entity); ast_unref(self->field); ast_expression_delete((ast_expression*)self); + self->~ast_entfield(); mem_d(self); } @@ -617,25 +612,25 @@ ast_member* ast_member_new(lex_ctx_t ctx, ast_expression *owner, unsigned int fi ast_instantiate(ast_member, ctx, ast_member_delete); if (field >= 3) { mem_d(self); - return NULL; + return nullptr; } if (owner->vtype != TYPE_VECTOR && owner->vtype != TYPE_FIELD) { compile_error(ctx, "member-access on an invalid owner of type %s", type_name[owner->vtype]); mem_d(self); - return NULL; + return nullptr; } ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_member_codegen); - self->expression.node.keep = true; /* keep */ + self->keep_node = true; /* keep */ if (owner->vtype == TYPE_VECTOR) { - self->expression.vtype = TYPE_FLOAT; - self->expression.next = NULL; + 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; @@ -646,14 +641,14 @@ ast_member* ast_member_new(lex_ctx_t ctx, ast_expression *owner, unsigned int fi if (name) self->name = util_strdup(name); else - self->name = NULL; + self->name = nullptr; return self; } void ast_member_delete(ast_member *self) { - /* The owner is always an ast_value, which has .keep=true, + /* The owner is always an ast_value, which has .keep_node=true, * also: ast_members are usually deleted after the owner, thus * this will cause invalid access ast_unref(self->owner); @@ -663,6 +658,7 @@ void ast_member_delete(ast_member *self) */ ast_expression_delete((ast_expression*)self); mem_d(self->name); + self->~ast_member(); mem_d(self); } @@ -683,7 +679,7 @@ ast_array_index* ast_array_index_new(lex_ctx_t ctx, ast_expression *array, ast_e if (!outtype) { mem_d(self); /* Error: field has no type... */ - return NULL; + return nullptr; } ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_array_index_codegen); @@ -695,13 +691,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 NULL; + return nullptr; } self->array = outtype; - self->expression.vtype = TYPE_FIELD; + self->vtype = TYPE_FIELD; } return self; @@ -722,7 +718,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; } @@ -731,6 +727,7 @@ void ast_argpipe_delete(ast_argpipe *self) if (self->index) ast_unref(self->index); ast_expression_delete((ast_expression*)self); + self->~ast_argpipe(); mem_d(self); } @@ -740,7 +737,7 @@ ast_ifthen* ast_ifthen_new(lex_ctx_t ctx, ast_expression *cond, ast_expression * if (!ontrue && !onfalse) { /* because it is invalid */ mem_d(self); - return NULL; + return nullptr; } ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_ifthen_codegen); @@ -764,6 +761,7 @@ void ast_ifthen_delete(ast_ifthen *self) if (self->on_false) ast_unref(self->on_false); ast_expression_delete((ast_expression*)self); + self->~ast_ifthen(); mem_d(self); } @@ -771,10 +769,10 @@ ast_ternary* ast_ternary_new(lex_ctx_t ctx, ast_expression *cond, ast_expression { ast_expression *exprtype = ontrue; ast_instantiate(ast_ternary, ctx, ast_ternary_delete); - /* This time NEITHER must be NULL */ + /* This time NEITHER must be nullptr */ if (!ontrue || !onfalse) { mem_d(self); - return NULL; + return nullptr; } ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_ternary_codegen); @@ -795,12 +793,13 @@ ast_ternary* ast_ternary_new(lex_ctx_t ctx, ast_expression *cond, ast_expression void ast_ternary_delete(ast_ternary *self) { /* the if()s are only there because computed-gotos can set them - * to NULL + * to nullptr */ if (self->cond) ast_unref(self->cond); if (self->on_true) ast_unref(self->on_true); if (self->on_false) ast_unref(self->on_false); ast_expression_delete((ast_expression*)self); + self->~ast_ternary(); mem_d(self); } @@ -850,6 +849,7 @@ void ast_loop_delete(ast_loop *self) if (self->body) ast_unref(self->body); ast_expression_delete((ast_expression*)self); + self->~ast_loop(); mem_d(self); } @@ -867,6 +867,7 @@ ast_breakcont* ast_breakcont_new(lex_ctx_t ctx, bool iscont, unsigned int levels void ast_breakcont_delete(ast_breakcont *self) { ast_expression_delete((ast_expression*)self); + self->~ast_breakcont(); mem_d(self); } @@ -876,7 +877,6 @@ ast_switch* ast_switch_new(lex_ctx_t ctx, ast_expression *op) ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_switch_codegen); self->operand = op; - self->cases = NULL; ast_propagate_effects(self, op); @@ -885,17 +885,16 @@ ast_switch* ast_switch_new(lex_ctx_t ctx, ast_expression *op) void ast_switch_delete(ast_switch *self) { - size_t i; ast_unref(self->operand); - for (i = 0; i < vec_size(self->cases); ++i) { - if (self->cases[i].value) - ast_unref(self->cases[i].value); - ast_unref(self->cases[i].code); + for (auto &it : self->cases) { + if (it.value) + ast_unref(it.value); + ast_unref(it.code); } - vec_free(self->cases); ast_expression_delete((ast_expression*)self); + self->~ast_switch(); mem_d(self); } @@ -904,11 +903,10 @@ 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 = NULL; - self->gotos = NULL; + self->irblock = nullptr; self->undefined = undefined; return self; @@ -917,14 +915,14 @@ ast_label* ast_label_new(lex_ctx_t ctx, const char *name, bool undefined) void ast_label_delete(ast_label *self) { mem_d((void*)self->name); - vec_free(self->gotos); ast_expression_delete((ast_expression*)self); + self->~ast_label(); mem_d(self); } static void ast_label_register_goto(ast_label *self, ast_goto *g) { - vec_push(self->gotos, g); + self->gotos.push_back(g); } ast_goto* ast_goto_new(lex_ctx_t ctx, const char *name) @@ -933,8 +931,8 @@ ast_goto* ast_goto_new(lex_ctx_t ctx, const char *name) ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_goto_codegen); self->name = util_strdup(name); - self->target = NULL; - self->irblock_from = NULL; + self->target = nullptr; + self->irblock_from = nullptr; return self; } @@ -943,6 +941,7 @@ void ast_goto_delete(ast_goto *self) { mem_d((void*)self->name); ast_expression_delete((ast_expression*)self); + self->~ast_goto(); mem_d(self); } @@ -968,6 +967,7 @@ void ast_state_delete(ast_state *self) ast_unref(self->nextthink); ast_expression_delete((ast_expression*)self); + self->~ast_state(); mem_d(self); } @@ -978,15 +978,14 @@ ast_call* ast_call_new(lex_ctx_t ctx, if (!funcexpr->next) { compile_error(ctx, "not a function"); mem_d(self); - return NULL; + return nullptr; } ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_call_codegen); ast_side_effects(self) = true; - self->params = NULL; self->func = funcexpr; - self->va_count = NULL; + self->va_count = nullptr; ast_type_adopt(self, funcexpr->next); @@ -995,10 +994,8 @@ ast_call* ast_call_new(lex_ctx_t ctx, void ast_call_delete(ast_call *self) { - size_t i; - for (i = 0; i < vec_size(self->params); ++i) - ast_unref(self->params[i]); - vec_free(self->params); + for (auto &it : self->params) + ast_unref(it); if (self->func) ast_unref(self->func); @@ -1007,6 +1004,7 @@ void ast_call_delete(ast_call *self) ast_unref(self->va_count); ast_expression_delete((ast_expression*)self); + self->~ast_call(); mem_d(self); } @@ -1058,11 +1056,11 @@ bool ast_call_check_types(ast_call *self, ast_expression *va_type) char texp[1024]; char tgot[1024]; size_t i; - bool retval = true; - const ast_expression *func = self->func; - size_t count = vec_size(self->params); - if (count > vec_size(func->params)) - count = vec_size(func->params); + bool retval = true; + const ast_expression *func = self->func; + size_t count = self->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)) { @@ -1071,21 +1069,21 @@ 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 */ retval = false; } } - count = vec_size(self->params); - if (count > vec_size(func->params) && func->varparam) { + count = self->params.size(); + 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 */ @@ -1132,6 +1130,7 @@ void ast_store_delete(ast_store *self) ast_unref(self->dest); ast_unref(self->source); ast_expression_delete((ast_expression*)self); + self->~ast_store(); mem_d(self); } @@ -1140,21 +1139,16 @@ ast_block* ast_block_new(lex_ctx_t ctx) ast_instantiate(ast_block, ctx, ast_block_delete); ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_block_codegen); - - self->locals = NULL; - self->exprs = NULL; - self->collect = NULL; - return self; } bool ast_block_add_expr(ast_block *self, ast_expression *e) { ast_propagate_effects(self, e); - vec_push(self->exprs, e); - if (self->expression.next) { - ast_delete(self->expression.next); - self->expression.next = NULL; + self->exprs.push_back(e); + if (self->next) { + ast_delete(self->next); + self->next = nullptr; } ast_type_adopt(self, e); return true; @@ -1162,30 +1156,24 @@ bool ast_block_add_expr(ast_block *self, ast_expression *e) void ast_block_collect(ast_block *self, ast_expression *expr) { - vec_push(self->collect, expr); - expr->node.keep = true; + self->collect.push_back(expr); + expr->keep_node = true; } void ast_block_delete(ast_block *self) { - size_t i; - for (i = 0; i < vec_size(self->exprs); ++i) - ast_unref(self->exprs[i]); - vec_free(self->exprs); - for (i = 0; i < vec_size(self->locals); ++i) - ast_delete(self->locals[i]); - vec_free(self->locals); - for (i = 0; i < vec_size(self->collect); ++i) - ast_delete(self->collect[i]); - vec_free(self->collect); + for (auto &it : self->exprs) ast_unref(it); + for (auto &it : self->locals) ast_delete(it); + for (auto &it : self->collect) ast_delete(it); ast_expression_delete((ast_expression*)self); + self->~ast_block(); mem_d(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); } @@ -1196,67 +1184,57 @@ 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; } - self->vtype = vtype; - self->name = name ? util_strdup(name) : NULL; - self->blocks = NULL; + self->function_type = vtype; + self->name = name ? util_strdup(name) : nullptr; self->labelcount = 0; self->builtin = 0; - self->ir_func = NULL; - self->curblock = NULL; - - self->breakblocks = NULL; - self->continueblocks = NULL; + self->ir_func = nullptr; + self->curblock = nullptr; vtype->hasvalue = true; vtype->constval.vfunc = self; - self->varargs = NULL; - self->argc = NULL; - self->fixedparams = NULL; - self->return_value = NULL; - - self->static_names = NULL; + self->varargs = nullptr; + self->argc = nullptr; + self->fixedparams = nullptr; + self->return_value = nullptr; self->static_count = 0; return self; cleanup: mem_d(self); - return NULL; + return nullptr; } void ast_function_delete(ast_function *self) { - size_t i; if (self->name) mem_d((void*)self->name); - if (self->vtype) { - /* ast_value_delete(self->vtype); */ - self->vtype->hasvalue = false; - self->vtype->constval.vfunc = NULL; + if (self->function_type) { + /* ast_value_delete(self->function_type); */ + self->function_type->hasvalue = false; + self->function_type->constval.vfunc = nullptr; /* We use unref - if it was stored in a global table it is supposed * to be deleted from *there* */ - ast_unref(self->vtype); - } - for (i = 0; i < vec_size(self->static_names); ++i) - mem_d(self->static_names[i]); - vec_free(self->static_names); - for (i = 0; i < vec_size(self->blocks); ++i) - ast_delete(self->blocks[i]); - vec_free(self->blocks); - vec_free(self->breakblocks); - vec_free(self->continueblocks); + ast_unref(self->function_type); + } + for (auto &it : self->static_names) + mem_d(it); + // FIXME::DELME:: unique_ptr used on ast_block + //for (auto &it : self->blocks) + // ast_delete(it); if (self->varargs) ast_delete(self->varargs); if (self->argc) @@ -1265,6 +1243,7 @@ void ast_function_delete(ast_function *self) ast_unref(self->fixedparams); if (self->return_value) ast_unref(self->return_value); + self->~ast_function(); mem_d(self); } @@ -1278,7 +1257,7 @@ const char* ast_function_label(ast_function *self, const char *prefix) !OPTS_OPTION_BOOL(OPTION_DUMPFIN) && !OPTS_OPTION_BOOL(OPTION_DEBUG)) { - return NULL; + return nullptr; } id = (self->labelcount++); @@ -1297,7 +1276,7 @@ const char* ast_function_label(ast_function *self, const char *prefix) /*********************************************************************/ /* AST codegen part - * by convention you must never pass NULL to the 'ir_value **out' + * by convention you must never pass nullptr to the 'ir_value **out' * parameter. If you really don't care about the output, pass a dummy. * But I can't imagine a pituation where the output is truly unnecessary. */ @@ -1310,17 +1289,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, @@ -1339,21 +1318,21 @@ bool ast_value_codegen(ast_value *self, ast_function *func, bool lvalue, ir_valu static bool ast_global_array_set(ast_value *self) { - size_t count = vec_size(self->initlist); + 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; @@ -1387,7 +1366,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; } } @@ -1396,13 +1375,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) { + 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; @@ -1410,16 +1389,16 @@ static bool check_array(ast_value *self, ast_value *array) bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield) { - ir_value *v = NULL; + 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); @@ -1427,18 +1406,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"); @@ -1451,7 +1430,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)) { @@ -1462,7 +1441,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); @@ -1475,18 +1454,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]) { @@ -1497,36 +1476,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; } @@ -1544,18 +1523,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]) { @@ -1566,7 +1545,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); @@ -1576,7 +1555,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; @@ -1589,14 +1568,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)) @@ -1632,27 +1611,27 @@ 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; } static bool ast_local_codegen(ast_value *self, ir_function *func, bool param) { - ir_value *v = NULL; + 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. @@ -1660,17 +1639,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; } @@ -1679,7 +1658,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; @@ -1699,7 +1678,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]) { @@ -1714,7 +1693,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); @@ -1725,7 +1704,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)) @@ -1740,7 +1719,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; } } @@ -1754,7 +1733,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; } @@ -1764,7 +1743,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; @@ -1773,7 +1752,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; } @@ -1800,9 +1779,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; } @@ -1814,8 +1792,6 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir) ast_expression *ec; ast_expression_codegen *cgen; - size_t i; - (void)ir; irf = self->ir_func; @@ -1825,15 +1801,14 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir) } /* fill the parameter list */ - ec = &self->vtype->expression; - for (i = 0; i < vec_size(ec->params); ++i) - { - if (ec->params[i]->expression.vtype == TYPE_FIELD) - vec_push(irf->params, ec->params[i]->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, ec->params[i]->expression.vtype); + vec_push(irf->params, it->vtype); if (!self->builtin) { - if (!ast_local_codegen(ec->params[i], self->ir_func, true)) + if (!ast_local_codegen(it, self->ir_func, true)) return false; } } @@ -1841,7 +1816,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) { @@ -1855,7 +1830,7 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir) return false; } - if (!vec_size(self->blocks)) { + if (self->blocks.empty()) { compile_error(ast_ctx(self), "function `%s` has no body", self->name); return false; } @@ -1872,10 +1847,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), @@ -1890,35 +1865,35 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir) } } - for (i = 0; i < vec_size(self->blocks); ++i) { - cgen = self->blocks[i]->expression.codegen; - if (!(*cgen)((ast_expression*)self->blocks[i], self, false, &dummy)) + for (auto &it : self->blocks) { + cgen = it->codegen; + if (!(*cgen)(it.get(), self, false, &dummy)) return false; } /* TODO: check return types */ if (!self->curblock->final) { - if (!self->vtype->expression.next || - self->vtype->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), NULL); + 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; } - return ir_block_create_return(self->curblock, ast_ctx(self), NULL); + return ir_block_create_return(self->curblock, ast_ctx(self), nullptr); } } return true; @@ -1943,8 +1918,6 @@ static bool starts_a_label(ast_expression *ex) */ bool ast_block_codegen(ast_block *self, ast_function *func, bool lvalue, ir_value **out) { - size_t i; - /* We don't use this * Note: an ast-representation using the comma-operator * of the form: (a, b, c) = x should not assign to c... @@ -1954,43 +1927,41 @@ 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; } - /* output is NULL at first, we'll have each expression + /* output is nullptr at first, we'll have each expression * assign to out output, thus, a comma-operator represention * using an ast_block will return the last generated value, * so: (b, c) + a executed both b and c, and returns c, * which is then added to a. */ - *out = NULL; + *out = nullptr; /* generate locals */ - for (i = 0; i < vec_size(self->locals); ++i) - { - if (!ast_local_codegen(self->locals[i], func->ir_func, false)) { + for (auto &it : self->locals) { + if (!ast_local_codegen(it, func->ir_func, false)) { if (OPTS_OPTION_BOOL(OPTION_DEBUG)) - compile_error(ast_ctx(self), "failed to generate local `%s`", self->locals[i]->name); + compile_error(ast_ctx(self), "failed to generate local `%s`", it->name); return false; } } - for (i = 0; i < vec_size(self->exprs); ++i) - { + for (auto &it : self->exprs) { ast_expression_codegen *gen; - if (func->curblock->final && !starts_a_label(self->exprs[i])) { - if (compile_warning(ast_ctx(self->exprs[i]), WARN_UNREACHABLE_CODE, "unreachable statement")) + if (func->curblock->final && !starts_a_label(it)) { + if (compile_warning(ast_ctx(it), WARN_UNREACHABLE_CODE, "unreachable statement")) return false; continue; } - gen = self->exprs[i]->codegen; - if (!(*gen)(self->exprs[i], func, false, out)) + gen = it->codegen; + if (!(*gen)(it, func, false, out)) return false; } - self->expression.outr = *out; + self->outr = *out; return true; } @@ -1998,20 +1969,20 @@ bool ast_block_codegen(ast_block *self, ast_function *func, bool lvalue, ir_valu bool ast_store_codegen(ast_store *self, ast_function *func, bool lvalue, ir_value **out) { ast_expression_codegen *cgen; - ir_value *left = NULL; - ir_value *right = NULL; + ir_value *left = nullptr; + ir_value *right = nullptr; ast_value *arr; ast_value *idx = 0; - ast_array_index *ai = NULL; + 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; } @@ -2022,7 +1993,7 @@ bool ast_store_codegen(ast_store *self, ast_function *func, bool lvalue, ir_valu idx = (ast_value*)ai->index; if (ast_istype(ai->index, ast_value) && idx->hasvalue && idx->cvq == CV_CONST) - ai = NULL; + ai = nullptr; } if (ai) { @@ -2041,11 +2012,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; @@ -2058,7 +2029,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 { @@ -2068,7 +2039,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! */ @@ -2077,7 +2048,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 @@ -2103,8 +2074,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; } @@ -2120,7 +2091,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 */ @@ -2157,13 +2128,17 @@ 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); + algo::shiftback(func->ir_func->blocks.begin() + merge_id, + func->ir_func->blocks.end()); + // FIXME::DELME:: + //func->ir_func->blocks[merge_id].release(); + //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); @@ -2205,7 +2180,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; } @@ -2230,7 +2205,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; @@ -2239,20 +2214,20 @@ bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_va bool ast_binstore_codegen(ast_binstore *self, ast_function *func, bool lvalue, ir_value **out) { ast_expression_codegen *cgen; - ir_value *leftl = NULL, *leftr, *right, *bin; + ir_value *leftl = nullptr, *leftr, *right, *bin; ast_value *arr; ast_value *idx = 0; - ast_array_index *ai = NULL; - ir_value *iridx = NULL; + 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; } @@ -2263,13 +2238,13 @@ bool ast_binstore_codegen(ast_binstore *self, ast_function *func, bool lvalue, i idx = (ast_value*)ai->index; if (ast_istype(ai->index, ast_value) && idx->hasvalue && idx->cvq == CV_CONST) - ai = NULL; + ai = nullptr; } /* 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; } @@ -2285,8 +2260,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 */ @@ -2304,7 +2278,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; @@ -2313,18 +2287,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 @@ -2350,8 +2324,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; } @@ -2364,7 +2338,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; } @@ -2374,7 +2348,7 @@ bool ast_return_codegen(ast_return *self, ast_function *func, bool lvalue, ir_va ast_expression_codegen *cgen; ir_value *operand; - *out = NULL; + *out = nullptr; /* In the context of a return operation, we don't actually return * anything... @@ -2384,11 +2358,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; @@ -2399,7 +2373,7 @@ bool ast_return_codegen(ast_return *self, ast_function *func, bool lvalue, ir_va if (!ir_block_create_return(func->curblock, ast_ctx(self), operand)) return false; } else { - if (!ir_block_create_return(func->curblock, ast_ctx(self), NULL)) + if (!ir_block_create_return(func->curblock, ast_ctx(self), nullptr)) return false; } @@ -2416,13 +2390,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; } @@ -2440,7 +2414,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); */ @@ -2448,16 +2422,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; @@ -2473,8 +2447,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; } @@ -2489,9 +2463,9 @@ 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 != NULL); + return (*out != nullptr); } bool ast_array_index_codegen(ast_array_index *self, ast_function *func, bool lvalue, ir_value **out) @@ -2499,12 +2473,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; } @@ -2541,7 +2515,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; @@ -2551,13 +2525,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) { @@ -2566,7 +2540,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) { @@ -2579,14 +2553,14 @@ 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; } bool ast_argpipe_codegen(ast_argpipe *self, ast_function *func, bool lvalue, ir_value **out) { - *out = NULL; + *out = nullptr; if (lvalue) { compile_error(ast_ctx(self), "argpipe node: not an lvalue"); return false; @@ -2607,20 +2581,20 @@ bool ast_ifthen_codegen(ast_ifthen *self, ast_function *func, bool lvalue, ir_va ir_block *cond; ir_block *ontrue; ir_block *onfalse; - ir_block *ontrue_endblock = NULL; - ir_block *onfalse_endblock = NULL; - ir_block *merge = NULL; - int fold = 0; + ir_block *ontrue_endblock = nullptr; + ir_block *onfalse_endblock = nullptr; + ir_block *merge = nullptr; + int folded = 0; /* We don't output any value, thus also don't care about r/lvalue */ (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; @@ -2630,8 +2604,8 @@ bool ast_ifthen_codegen(ast_ifthen *self, ast_function *func, bool lvalue, ir_va cond = func->curblock; /* try constant folding away the condition */ - if ((fold = fold_cond_ifthen(condval, func, self)) != -1) - return fold; + if ((folded = fold::cond_ifthen(condval, func, self)) != -1) + return folded; if (self->on_true) { /* create on-true block */ @@ -2650,7 +2624,7 @@ bool ast_ifthen_codegen(ast_ifthen *self, ast_function *func, bool lvalue, ir_va /* we now need to work from the current endpoint */ ontrue_endblock = func->curblock; } else - ontrue = NULL; + ontrue = nullptr; /* on-false path */ if (self->on_false) { @@ -2670,7 +2644,7 @@ bool ast_ifthen_codegen(ast_ifthen *self, ast_function *func, bool lvalue, ir_va /* we now need to work from the current endpoint */ onfalse_endblock = func->curblock; } else - onfalse = NULL; + onfalse = nullptr; /* Merge block were they all merge in to */ if (!ontrue || !onfalse || !ontrue_endblock->final || !onfalse_endblock->final) @@ -2709,11 +2683,11 @@ bool ast_ternary_codegen(ast_ternary *self, ast_function *func, bool lvalue, ir_ ir_instr *phi; ir_block *cond = func->curblock; - ir_block *cond_out = NULL; - ir_block *ontrue, *ontrue_out = NULL; - ir_block *onfalse, *onfalse_out = NULL; + ir_block *cond_out = nullptr; + ir_block *ontrue, *ontrue_out = nullptr; + ir_block *onfalse, *onfalse_out = nullptr; ir_block *merge; - int fold = 0; + int folded = 0; /* Ternary can never create an lvalue... */ if (lvalue) @@ -2724,8 +2698,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; } @@ -2739,8 +2713,8 @@ bool ast_ternary_codegen(ast_ternary *self, ast_function *func, bool lvalue, ir_ cond_out = func->curblock; /* try constant folding away the condition */ - if ((fold = fold_cond_ternary(condval, func, self)) != -1) - return fold; + if ((folded = fold::cond_ternary(condval, func, self)) != -1) + return folded; /* create on-true block */ ontrue = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "tern_T")); @@ -2803,7 +2777,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; @@ -2811,8 +2785,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); @@ -2823,37 +2797,37 @@ bool ast_loop_codegen(ast_loop *self, ast_function *func, bool lvalue, ir_value { ast_expression_codegen *cgen; - ir_value *dummy = NULL; - ir_value *precond = NULL; - ir_value *postcond = NULL; + ir_value *dummy = nullptr; + ir_value *precond = nullptr; + ir_value *postcond = nullptr; /* Since we insert some jumps "late" so we have blocks * ordered "nicely", we need to keep track of the actual end-blocks * of expressions to add the jumps to. */ - ir_block *bbody = NULL, *end_bbody = NULL; - ir_block *bprecond = NULL, *end_bprecond = NULL; - ir_block *bpostcond = NULL, *end_bpostcond = NULL; - ir_block *bincrement = NULL, *end_bincrement = NULL; - ir_block *bout = NULL, *bin = NULL; + ir_block *bbody = nullptr, *end_bbody = nullptr; + ir_block *bprecond = nullptr, *end_bprecond = nullptr; + ir_block *bpostcond = nullptr, *end_bpostcond = nullptr; + ir_block *bincrement = nullptr, *end_bincrement = nullptr; + ir_block *bout = nullptr, *bin = nullptr; /* let's at least move the outgoing block to the end */ size_t bout_id; /* 'break' and 'continue' need to be able to find the right blocks */ - ir_block *bcontinue = NULL; - ir_block *bbreak = NULL; + ir_block *bcontinue = nullptr; + ir_block *bbreak = nullptr; - ir_block *tmpblock = NULL; + ir_block *tmpblock = nullptr; (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 @@ -2896,7 +2870,7 @@ bool ast_loop_codegen(ast_loop *self, ast_function *func, bool lvalue, ir_value end_bprecond = func->curblock; } else { - bprecond = end_bprecond = NULL; + bprecond = end_bprecond = nullptr; } /* Now the next blocks won't be ordered nicely, but we need to @@ -2908,7 +2882,7 @@ bool ast_loop_codegen(ast_loop *self, ast_function *func, bool lvalue, ir_value return false; bcontinue = bincrement; /* increment comes before the pre-loop-condition */ } else { - bincrement = end_bincrement = NULL; + bincrement = end_bincrement = nullptr; } if (self->postcond) { @@ -2917,10 +2891,10 @@ bool ast_loop_codegen(ast_loop *self, ast_function *func, bool lvalue, ir_value return false; bcontinue = bpostcond; /* postcond comes before the increment */ } else { - bpostcond = end_bpostcond = NULL; + 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; @@ -2936,11 +2910,11 @@ bool ast_loop_codegen(ast_loop *self, ast_function *func, bool lvalue, ir_value /* enter */ func->curblock = bbody; - vec_push(func->breakblocks, bbreak); + func->breakblocks.push_back(bbreak); if (bcontinue) - vec_push(func->continueblocks, bcontinue); + func->continueblocks.push_back(bcontinue); else - vec_push(func->continueblocks, bbody); + func->continueblocks.push_back(bbody); /* generate */ if (self->body) { @@ -2950,8 +2924,8 @@ bool ast_loop_codegen(ast_loop *self, ast_function *func, bool lvalue, ir_value } end_bbody = func->curblock; - vec_pop(func->breakblocks); - vec_pop(func->continueblocks); + func->breakblocks.pop_back(); + func->continueblocks.pop_back(); } /* post-loop-condition */ @@ -3064,8 +3038,12 @@ 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); + algo::shiftback(func->ir_func->blocks.begin() + bout_id, + func->ir_func->blocks.end()); + // FIXME::DELME:: + //func->ir_func->blocks[bout_id].release(); // it's a vector> + //func->ir_func->blocks.erase(func->ir_func->blocks.begin() + bout_id); + //func->ir_func->blocks.emplace_back(bout); return true; } @@ -3074,23 +3052,23 @@ bool ast_breakcont_codegen(ast_breakcont *self, ast_function *func, bool lvalue, { ir_block *target; - *out = NULL; + *out = nullptr; if (lvalue) { compile_error(ast_ctx(self), "break/continue expression is not an l-value"); 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[vec_size(func->continueblocks)-1-self->levels]; + target = func->continueblocks[func->continueblocks.size()-1-self->levels]; else - target = func->breakblocks[vec_size(func->breakblocks)-1-self->levels]; + target = func->breakblocks[func->breakblocks.size()-1-self->levels]; if (!target) { compile_error(ast_ctx(self), "%s is lacking a target block", (self->is_continue ? "continue" : "break")); @@ -3106,17 +3084,16 @@ bool ast_switch_codegen(ast_switch *self, ast_function *func, bool lvalue, ir_va { ast_expression_codegen *cgen; - ast_switch_case *def_case = NULL; - ir_block *def_bfall = NULL; - ir_block *def_bfall_to = NULL; + ast_switch_case *def_case = nullptr; + ir_block *def_bfall = nullptr; + ir_block *def_bfall_to = nullptr; bool set_def_bfall_to = false; - ir_value *dummy = NULL; - ir_value *irop = NULL; - ir_block *bout = NULL; - ir_block *bfall = NULL; + ir_value *dummy = nullptr; + ir_value *irop = nullptr; + ir_block *bout = nullptr; + ir_block *bfall = nullptr; size_t bout_id; - size_t c; char typestr[1024]; uint16_t cmpinstr; @@ -3126,11 +3103,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; @@ -3139,7 +3116,7 @@ bool ast_switch_codegen(ast_switch *self, ast_function *func, bool lvalue, ir_va if (!(*cgen)((ast_expression*)(self->operand), func, false, &irop)) return false; - if (!vec_size(self->cases)) + if (self->cases.empty()) return true; cmpinstr = type_eq_instr[irop->vtype]; @@ -3149,21 +3126,21 @@ 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; /* setup the break block */ - vec_push(func->breakblocks, bout); + func->breakblocks.push_back(bout); /* Now create all cases */ - for (c = 0; c < vec_size(self->cases); ++c) { + for (auto &it : self->cases) { ir_value *cond, *val; ir_block *bcase, *bnot; size_t bnot_id; - ast_switch_case *swcase = &self->cases[c]; + ast_switch_case *swcase = ⁢ if (swcase->value) { /* A regular case */ @@ -3177,7 +3154,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; @@ -3205,13 +3182,17 @@ 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); + algo::shiftback(func->ir_func->blocks.begin() + bnot_id, + func->ir_func->blocks.end()); + // FIXME::DELME:: + //func->ir_func->blocks[bnot_id].release(); + //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: */ def_bfall = bfall; - bfall = NULL; + bfall = nullptr; /* remember which case it was */ def_case = swcase; /* And the next case will be remembered */ @@ -3260,18 +3241,21 @@ bool ast_switch_codegen(ast_switch *self, ast_function *func, bool lvalue, ir_va func->curblock = bout; /* restore the break block */ - vec_pop(func->breakblocks); + 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); + algo::shiftback(func->ir_func->blocks.begin() + bout_id, + func->ir_func->blocks.end()); + // FIXME::DELME:: + //func->ir_func->blocks[bout_id].release(); + //func->ir_func->blocks.erase(func->ir_func->blocks.begin() + bout_id); + //func->ir_func->blocks.emplace_back(bout); return true; } bool ast_label_codegen(ast_label *self, ast_function *func, bool lvalue, ir_value **out) { - size_t i; ir_value *dummy; if (self->undefined) { @@ -3279,7 +3263,7 @@ bool ast_label_codegen(ast_label *self, ast_function *func, bool lvalue, ir_valu return false; } - *out = NULL; + *out = nullptr; if (lvalue) { compile_error(ast_ctx(self), "internal error: ast_label cannot be an lvalue"); return false; @@ -3300,8 +3284,8 @@ bool ast_label_codegen(ast_label *self, ast_function *func, bool lvalue, ir_valu func->curblock = self->irblock; /* Generate all the leftover gotos */ - for (i = 0; i < vec_size(self->gotos); ++i) { - if (!ast_goto_codegen(self->gotos[i], func, false, &dummy)) + for (auto &it : self->gotos) { + if (!ast_goto_codegen(it, func, false, &dummy)) return false; } @@ -3310,7 +3294,7 @@ bool ast_label_codegen(ast_label *self, ast_function *func, bool lvalue, ir_valu bool ast_goto_codegen(ast_goto *self, ast_function *func, bool lvalue, ir_value **out) { - *out = NULL; + *out = nullptr; if (lvalue) { compile_error(ast_ctx(self), "internal error: ast_goto cannot be an lvalue"); return false; @@ -3357,11 +3341,11 @@ 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; } - *out = NULL; + *out = nullptr; cgen = self->framenum->codegen; if (!(*cgen)((ast_expression*)(self->framenum), func, false, &frameval)) @@ -3380,18 +3364,17 @@ 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; } bool ast_call_codegen(ast_call *self, ast_function *func, bool lvalue, ir_value **out) { ast_expression_codegen *cgen; - ir_value **params; - ir_instr *callinstr; - size_t i; + std::vector params; + ir_instr *callinstr; - ir_value *funval = NULL; + ir_value *funval = nullptr; /* return values are never lvalues */ if (lvalue) { @@ -3399,8 +3382,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; } @@ -3410,20 +3393,15 @@ bool ast_call_codegen(ast_call *self, ast_function *func, bool lvalue, ir_value if (!funval) return false; - params = NULL; - /* parameters */ - for (i = 0; i < vec_size(self->params); ++i) - { + for (auto &it : self->params) { ir_value *param; - ast_expression *expr = self->params[i]; - - cgen = expr->codegen; - if (!(*cgen)(expr, func, false, ¶m)) - goto error; + cgen = it->codegen; + if (!(*cgen)(it, func, false, ¶m)) + return false; if (!param) - goto error; - vec_push(params, param); + return false; + params.push_back(param); } /* varargs counter */ @@ -3444,20 +3422,15 @@ bool ast_call_codegen(ast_call *self, ast_function *func, bool lvalue, ir_value ast_function_label(func, "call"), funval, !!(self->func->flags & AST_FLAG_NORETURN)); if (!callinstr) - goto error; + return false; - for (i = 0; i < vec_size(params); ++i) { - ir_call_param(callinstr, params[i]); - } + for (auto &it : params) + ir_call_param(callinstr, it); *out = ir_call_value(callinstr); - self->expression.outr = *out; + self->outr = *out; codegen_output_type(self, *out); - vec_free(params); return true; -error: - vec_free(params); - return false; }