]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - parser.cpp
Make parser_find_local only actually search locals
[xonotic/gmqcc.git] / parser.cpp
index 1e15ba3a658073efeeccb9bc1880d9ab1bd1a132..c795e40a39c9c6dd6e8354b5a76e6d83ea394c0e 100644 (file)
@@ -156,7 +156,7 @@ static ast_expression* parser_find_var(parser_t *parser, const char *name)
 {
     bool dummy;
     ast_expression *v;
-    v         = parser_find_local(parser, name, 0, &dummy);
+    v         = parser_find_local(parser, name, PARSER_HT_LOCALS, &dummy);
     if (!v) v = parser_find_global(parser, name);
     return v;
 }
@@ -293,6 +293,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 +342,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 +921,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 +939,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 +1034,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 +1066,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 +1107,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 +1129,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 +3163,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 +5511,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]);
                         }
                     }