From: Wolfgang (Blub) Bumiller Date: Fri, 23 Nov 2012 13:39:05 +0000 (+0100) Subject: operator &~= X-Git-Tag: 0.1.9~311 X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=commitdiff_plain;h=0d33939b1be1b273daf462a070ea6be4c99820e4 operator &~= --- diff --git a/lexer.c b/lexer.c index c37678e..8f1bcb8 100644 --- 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 f293345..2135ec6 100644 --- 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 }, diff --git a/parser.c b/parser.c index 67d7202..fb13d2b 100644 --- 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 diff --git a/tests/operators.qc b/tests/operators.qc index e1464e3..1ca6f67 100644 --- a/tests/operators.qc +++ b/tests/operators.qc @@ -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"); } diff --git a/tests/operators.tmpl b/tests/operators.tmpl index fcf9afd..1283ad6 100644 --- a/tests/operators.tmpl +++ b/tests/operators.tmpl @@ -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