evaluateOpBinary method
Implementation
EvaluateOutput evaluateOpBinary(EvaluateInput input) {
final op = input.expr.opBinary;
final ol =
evaluateExpr(EvaluateInput(defStack: input.defStack, expr: op.left));
if (ol.status != EvaluateOutput_Status.OK) {
return ol;
}
final or =
evaluateExpr(EvaluateInput(defStack: input.defStack, expr: op.right));
if (or.status != EvaluateOutput_Status.OK) {
return or;
}
final operandL = ol.value;
final operandR = or.value;
switch (op.op) {
case OpBinary_Op.SUB:
if (operandL.type != Value_Type.NUM) {
return _errorUnexpectedType(input.expr.path.append(['sub', 0]),
operandL.type, [Value_Type.NUM]);
}
if (operandR.type != Value_Type.NUM) {
return _errorUnexpectedType(input.expr.path.append(['sub', 1]),
operandR.type, [Value_Type.NUM]);
}
final v = operandL.num - operandR.num;
if (!v.isFinite) {
return _errorNotFiniteNumber(input.expr.path);
}
return EvaluateOutput(value: numValue(v));
case OpBinary_Op.DIV:
if (operandL.type != Value_Type.NUM) {
return _errorUnexpectedType(input.expr.path.append(['div', 0]),
operandL.type, [Value_Type.NUM]);
}
if (operandR.type != Value_Type.NUM) {
return _errorUnexpectedType(input.expr.path.append(['div', 1]),
operandR.type, [Value_Type.NUM]);
}
final v = operandL.num / operandR.num;
if (!v.isFinite) {
return _errorNotFiniteNumber(input.expr.path);
}
return EvaluateOutput(value: numValue(v));
case OpBinary_Op.EQ:
return EvaluateOutput(value: _equal(operandL, operandR));
case OpBinary_Op.NEQ:
return EvaluateOutput(
value: boolValue(!_equal(operandL, operandR).bool_2));
case OpBinary_Op.LT:
final cmpVal =
_compare(input.expr.path.append(['lt']), operandL, operandR);
if (cmpVal.status != EvaluateOutput_Status.OK) {
return cmpVal;
}
return EvaluateOutput(value: boolValue(cmpVal.value.num < 0));
case OpBinary_Op.LTE:
final cmpVal =
_compare(input.expr.path.append(['lte']), operandL, operandR);
if (cmpVal.status != EvaluateOutput_Status.OK) {
return cmpVal;
}
return EvaluateOutput(value: boolValue(cmpVal.value.num <= 0));
case OpBinary_Op.GT:
final cmpVal =
_compare(input.expr.path.append(['gt']), operandL, operandR);
if (cmpVal.status != EvaluateOutput_Status.OK) {
return cmpVal;
}
return EvaluateOutput(value: boolValue(cmpVal.value.num > 0));
case OpBinary_Op.GTE:
final cmpVal =
_compare(input.expr.path.append(['gte']), operandL, operandR);
if (cmpVal.status != EvaluateOutput_Status.OK) {
return cmpVal;
}
return EvaluateOutput(value: boolValue(cmpVal.value.num >= 0));
default:
throw ArgumentError('unexpected binary operator ${op.op}');
}
}