return (a.x && a.y && a.z);
}
+static GMQCC_INLINE vec3_t vec3_cross(vec3_t a, vec3_t b) {
+ vec3_t out;
+ out.x = a.y * b.z - a.z * b.y;
+ out.y = a.z * b.x - a.x * b.z;
+ out.z = a.x * b.y - a.y * b.x;
+ return out;
+}
+
static lex_ctx_t fold_ctx(fold_t *fold) {
lex_ctx_t ctx;
if (fold->parser->lex)
return NULL;
}
+static GMQCC_INLINE ast_expression *fold_op_cross(fold_t *fold, ast_value *a, ast_value *b) {
+ if (fold_can_2(a, b))
+ return fold_constgen_vector(fold, vec3_cross(fold_immvalue_vector(a), fold_immvalue_vector(b)));
+ return NULL;
+}
+
ast_expression *fold_op(fold_t *fold, const oper_info *info, ast_expression **opexprs) {
ast_value *a = (ast_value*)opexprs[0];
ast_value *b = (ast_value*)opexprs[1];
fold_op_case(2, ('!', '='), cmp, (fold, a, b, true));
fold_op_case(2, ('=', '='), cmp, (fold, a, b, false));
fold_op_case(2, ('~', 'P'), bnot, (fold, a));
+ fold_op_case(2, ('>', '<'), cross, (fold, a, b));
}
#undef fold_op_case
compile_error(fold_ctx(fold), "internal error: attempted to constant-fold for unsupported operator");
}
if (ch == '+' || ch == '-' || /* ++, --, +=, -= and -> as well! */
- ch == '>' || ch == '<' || /* <<, >>, <=, >= */
+ ch == '>' || ch == '<' || /* <<, >>, <=, >= and >< as well! */
ch == '=' || ch == '!' || /* <=>, ==, != */
ch == '&' || ch == '|' || /* &&, ||, &=, |= */
ch == '~' || ch == '^' /* ~=, ~, ^ */
lex_tokench(lex, ch);
nextch = lex_getch(lex);
- if ((nextch == '=' && ch != '<') || (nextch == ch && ch != '!')) {
+ if ((nextch == '=' && ch != '<') ||
+ (nextch == ch && ch != '!') ||
+ (nextch == '<' && ch == '>')) {
lex_tokench(lex, nextch);
} else if (ch == '<' && nextch == '=') {
lex_tokench(lex, nextch);
{ "*", 2, opid1('*'), ASSOC_LEFT, 13, 0, true},
{ "/", 2, opid1('/'), ASSOC_LEFT, 13, 0, true},
{ "%", 2, opid1('%'), ASSOC_LEFT, 13, 0, true},
+ { "><", 2, opid2('>','<'), ASSOC_LEFT, 13, 0, true},
{ "+", 2, opid1('+'), ASSOC_LEFT, 12, 0, true},
{ "-", 2, opid1('-'), ASSOC_LEFT, 12, 0, true},
}
break;
+ case opid2('>', '<'):
+ if (NotSameType(TYPE_VECTOR)) {
+ ast_type_to_string(exprs[0], ty1, sizeof(ty1));
+ ast_type_to_string(exprs[1], ty2, sizeof(ty2));
+ compile_error(ctx, "invalid types used in cross product: %s and %s",
+ ty1, ty2);
+ return false;
+ }
+
+ if (!(out = fold_op(parser->fold, op, exprs))) {
+ compile_error(ctx, "cross product for non-constant vectors unimplemented");
+ return false;
+ }
+
+ break;
+
case opid3('<','=','>'): /* -1, 0, or 1 */
if (NotSameType(TYPE_FLOAT)) {
ast_type_to_string(exprs[0], ty1, sizeof(ty1));
print(vtos(v & 16), "\n");
print(vtos(v | '25 42 51'), "\n");
print(vtos(v & '25 42 51'), "\n");
+ print(vtos('1 2 3' >< '3 2 1'));
}
I: vec_ops.qc
D: some additional vector operations
T: -execute
-C: -std=fteqcc
+C: -std=gmqcc
E: -vector "8 16 32"
M: '8 16 32'
M: '4 8 16'
M: '0 0 16'
M: '29 42 51'
M: '0 8 16'
+M: '-4 8 -4'