[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; const float *v1, *v2;
vec3_t v, float_vec; vec3_t v, float_vec;
static int valid[] = {'+', '-', '*', SCALE, EQ, NE, 0}; static int valid[] = {'+', '-', '*', HADAMARD, SCALE, EQ, NE, 0};
expr_t *t; expr_t *t;
if (!is_vector(get_type (e1))) { if (!is_vector(get_type (e1))) {

View file

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

View file

@ -150,6 +150,7 @@ static expr_type_t vector_vector[] = {
{'-', &type_vector}, {'-', &type_vector},
{DOT, &type_vector}, {DOT, &type_vector},
{CROSS, &type_vector}, {CROSS, &type_vector},
{HADAMARD, &type_vector},
{'*', 0, 0, 0, vector_multiply}, {'*', 0, 0, 0, vector_multiply},
{EQ, 0, 0, 0, vector_compare}, {EQ, 0, 0, 0, vector_compare},
{NE, 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; t2 = pt2;
} }
} }
int scalar_op = 0;
if (type_width (t1) == 1) { if (type_width (t1) == 1) {
// scalar op vec // scalar op vec
if (!(e = convert_scalar (e1, op, e2))) { if (!(e = convert_scalar (e1, op, e2))) {
return invalid_binary_expr (op, e1, e2); return invalid_binary_expr (op, e1, e2);
} }
scalar_op = 1;
e1 = e; e1 = e;
t1 = get_type (e1); 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))) { if (!(e = convert_scalar (e2, op, e1))) {
return invalid_binary_expr (op, e1, e2); return invalid_binary_expr (op, e1, e2);
} }
scalar_op = 1;
e2 = e; e2 = e;
t2 = get_type (e2); t2 = get_type (e2);
} }
if (scalar_op && op == '*') {
op = HADAMARD;
}
if (type_width (t1) != type_width (t2)) { if (type_width (t1) != type_width (t2)) {
// vec op vec of different widths // vec op vec of different widths
return invalid_binary_expr (op, e1, e2); 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) if (options.code.vector_components == (qboolean) -1)
options.code.vector_components = false; options.code.vector_components = false;
if (options.math.vector_mult == 0) if (options.math.vector_mult == 0)
options.math.vector_mult = options.advanced == 1 ? DOT : '*'; options.math.vector_mult = options.advanced == 1 ? DOT : HADAMARD;
} else { } else {
options.code.promote_float = 0; options.code.promote_float = 0;
} }

View file

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

View file

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

View file

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