1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-12 13:24:09 +02:00

Pre-widened args for 'i32 = i8 + 100'

This commit is contained in:
Brian Fiete 2021-12-31 07:55:52 -05:00
parent 07a530c921
commit e7f079f611

View file

@ -20835,7 +20835,13 @@ void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExp
if ((binaryOp == BfBinaryOp_NullCoalesce) && (PerformBinaryOperation_NullCoalesce(opToken, leftExpression, rightExpression, leftValue, wantType, NULL))) if ((binaryOp == BfBinaryOp_NullCoalesce) && (PerformBinaryOperation_NullCoalesce(opToken, leftExpression, rightExpression, leftValue, wantType, NULL)))
return; return;
rightValue = mModule->CreateValueFromExpression(rightExpression, wantType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast)); BfType* rightWantType = wantType;
if ((mExpectingType != NULL) && (wantType != NULL) && (mExpectingType->IsIntegral()) && (wantType->IsIntegral()) && (mExpectingType->mSize > wantType->mSize) &&
((binaryOp == BfBinaryOp_Add) || (binaryOp == BfBinaryOp_Subtract) || (binaryOp == BfBinaryOp_Multiply)))
rightWantType = mExpectingType;
rightValue = mModule->CreateValueFromExpression(rightExpression, rightWantType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast));
if ((rightWantType != wantType) && (rightValue.mType == rightWantType))
wantType = rightWantType;
if ((!leftValue) || (!rightValue)) if ((!leftValue) || (!rightValue))
return; return;
@ -21268,46 +21274,63 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
if (!forceLeftType) if (!forceLeftType)
{ {
bool handled = false; bool handled = false;
// If one of these is a constant that can be converted into a smaller type, then do that
if (rightValue.mValue.IsConst())
{
if (mModule->CanCast(rightValue, leftValue.mType, BfCastFlags_NoBox))
{
resultType = leftValue.mType;
handled = true;
}
}
// If left is an IntUnknown, allow the right to inform the type if (leftValue.mType == rightValue.mType)
if (leftValue.mType->IsIntUnknown()) {
// All good
handled = true;
}
else if ((mExpectingType != NULL) &&
(mModule->CanCast(leftValue, mExpectingType, BfCastFlags_NoBox)) &&
(mModule->CanCast(rightValue, mExpectingType, BfCastFlags_NoBox)) &&
(!leftValue.mType->IsVar()) && (!rightValue.mType->IsVar()))
{
resultType = mExpectingType;
handled = true;
}
else
{ {
if (leftValue.mValue.IsConst()) // If one of these is a constant that can be converted into a smaller type, then do that
if (rightValue.mValue.IsConst())
{ {
if (mModule->CanCast(leftValue, rightValue.mType)) if (mModule->CanCast(rightValue, leftValue.mType, BfCastFlags_NoBox))
{ {
resultType = rightValue.mType; resultType = leftValue.mType;
handled = true; handled = true;
} }
} }
}
if ((leftValue.mType->IsPointer()) && // If left is an IntUnknown, allow the right to inform the type
(rightValue.mType->IsPointer())) if (leftValue.mType->IsIntUnknown())
{
BfPointerType* leftPointerType = (BfPointerType*)leftValue.mType;
BfPointerType* rightPointerType = (BfPointerType*)rightValue.mType;
// If one is a pointer to a sized array then use the other type
if (leftPointerType->mElementType->IsSizedArray())
{ {
resultType = rightPointerType; if (leftValue.mValue.IsConst())
handled = true; {
if (mModule->CanCast(leftValue, rightValue.mType))
{
resultType = rightValue.mType;
handled = true;
}
}
} }
else if (rightPointerType->mElementType->IsSizedArray())
if ((leftValue.mType->IsPointer()) &&
(rightValue.mType->IsPointer()))
{ {
resultType = leftPointerType; BfPointerType* leftPointerType = (BfPointerType*)leftValue.mType;
handled = true; BfPointerType* rightPointerType = (BfPointerType*)rightValue.mType;
}
// If one is a pointer to a sized array then use the other type
if (leftPointerType->mElementType->IsSizedArray())
{
resultType = rightPointerType;
handled = true;
}
else if (rightPointerType->mElementType->IsSizedArray())
{
resultType = leftPointerType;
handled = true;
}
}
} }
if (!handled) if (!handled)