in daffodil-core/src/main/scala/org/apache/daffodil/core/dpath/NodeInfoUtils.scala [84:133]
def generalizeArgAndResultTypesForNumericOp(
op: String,
leftArgType: Numeric.Kind,
rightArgType: Numeric.Kind
): ( //
Numeric.Kind, // first result is generalized arg type
Numeric.Kind // second result is generalized result type
) = {
/*
* Adjust for the Decimal result type when div/idiv is used
*/
def divResult(resultType: NodeInfo.Numeric.Kind) = resultType match {
case ArrayIndex => ArrayIndex
case _: Decimal.Kind => Decimal
case Double => Double
case Float => Float
case _ => Assert.usageError("Unsupported return type: %s".format(resultType))
}
def idivResult(resultType: NodeInfo.Numeric.Kind) = resultType match {
case Decimal => Integer
case Integer => Integer
case Double => Long
case Long => Long
case Float => Int
case Int => Int
case Short => Short
case ArrayIndex => ArrayIndex
case _ => Assert.usageError("Unsupported return type: %s".format(resultType))
}
val (argType: Numeric.Kind, resultType: Numeric.Kind) = {
val lub = NodeInfoUtils.typeLeastUpperBound(leftArgType, rightArgType)
//
// For each abstract type that could be the least upper bound of the two
// arg types, we must pick a concrete type to convert everything into.
val lubImplementationType = lub match {
case SignedNumeric => NodeInfo.Double
case _ => lub
}
(lubImplementationType, lubImplementationType)
}
val res = op match {
case "div" => (argType, divResult(resultType))
case "idiv" => (argType, idivResult(resultType))
case _ => (argType, resultType)
}
res
}