[qfcc] Add an explicit hadamard operator

While the option to make '*' mean dot product for vectors is important,
it breaks vector scaling in ruamoko progs as the resultant vector op
becomes a dot product instead of the indented hadamard product (ie,
component-wise).
This commit is contained in:
Bill Currie 2022-11-16 00:06:21 +09:00
parent 387f17dc0c
commit f323401c10
7 changed files with 14 additions and 3 deletions

View file

@ -394,7 +394,7 @@ do_op_vector (int op, expr_t *e, expr_t *e1, expr_t *e2)
{
const float *v1, *v2;
vec3_t v, float_vec;
static int valid[] = {'+', '-', '*', SCALE, EQ, NE, 0};
static int valid[] = {'+', '-', '*', HADAMARD, SCALE, EQ, NE, 0};
expr_t *t;
if (!is_vector(get_type (e1))) {

View file

@ -94,6 +94,7 @@ get_op_string (int op)
case 'C': return "<cast>";
case CROSS: return "@cross";
case DOT: return "@dot";
case HADAMARD: return "@hadamard";
case SCALE: return "@scale";
default:
return "unknown";

View file

@ -150,6 +150,7 @@ static expr_type_t vector_vector[] = {
{'-', &type_vector},
{DOT, &type_vector},
{CROSS, &type_vector},
{HADAMARD, &type_vector},
{'*', 0, 0, 0, vector_multiply},
{EQ, 0, 0, 0, vector_compare},
{NE, 0, 0, 0, vector_compare},
@ -1100,11 +1101,13 @@ binary_expr (int op, expr_t *e1, expr_t *e2)
t2 = pt2;
}
}
int scalar_op = 0;
if (type_width (t1) == 1) {
// scalar op vec
if (!(e = convert_scalar (e1, op, e2))) {
return invalid_binary_expr (op, e1, e2);
}
scalar_op = 1;
e1 = e;
t1 = get_type (e1);
}
@ -1113,9 +1116,13 @@ binary_expr (int op, expr_t *e1, expr_t *e2)
if (!(e = convert_scalar (e2, op, e1))) {
return invalid_binary_expr (op, e1, e2);
}
scalar_op = 1;
e2 = e;
t2 = get_type (e2);
}
if (scalar_op && op == '*') {
op = HADAMARD;
}
if (type_width (t1) != type_width (t2)) {
// vec op vec of different widths
return invalid_binary_expr (op, e1, e2);

View file

@ -742,7 +742,7 @@ DecodeArgs (int argc, char **argv)
if (options.code.vector_components == (qboolean) -1)
options.code.vector_components = false;
if (options.math.vector_mult == 0)
options.math.vector_mult = options.advanced == 1 ? DOT : '*';
options.math.vector_mult = options.advanced == 1 ? DOT : HADAMARD;
} else {
options.code.promote_float = 0;
}

View file

@ -428,6 +428,7 @@ static keyword_t qf_keywords[] = {
{"@cross", CROSS, 0 },
{"@dot", DOT, 0 },
{"@hadamard", HADAMARD, 0 },
};
// These keywors are always available. Other than the @ keywords, they

View file

@ -141,7 +141,7 @@ int yylex (void);
%left SHL SHR
%left '+' '-'
%left '*' '/' '%' MOD SCALE
%left CROSS DOT
%left CROSS DOT HADAMARD
%right <op> SIZEOF UNARY INCOP
%left HYPERUNARY
%left '.' '(' '['
@ -1672,6 +1672,7 @@ expr
| expr MOD expr { $$ = binary_expr (MOD, $1, $3); }
| expr CROSS expr { $$ = binary_expr (CROSS, $1, $3); }
| expr DOT expr { $$ = binary_expr (DOT, $1, $3); }
| expr HADAMARD expr { $$ = binary_expr (HADAMARD, $1, $3); }
;
texpr

View file

@ -538,6 +538,7 @@ convert_op (int op)
case '.': return "load";
case CROSS: return "cross";
case DOT: return "dot";
case HADAMARD: return "mul";
case SCALE: return "scale";
default:
return 0;