operator &~=
authorWolfgang (Blub) Bumiller <blub@speed.at>
Fri, 23 Nov 2012 13:39:05 +0000 (14:39 +0100)
committerWolfgang (Blub) Bumiller <blub@speed.at>
Fri, 23 Nov 2012 13:39:05 +0000 (14:39 +0100)
lexer.c
lexer.h
parser.c
tests/operators.qc
tests/operators.tmpl

diff --git a/lexer.c b/lexer.c
index c37678ec0d0c7f1baca44e322aeb6563acbb4891..8f1bcb8a46eb3eb5bd823c91267f5bae01765950 100644 (file)
--- a/lexer.c
+++ b/lexer.c
@@ -834,7 +834,7 @@ static int GMQCC_WARN lex_finish_digit(lex_file *lex, int lastch)
 
 int lex_do(lex_file *lex)
 {
-    int ch, nextch;
+    int ch, nextch, thirdch;
 
     lex_token_new(lex);
 #if 0
@@ -1114,6 +1114,16 @@ int lex_do(lex_file *lex)
             lex_tokench(lex, nextch);
         } else if (ch == '-' && nextch == '>') {
             lex_tokench(lex, nextch);
+        } else if (ch == '&' && nextch == '~') {
+            thirdch = lex_getch(lex);
+            if (thirdch != '=') {
+                lex_ungetch(lex, thirdch);
+                lex_ungetch(lex, nextch);
+            }
+            else {
+                lex_tokench(lex, nextch);
+                lex_tokench(lex, thirdch);
+            }
         } else
             lex_ungetch(lex, nextch);
 
diff --git a/lexer.h b/lexer.h
index f2933455723b0075e01ddf43c2c0619abc5ceb9b..2135ec60ee3f53c3c7ec43866f3701d19cf0a946 100644 (file)
--- a/lexer.h
+++ b/lexer.h
@@ -238,6 +238,7 @@ static const oper_info fte_operators[] = {
     { "%=",  2, opid2('%','='),     ASSOC_RIGHT, 8,  0 },
     { "&=",  2, opid2('&','='),     ASSOC_RIGHT, 8,  0 },
     { "|=",  2, opid2('|','='),     ASSOC_RIGHT, 8,  0 },
+    { "&~=", 2, opid3('&','~','='), ASSOC_RIGHT, 8,  0 },
 
     { "&&",  2, opid2('&','&'),     ASSOC_LEFT,  5,  0 },
     { "||",  2, opid2('|','|'),     ASSOC_LEFT,  5,  0 },
index 67d72023fda748f2967f097af249729132947e21..fb13d2b09c5037b9009b38adeb2b26dc70bd852c 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -1032,6 +1032,27 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
                                                     (op->id == opid2('&','=') ? INSTR_BITAND : INSTR_BITOR),
                                                     exprs[0], exprs[1]);
             break;
+        case opid3('&','~','='):
+            /* This is like: a &= ~(b);
+             * But QC has no bitwise-not, so we implement it as
+             * a -= a & (b);
+             */
+            if (NotSameType(TYPE_FLOAT)) {
+                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];
+            out = (ast_expression*)ast_binary_new(ctx, INSTR_BITAND, exprs[0], exprs[1]);
+            if (!out)
+                return false;
+            out = (ast_expression*)ast_binstore_new(ctx, assignop, INSTR_SUB_F, exprs[0], out);
+            break;
     }
 #undef NotSameType
 
index e1464e381c6b2740529c814f89ceb292791e9433..1ca6f67caa0e5cf56ecf2516b82f487af3ba750d 100644 (file)
@@ -56,4 +56,7 @@ void main() {
        a = 1;
        print(ftos(a |= 2), " = 3\n");
        print(ftos(a &= 6), " = 2\n");
+       a = 7;
+
+       print(ftos(a &~= 3), " = 4\n");
 }
index fcf9afd56c810f56b2e0365ba784dbfecdfa6e22..1283ad6fdffbcdf53402d55e9296e120b899f6dd 100644 (file)
@@ -18,3 +18,4 @@ M: '6 8 10' = '6 8 10'
 M: '3 4 5' = '3 4 5'
 M: 3 = 3
 M: 2 = 2
+M: 4 = 4