Implemented bitwise xor operator.

This commit is contained in:
Dale Weiler 2013-06-15 09:48:40 +00:00
parent 04406b191f
commit a8fddbb7d3
4 changed files with 71 additions and 3 deletions

View file

@ -1309,7 +1309,7 @@ int lex_do(lex_file *lex)
ch == '>' || ch == '<' || /* <<, >>, <=, >= */
ch == '=' || ch == '!' || /* <=>, ==, != */
ch == '&' || ch == '|' || /* &&, ||, &=, |= */
ch == '~' /* ~=, ~ */
ch == '~' || ch == '^' /* ~=, ~, ^ */
) {
lex_tokench(lex, ch);

View file

@ -1034,8 +1034,57 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
exprs[0], exprs[1]);
break;
case opid1('^'):
compile_error(ast_ctx(exprs[0]), "Not Yet Implemented: bit-xor via ^");
return false;
/*
* ^ can be implemented as:
* (LHS | RHS) & ~(LHS & RHS)
* to implement ~ we need to use -1-X, as you can see the
* whole process ends up becoming:
* (LHS | RHS) & (-1 - (LHS & RHS))
*/
#define TRY_TYPE(I) \
if (exprs[0]->vtype != TYPE_FLOAT) { \
ast_type_to_string(exprs[0], ty1, sizeof(ty1)); \
compile_error ( \
ast_ctx(exprs[(I)]), \
"invalid type for bit-xor in %s: %s", \
ty1, \
((I) == 0) \
? "left-hand-side of expression" \
: "right-hand-side of expression" \
); \
return false; \
}
TRY_TYPE(0)
TRY_TYPE(1)
#undef TRY_TYPE
if(CanConstFold(exprs[0], exprs[1])) {
out = (ast_expression*)parser_const_float(parser, (float)((qcint)(ConstF(0)) ^ ((qcint)(ConstF(1)))));
} else {
out = (ast_expression*)
ast_binary_new(
ctx,
INSTR_BITAND,
(ast_expression*)ast_binary_new(
ctx,
INSTR_BITOR,
exprs[0],
exprs[1]
),
(ast_expression*)ast_binary_new(
ctx,
INSTR_SUB_F,
(ast_expression*)parser_const_float_neg1(parser),
(ast_expression*)ast_binary_new(
ctx,
INSTR_BITAND,
exprs[0],
exprs[1]
)
)
);
}
break;
case opid2('<','<'):
case opid2('>','>'):

12
tests/xor.qc Normal file
View file

@ -0,0 +1,12 @@
void main() {
float x = 5;
float y = 3;
float z = x ^ y; // 6
float a = 2;
float b = 10;
float c = a ^ b; // 8
print(ftos(z), "\n");
print(ftos(c), "\n");
}

7
tests/xor.tmpl Normal file
View file

@ -0,0 +1,7 @@
I: xor.qc
D: test bitwise xor
T: -execute
C: -std=gmqcc
E: $null
M: 6
M: 8