[qfcc] Implement quaternion multiplication

I'm surprised it took almost two years to discover that I had no
quaternion multiplications in any test code, but getting an ICE for a
quaternion-vector product, and the Hadamard product for
quaternion-quaternion was a bit of a nasty surprise.
This commit is contained in:
Bill Currie 2024-02-01 11:00:27 +09:00
parent 2e19e2d913
commit 5fef8e6edb
3 changed files with 17 additions and 3 deletions

View file

@ -48,6 +48,7 @@ typedef struct {
bool (*commutative) (void);
bool (*anticommute) (void);
bool (*associative) (void);
int true_op;
} expr_type_t;
static const expr_t *pointer_arithmetic (int op, const expr_t *e1,
@ -272,7 +273,12 @@ static expr_type_t quat_float[] = {
};
static expr_type_t quat_vector[] = {
{'*', &type_vector},
{'*', &type_vector, .true_op = QVMUL},
{0, 0}
};
static expr_type_t vector_quat[] = {
{'*', &type_vector, .true_op = VQMUL},
{0, 0}
};
@ -281,7 +287,7 @@ static expr_type_t quat_quat[] = {
.commutative = fp_com_add, .associative = fp_ass_add},
{'-', &type_quaternion,
.anticommute = fp_com_add},
{'*', &type_quaternion, .associative = always},
{'*', &type_quaternion, .associative = always, .true_op = QMUL},
{EQ, &type_int},
{NE, &type_int},
{0, 0}
@ -727,6 +733,7 @@ static expr_type_t *float_x[ev_type_count] = {
static expr_type_t *vector_x[ev_type_count] = {
[ev_float] = vector_float,
[ev_vector] = vector_vector,
[ev_quaternion] = vector_quat,
[ev_int] = vector_int,
[ev_uint] = vector_uint,
[ev_short] = vector_short,
@ -1463,6 +1470,10 @@ binary_expr (int op, const expr_t *e1, const expr_t *e2)
if ((e = reimplement_binary_expr (op, e1, e2)))
return edag_add_expr (fold_constants (e));
if (expr_type->true_op) {
op = expr_type->true_op;
}
auto ne = new_binary_expr (op, e1, e2);
ne->expr.type = expr_type->result_type;
if (expr_type->commutative) {

View file

@ -143,7 +143,7 @@ int yylex (void);
%left SHL SHR
%left '+' '-'
%left '*' '/' '%' MOD SCALE GEOMETRIC
%left '*' '/' '%' MOD SCALE GEOMETRIC QMUL QVMUL VQMUL
%left HADAMARD CROSS DOT WEDGE REGRESSIVE
%right <op> SIZEOF UNARY INCOP REVERSE STAR DUAL
%left HYPERUNARY

View file

@ -602,6 +602,9 @@ convert_op (int op)
case DOT: return "dot";
case HADAMARD: return "mul";
case SCALE: return "scale";
case QMUL: return "qmul";
case QVMUL: return "qvmul";
case VQMUL: return "vqmul";
default:
return 0;
}