X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=parser.cpp;h=9bfd7517a26aea26b9671f362f6e9be58dcdfd50;hp=1e15ba3a658073efeeccb9bc1880d9ab1bd1a132;hb=73d3d7eec1f9bbdf0f5905bf25d5d1f05aaf1995;hpb=047ecd426f4068566a2db97a894d00d98c66f345 diff --git a/parser.cpp b/parser.cpp index 1e15ba3..9bfd751 100644 --- a/parser.cpp +++ b/parser.cpp @@ -135,17 +135,22 @@ static ast_expression* parser_find_local(parser_t *parser, const char *name, siz { size_t i, hash; ast_expression *e; + ast_expression *p; hash = util_hthash(parser->htglobals, name); *isparam = false; + p = parser_find_param(parser, name); + if (p) { + *isparam = true; + return p; + } for (i = parser->variables.size(); i > upto;) { --i; if ( (e = (ast_expression*)util_htgeth(parser->variables[i], name, hash)) ) return e; } - *isparam = true; - return parser_find_param(parser, name); + return NULL; } static ast_expression* parser_find_local(parser_t *parser, const std::string &name, size_t upto, bool *isparam) { @@ -293,6 +298,27 @@ static bool rotate_entfield_array_index_nodes(ast_expression **out) return true; } +static int store_op_for(ast_expression* expr) +{ + if (OPTS_FLAG(ADJUST_VECTOR_FIELDS) && expr->m_vtype == TYPE_FIELD && expr->m_next->m_vtype == TYPE_VECTOR) { + if (ast_istype(expr, ast_entfield)) { + return type_storep_instr[TYPE_VECTOR]; + } else { + return type_store_instr[TYPE_VECTOR]; + } + } + + if (ast_istype(expr, ast_member) && ast_istype(((ast_member*)expr)->m_owner, ast_entfield)) { + return type_storep_instr[expr->m_vtype]; + } + + if (ast_istype(expr, ast_entfield)) { + return type_storep_instr[expr->m_vtype]; + } + + return type_store_instr[expr->m_vtype]; +} + static bool check_write_to(lex_ctx_t ctx, ast_expression *expr) { if (ast_istype(expr, ast_value)) { @@ -321,7 +347,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy) const oper_info *op; lex_ctx_t ctx; ast_expression *out = nullptr; - ast_expression *exprs[3]; + ast_expression *exprs[3] = { 0, 0, 0 }; ast_block *blocks[3]; ast_binstore *asbinstore; size_t i, assignop, addop, subop; @@ -900,14 +926,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy) case opid1('='): if (ast_istype(exprs[0], ast_entfield)) { ast_expression *field = ((ast_entfield*)exprs[0])->m_field; - if (OPTS_FLAG(ADJUST_VECTOR_FIELDS) && - exprs[0]->m_vtype == TYPE_FIELD && - exprs[0]->m_next->m_vtype == TYPE_VECTOR) - { - assignop = type_storep_instr[TYPE_VECTOR]; - } - else - assignop = type_storep_instr[exprs[0]->m_vtype]; + assignop = store_op_for(exprs[0]); if (assignop == VINSTR_END || !field->m_next->compareType(*exprs[1])) { ast_type_to_string(field->m_next, ty1, sizeof(ty1)); @@ -925,15 +944,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy) } else { - if (OPTS_FLAG(ADJUST_VECTOR_FIELDS) && - exprs[0]->m_vtype == TYPE_FIELD && - exprs[0]->m_next->m_vtype == TYPE_VECTOR) - { - assignop = type_store_instr[TYPE_VECTOR]; - } - else { - assignop = type_store_instr[exprs[0]->m_vtype]; - } + assignop = store_op_for(exprs[0]); if (assignop == VINSTR_END) { ast_type_to_string(exprs[0], ty1, sizeof(ty1)); @@ -1028,10 +1039,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy) return false; } (void)check_write_to(ctx, exprs[0]); - if (ast_istype(exprs[0], ast_entfield)) - assignop = type_storep_instr[exprs[0]->m_vtype]; - else - assignop = type_store_instr[exprs[0]->m_vtype]; + assignop = store_op_for(exprs[0]); switch (exprs[0]->m_vtype) { case TYPE_FLOAT: out = new ast_binstore(ctx, assignop, @@ -1063,10 +1071,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy) return false; } (void)check_write_to(ctx, exprs[0]); - if (ast_istype(exprs[0], ast_entfield)) - assignop = type_storep_instr[exprs[0]->m_vtype]; - else - assignop = type_store_instr[exprs[0]->m_vtype]; + assignop = store_op_for(exprs[0]); switch (exprs[0]->m_vtype) { case TYPE_FLOAT: out = new ast_binstore(ctx, assignop, @@ -1107,10 +1112,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy) return false; } (void)check_write_to(ctx, exprs[0]); - if (ast_istype(exprs[0], ast_entfield)) - assignop = type_storep_instr[exprs[0]->m_vtype]; - else - assignop = type_store_instr[exprs[0]->m_vtype]; + assignop = store_op_for(exprs[0]); if (exprs[0]->m_vtype == TYPE_FLOAT) out = new ast_binstore(ctx, assignop, (op->id == opid2('^','=') ? VINSTR_BITXOR : op->id == opid2('&','=') ? INSTR_BITAND : INSTR_BITOR), @@ -1132,10 +1134,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy) ty1, ty2); return false; } - if (ast_istype(exprs[0], ast_entfield)) - assignop = type_storep_instr[exprs[0]->m_vtype]; - else - assignop = type_store_instr[exprs[0]->m_vtype]; + assignop = store_op_for(exprs[0]); if (exprs[0]->m_vtype == TYPE_FLOAT) out = fold::binary(ctx, INSTR_BITAND, exprs[0], exprs[1]); else @@ -3169,6 +3168,7 @@ static bool parse_switch_go(parser_t *parser, ast_block *block, ast_expression * } if (!OPTS_FLAG(RELAXED_SWITCH)) { if (!ast_istype(swcase.m_value, ast_value)) { /* || ((ast_value*)swcase.m_value)->m_cvq != CV_CONST) { */ + delete switchnode; parseerror(parser, "case on non-constant values need to be explicitly enabled via -frelaxed-switch"); ast_unref(operand); return false; @@ -5516,7 +5516,7 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield defname.erase(prefix_len); for (i = 0; i < 3; ++i) { util_htset(parser->variables.back(), me[i]->m_name.c_str(), (void*)(me[i])); - me[i]->m_name = move(defname + me[i]->m_name); + me[i]->m_name = defname + me[i]->m_name; parser->globals.push_back(me[i]); } }