binary method

Expression binary(
  1. ExpressionToken op,
  2. Expression left,
  3. Expression right
)

+ - * /, 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),
  );
}