]> git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
*= and /= operators
authorWolfgang (Blub) Bumiller <blub@speed.at>
Fri, 23 Nov 2012 13:24:58 +0000 (14:24 +0100)
committerWolfgang (Blub) Bumiller <blub@speed.at>
Fri, 23 Nov 2012 13:24:58 +0000 (14:24 +0100)
parser.c
tests/operators.qc
tests/operators.tmpl

index 6e150c106d3fcd233eaedf9999d9aa257f5e0096..c8d1c11241c3c70247e0a2bb49e7572a7bc48307 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -971,6 +971,50 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
                     return false;
             };
             break;
+        case opid2('*','='):
+        case opid2('/','='):
+            if (exprs[1]->expression.vtype != TYPE_FLOAT ||
+                !(exprs[0]->expression.vtype == TYPE_FLOAT ||
+                  exprs[0]->expression.vtype == TYPE_VECTOR))
+            {
+                ast_type_to_string(exprs[0], ty1, sizeof(ty1));
+                ast_type_to_string(exprs[1], ty2, sizeof(ty2));
+                parseerror(parser, "invalid types used in expression: %s and %s",
+                           ty1, ty2);
+                return false;
+            }
+            if (ast_istype(exprs[0], ast_entfield))
+                assignop = type_storep_instr[exprs[0]->expression.vtype];
+            else
+                assignop = type_store_instr[exprs[0]->expression.vtype];
+            switch (exprs[0]->expression.vtype) {
+                case TYPE_FLOAT:
+                    out = (ast_expression*)ast_binstore_new(ctx, assignop,
+                                                            (op->id == opid2('*','=') ? INSTR_MUL_F : INSTR_DIV_F),
+                                                            exprs[0], exprs[1]);
+                    break;
+                case TYPE_VECTOR:
+                    if (op->id == opid2('*','=')) {
+                        out = (ast_expression*)ast_binstore_new(ctx, assignop, INSTR_MUL_VF,
+                                                                exprs[0], exprs[1]);
+                    } else {
+                        /* there's no DIV_VF */
+                        out = (ast_expression*)ast_binary_new(ctx, INSTR_DIV_F,
+                                                              (ast_expression*)parser_const_float_1(parser),
+                                                              exprs[1]);
+                        if (!out)
+                            return false;
+                        out = (ast_expression*)ast_binstore_new(ctx, assignop, INSTR_MUL_VF,
+                                                                exprs[0], out);
+                    }
+                    break;
+                default:
+                    parseerror(parser, "invalid types used in expression: cannot add or subtract type %s and %s",
+                               type_name[exprs[0]->expression.vtype],
+                               type_name[exprs[1]->expression.vtype]);
+                    return false;
+            };
+            break;
     }
 #undef NotSameType
 
index 1c23e7aa5dada59fc3ab6494fabbc165a9470f53..e440ec54d77ca1b322ac1abfe6ada7506d193b98 100644 (file)
@@ -1,6 +1,7 @@
-void   print(...)   = #1;
-string ftos (float) = #2;
-entity() spawn = #3;
+void   print(...)    = #1;
+string ftos (float)  = #2;
+string vtos (vector) = #5;
+entity spawn()       = #3;
 
 .float mem;
 
@@ -39,4 +40,15 @@ void main() {
        // postfix on members
        print(ftos(e.mem--), " = ");
        print(ftos(e.mem+1), "\n");
+
+       // compounds in general
+       a = 3;
+       print(ftos(a *= 2), " = 6\n");
+       print(ftos(a /= 2), " = 3\n");
+
+    // compounds on vectors
+       vector v;
+       v = '3 4 5';
+       print(vtos(v *= 2), " = '6 8 10'\n");
+       print(vtos(v /= 2), " = '3 4 5'\n");
 }
index 1e12706468f2baf789ce35f0648cc3c898fb7db9..06426ac1b06c4a37b6945118b99ebc552188389e 100644 (file)
@@ -12,3 +12,7 @@ M: 11 = 11
 M: 4
 M: 2
 M: 12 = 12
+M: 6 = 6
+M: 3 = 3
+M: '6 8 10' = '6 8 10'
+M: '3 4 5' = '3 4 5'