binary method
+ - * /, with GLSL's broadcasting; a sum or a difference of one
dimension, a product or a quotient of any two.
Implementation
Expression binary(ExpressionToken op, Expression left, Expression right) {
for (final side in <Expression>[left, right]) {
if (!side.type.isNumeric) {
fail(
'"${op.text}" works on numbers, not on a ${side.type.name}.',
where: op,
);
}
}
final a = left.type.components;
final b = right.type.components;
if (a != b && a != 1 && b != 1) {
fail(
'a ${left.type} and a ${right.type} cannot be combined with '
'"${op.text}".',
where: op,
);
}
final dimension = switch (op.text) {
'*' => left.type.dimension * right.type.dimension,
'/' => left.type.dimension / right.type.dimension,
_ when left.type.dimension == right.type.dimension => left.type.dimension,
_ => fail(
'a ${left.type} and a ${right.type} cannot be '
'${op.text == '+' ? 'added' : 'subtracted'}: they measure different '
'things.',
where: op,
),
};
return ExpressionBinary(
op.text,
left,
right,
ExpressionType.numeric[a > b ? a : b]!.withDimension(dimension),
);
}