visitBinaryExpr method

  1. @override
Object? visitBinaryExpr(
  1. Binary expr
)
override

Implementation

@override
Object? visitBinaryExpr(Expr.Binary expr) {
  Object? left = evaluate(expr.left);
  Object? right = evaluate(expr.right);
  switch (expr.operator.type) {
    case TokenType.GREATER:
      checkNumberOperands(expr.operator, left, right);
      return (left as num) > (right as num);
    case TokenType.GREATER_EQUAL:
      checkNumberOperands(expr.operator, left, right);
      return (left as num) >= (right as num);
    case TokenType.LESS:
      checkNumberOperands(expr.operator, left, right);
      return (left as num) < (right as num);
    case TokenType.LESS_EQUAL:
      checkNumberOperands(expr.operator, left, right);
      return (left as num) <= (right as num);
    case TokenType.BANG_EQUAL:
      return !isEqual(left, right);
    case TokenType.EQUAL_EQUAL:
      return isEqual(left, right);
    case TokenType.MINUS:
      if (left is Arithmetic && right is Arithmetic) {
        return left - right;
      }
      checkNumberOperands(expr.operator, right, left);
      return (left as num) - (right as num);
    case TokenType.SLASH:
      checkNumberOperands(expr.operator, right, left);
      return (left as num) / (right as num);
    case TokenType.STAR:
      checkNumberOperands(expr.operator, right, left);
      return (left as num) * (right as num);
    case TokenType.MOD:
      checkNumberOperands(expr.operator, right, left);
      return (left as num) % (right as num);
    case TokenType.PLUS:
      if (left is Arithmetic && right is Arithmetic) {
        return left + right;
      }
      if (left is num && right is num) {
        return left + right;
      }
      if (left is String && right is String) {
        return left + right;
      }
      throw RuntimeError(
          expr.operator, "Operands must be two numbers or two strings.");
    default:
      break;
  }
  return null;
}