evaluateOpBinary method

EvaluateExprOutput evaluateOpBinary(
  1. EvaluateExprInput input
)

Implementation

EvaluateExprOutput evaluateOpBinary(EvaluateExprInput input) {
  final operator = input.expr.obj.keys.first;
  final ol = evaluateExpr(EvaluateExprInput(
      path: pathAppendIndex(pathAppendKey(input.path, operator), 0),
      defs: input.defs,
      expr: input.expr.obj[operator]!.arr[0]));
  if (ol.status != EvaluateExprOutput_Status.OK) {
    return ol;
  }
  final operandL = ol.value;
  final or = evaluateExpr(EvaluateExprInput(
      path: pathAppendIndex(pathAppendKey(input.path, operator), 1),
      defs: input.defs,
      expr: input.expr.obj[operator]!.arr[1]));
  if (or.status != EvaluateExprOutput_Status.OK) {
    return or;
  }
  final operandR = or.value;
  final pathOp = pathAppendKey(input.path, operator);
  if (operator == opBinaryKeyName(OpBinary_Operator.SUB)) {
    if (operandL.type != Type.TYPE_NUM) {
      return _errorUnexpectedType(
          pathAppendIndex(pathOp, 0), [Type.TYPE_NUM], operandL.type);
    }
    if (operandR.type != Type.TYPE_NUM) {
      return _errorUnexpectedType(
          pathAppendIndex(pathOp, 1), [Type.TYPE_NUM], operandR.type);
    }
    final v = Value(type: Type.TYPE_NUM, num: operandL.num - operandR.num);
    if (!_isFiniteNumber(v)) {
      return _errorArithmeticError(
          pathOp, "${operandL.num}-${operandR.num} is not a finite number");
    }
    return EvaluateExprOutput(value: v);
  } else if (operator == opBinaryKeyName(OpBinary_Operator.DIV)) {
    if (operandL.type != Type.TYPE_NUM) {
      return _errorUnexpectedType(
          pathAppendIndex(pathOp, 0), [Type.TYPE_NUM], operandL.type);
    }
    if (operandR.type != Type.TYPE_NUM) {
      return _errorUnexpectedType(
          pathAppendIndex(pathOp, 1), [Type.TYPE_NUM], operandR.type);
    }
    final v = Value(type: Type.TYPE_NUM, num: operandL.num / operandR.num);
    if (!_isFiniteNumber(v)) {
      return _errorArithmeticError(
          pathOp, "${operandL.num}/${operandR.num} is not a finite number");
    }
    return EvaluateExprOutput(value: v);
  } else if (operator == opBinaryKeyName(OpBinary_Operator.EQ)) {
    return equal(pathOp, operandL, operandR);
  } else if (operator == opBinaryKeyName(OpBinary_Operator.NEQ)) {
    final eq = equal(pathOp, operandL, operandR);
    if (eq.status != EvaluateExprOutput_Status.OK) {
      return eq;
    }
    return EvaluateExprOutput(
        value: Value(type: Type.TYPE_BOOL, bool_2: !eq.value.bool_2));
  } else if (operator == opBinaryKeyName(OpBinary_Operator.LT)) {
    final cmp = compare(pathOp, operandL, operandR);
    if (cmp.status != EvaluateExprOutput_Status.OK) {
      return cmp;
    }
    return EvaluateExprOutput(
        value: Value(type: Type.TYPE_BOOL, bool_2: cmp.value.num < 0));
  } else if (operator == opBinaryKeyName(OpBinary_Operator.LTE)) {
    final cmp = compare(pathOp, operandL, operandR);
    if (cmp.status != EvaluateExprOutput_Status.OK) {
      return cmp;
    }
    return EvaluateExprOutput(
        value: Value(type: Type.TYPE_BOOL, bool_2: cmp.value.num <= 0));
  } else if (operator == opBinaryKeyName(OpBinary_Operator.GT)) {
    final cmp = compare(pathOp, operandL, operandR);
    if (cmp.status != EvaluateExprOutput_Status.OK) {
      return cmp;
    }
    return EvaluateExprOutput(
        value: Value(type: Type.TYPE_BOOL, bool_2: cmp.value.num > 0));
  } else if (operator == opBinaryKeyName(OpBinary_Operator.GTE)) {
    final cmp = compare(pathOp, operandL, operandR);
    if (cmp.status != EvaluateExprOutput_Status.OK) {
      return cmp;
    }
    return EvaluateExprOutput(
        value: Value(type: Type.TYPE_BOOL, bool_2: cmp.value.num >= 0));
  }
  return _errorUnsupportedOperation(input.path, operator);
}