// valueType maybe a ConstantExpression and then Prune optimizes unreachable branches out static Expression MatchOrElse(Expression valueType, BondDataType expectedType, TypeHandlerCompiletime handler, Expression orElse) { return(PrunedExpression.IfThenElse( Expression.Equal(valueType, Expression.Constant(expectedType)), handler(expectedType), orElse)); }
// Generates expression to handle value of type that is different but compatible with expected type static Expression TryCompatible(Expression valueType, BondDataType expectedType, TypeHandlerCompiletime handler) { if (expectedType == BondDataType.BT_DOUBLE) { return(MatchOrElse(valueType, BondDataType.BT_FLOAT, handler, InvalidType(expectedType, valueType))); } if (expectedType == BondDataType.BT_UINT64) { return(MatchOrElse(valueType, BondDataType.BT_UINT32, handler, MatchOrElse(valueType, BondDataType.BT_UINT16, handler, MatchOrElse(valueType, BondDataType.BT_UINT8, handler, InvalidType(expectedType, valueType))))); } if (expectedType == BondDataType.BT_UINT32) { return(MatchOrElse(valueType, BondDataType.BT_UINT16, handler, MatchOrElse(valueType, BondDataType.BT_UINT8, handler, InvalidType(expectedType, valueType)))); } if (expectedType == BondDataType.BT_UINT16) { return(MatchOrElse(valueType, BondDataType.BT_UINT8, handler, InvalidType(expectedType, valueType))); } if (expectedType == BondDataType.BT_INT64) { return(MatchOrElse(valueType, BondDataType.BT_INT32, handler, MatchOrElse(valueType, BondDataType.BT_INT16, handler, MatchOrElse(valueType, BondDataType.BT_INT8, handler, InvalidType(expectedType, valueType))))); } if (expectedType == BondDataType.BT_INT32) { return(MatchOrElse(valueType, BondDataType.BT_INT16, handler, MatchOrElse(valueType, BondDataType.BT_INT8, handler, InvalidType(expectedType, valueType)))); } if (expectedType == BondDataType.BT_INT16) { return(MatchOrElse(valueType, BondDataType.BT_INT8, handler, InvalidType(expectedType, valueType))); } return(InvalidType(expectedType, valueType)); }
// Generate expression to handle exact match or compatible type static Expression MatchOrCompatible(Expression valueType, BondDataType expectedType, TypeHandlerCompiletime handler) { return(MatchOrElse(valueType, expectedType, handler, TryCompatible(valueType, expectedType, handler))); }