evaluateOpBinary method
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);
}