mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +02:00
Added overflow operators &+, &-, &*
This commit is contained in:
parent
8d2b222c1a
commit
d475d3641f
7 changed files with 151 additions and 25 deletions
|
@ -1500,6 +1500,12 @@ const char* Beefy::BfTokenToString(BfToken token)
|
||||||
return ">>=";
|
return ">>=";
|
||||||
case BfToken_AndEquals:
|
case BfToken_AndEquals:
|
||||||
return "&=";
|
return "&=";
|
||||||
|
case BfToken_AndMinus:
|
||||||
|
return "&-";
|
||||||
|
case BfToken_AndPlus:
|
||||||
|
return "&+";
|
||||||
|
case BfToken_AndStar:
|
||||||
|
return "&*";
|
||||||
case BfToken_OrEquals:
|
case BfToken_OrEquals:
|
||||||
return "|=";
|
return "|=";
|
||||||
case BfToken_XorEquals:
|
case BfToken_XorEquals:
|
||||||
|
@ -1630,11 +1636,14 @@ int Beefy::BfGetBinaryOpPrecendence(BfBinaryOp binOp)
|
||||||
switch (binOp)
|
switch (binOp)
|
||||||
{
|
{
|
||||||
case BfBinaryOp_Multiply:
|
case BfBinaryOp_Multiply:
|
||||||
|
case BfBinaryOp_OverflowMultiply:
|
||||||
case BfBinaryOp_Divide:
|
case BfBinaryOp_Divide:
|
||||||
case BfBinaryOp_Modulus:
|
case BfBinaryOp_Modulus:
|
||||||
return 13;
|
return 13;
|
||||||
case BfBinaryOp_Add:
|
case BfBinaryOp_Add:
|
||||||
case BfBinaryOp_Subtract:
|
case BfBinaryOp_Subtract:
|
||||||
|
case BfBinaryOp_OverflowAdd:
|
||||||
|
case BfBinaryOp_OverflowSubtract:
|
||||||
return 12;
|
return 12;
|
||||||
case BfBinaryOp_LeftShift:
|
case BfBinaryOp_LeftShift:
|
||||||
case BfBinaryOp_RightShift:
|
case BfBinaryOp_RightShift:
|
||||||
|
@ -1682,6 +1691,9 @@ const char* Beefy::BfGetOpName(BfBinaryOp binOp)
|
||||||
case BfBinaryOp_Add: return "+";
|
case BfBinaryOp_Add: return "+";
|
||||||
case BfBinaryOp_Subtract: return "-";
|
case BfBinaryOp_Subtract: return "-";
|
||||||
case BfBinaryOp_Multiply: return "*";
|
case BfBinaryOp_Multiply: return "*";
|
||||||
|
case BfBinaryOp_OverflowAdd: return "&+";
|
||||||
|
case BfBinaryOp_OverflowSubtract: return "&-";
|
||||||
|
case BfBinaryOp_OverflowMultiply: return "&*";
|
||||||
case BfBinaryOp_Divide: return "/";
|
case BfBinaryOp_Divide: return "/";
|
||||||
case BfBinaryOp_Modulus: return "%";
|
case BfBinaryOp_Modulus: return "%";
|
||||||
case BfBinaryOp_BitwiseAnd: return "&";
|
case BfBinaryOp_BitwiseAnd: return "&";
|
||||||
|
@ -1742,6 +1754,12 @@ BfBinaryOp Beefy::BfTokenToBinaryOp(BfToken token)
|
||||||
return BfBinaryOp_Subtract;
|
return BfBinaryOp_Subtract;
|
||||||
case BfToken_Star:
|
case BfToken_Star:
|
||||||
return BfBinaryOp_Multiply;
|
return BfBinaryOp_Multiply;
|
||||||
|
case BfToken_AndPlus:
|
||||||
|
return BfBinaryOp_OverflowAdd;
|
||||||
|
case BfToken_AndMinus:
|
||||||
|
return BfBinaryOp_OverflowSubtract;
|
||||||
|
case BfToken_AndStar:
|
||||||
|
return BfBinaryOp_OverflowMultiply;
|
||||||
case BfToken_ForwardSlash:
|
case BfToken_ForwardSlash:
|
||||||
return BfBinaryOp_Divide;
|
return BfBinaryOp_Divide;
|
||||||
case BfToken_Modulus:
|
case BfToken_Modulus:
|
||||||
|
|
|
@ -210,6 +210,9 @@ enum BfToken : uint8
|
||||||
BfToken_ShiftLeftEquals,
|
BfToken_ShiftLeftEquals,
|
||||||
BfToken_ShiftRightEquals,
|
BfToken_ShiftRightEquals,
|
||||||
BfToken_AndEquals,
|
BfToken_AndEquals,
|
||||||
|
BfToken_AndMinus,
|
||||||
|
BfToken_AndPlus,
|
||||||
|
BfToken_AndStar,
|
||||||
BfToken_OrEquals,
|
BfToken_OrEquals,
|
||||||
BfToken_XorEquals,
|
BfToken_XorEquals,
|
||||||
BfToken_NullCoalsceEquals,
|
BfToken_NullCoalsceEquals,
|
||||||
|
@ -1795,6 +1798,9 @@ enum BfBinaryOp
|
||||||
BfBinaryOp_Add,
|
BfBinaryOp_Add,
|
||||||
BfBinaryOp_Subtract,
|
BfBinaryOp_Subtract,
|
||||||
BfBinaryOp_Multiply,
|
BfBinaryOp_Multiply,
|
||||||
|
BfBinaryOp_OverflowAdd,
|
||||||
|
BfBinaryOp_OverflowSubtract,
|
||||||
|
BfBinaryOp_OverflowMultiply,
|
||||||
BfBinaryOp_Divide,
|
BfBinaryOp_Divide,
|
||||||
BfBinaryOp_Modulus,
|
BfBinaryOp_Modulus,
|
||||||
BfBinaryOp_BitwiseAnd,
|
BfBinaryOp_BitwiseAnd,
|
||||||
|
|
|
@ -21177,11 +21177,20 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
BfBinaryOp findBinaryOp = binaryOp;
|
BfBinaryOp findBinaryOp = binaryOp;
|
||||||
|
|
||||||
bool isComparison = (binaryOp >= BfBinaryOp_Equality) && (binaryOp <= BfBinaryOp_LessThanOrEqual);
|
bool isComparison = (binaryOp >= BfBinaryOp_Equality) && (binaryOp <= BfBinaryOp_LessThanOrEqual);
|
||||||
|
|
||||||
for (int pass = 0; pass < 2; pass++)
|
for (int pass = 0; pass < 2; pass++)
|
||||||
{
|
{
|
||||||
BfBinaryOp oppositeBinaryOp = BfGetOppositeBinaryOp(findBinaryOp);
|
BfBinaryOp oppositeBinaryOp = BfGetOppositeBinaryOp(findBinaryOp);
|
||||||
bool foundOp = false;
|
BfBinaryOp overflowBinaryOp = BfBinaryOp_None;
|
||||||
|
|
||||||
|
if (findBinaryOp == BfBinaryOp_OverflowAdd)
|
||||||
|
overflowBinaryOp = BfBinaryOp_Add;
|
||||||
|
else if (findBinaryOp == BfBinaryOp_OverflowSubtract)
|
||||||
|
overflowBinaryOp = BfBinaryOp_Subtract;
|
||||||
|
else if (findBinaryOp == BfBinaryOp_OverflowMultiply)
|
||||||
|
overflowBinaryOp = BfBinaryOp_Multiply;
|
||||||
|
|
||||||
|
bool foundOp = false;
|
||||||
|
|
||||||
BfResolvedArg leftArg;
|
BfResolvedArg leftArg;
|
||||||
leftArg.mExpression = leftExpression;
|
leftArg.mExpression = leftExpression;
|
||||||
|
@ -21225,7 +21234,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
bool invertResult = false;
|
bool invertResult = false;
|
||||||
BfType* operatorConstraintReturnType = NULL;
|
BfType* operatorConstraintReturnType = NULL;
|
||||||
|
|
||||||
bool wasTransformedUsage = pass == 1;
|
bool wasTransformedUsage = (pass == 1);
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
@ -21288,7 +21297,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (operatorDef->mOperatorDeclaration->mBinOp == oppositeBinaryOp)
|
else if ((operatorDef->mOperatorDeclaration->mBinOp == oppositeBinaryOp) || (operatorDef->mOperatorDeclaration->mBinOp == overflowBinaryOp))
|
||||||
oppositeOperatorDefs.Add(operatorDef);
|
oppositeOperatorDefs.Add(operatorDef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21309,7 +21318,8 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
methodMatcher.mBestMethodDef = oppositeOperatorDef;
|
methodMatcher.mBestMethodDef = oppositeOperatorDef;
|
||||||
methodMatcher.mBestMethodTypeInstance = checkType;
|
methodMatcher.mBestMethodTypeInstance = checkType;
|
||||||
methodMatcher.mSelfType = entry.mSrcType;
|
methodMatcher.mSelfType = entry.mSrcType;
|
||||||
wasTransformedUsage = true;
|
if (oppositeBinaryOp != BfBinaryOp_None)
|
||||||
|
wasTransformedUsage = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -21322,7 +21332,8 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
{
|
{
|
||||||
operatorConstraintReturnType = returnType;
|
operatorConstraintReturnType = returnType;
|
||||||
methodMatcher.mSelfType = entry.mSrcType;
|
methodMatcher.mSelfType = entry.mSrcType;
|
||||||
wasTransformedUsage = true;
|
if (oppositeBinaryOp != BfBinaryOp_None)
|
||||||
|
wasTransformedUsage = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21332,7 +21343,8 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
if (methodMatcher.CheckMethod(NULL, checkType, oppositeOperatorDef, false))
|
if (methodMatcher.CheckMethod(NULL, checkType, oppositeOperatorDef, false))
|
||||||
{
|
{
|
||||||
methodMatcher.mSelfType = entry.mSrcType;
|
methodMatcher.mSelfType = entry.mSrcType;
|
||||||
wasTransformedUsage = true;
|
if (oppositeBinaryOp != BfBinaryOp_None)
|
||||||
|
wasTransformedUsage = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21526,12 +21538,12 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
|
|
||||||
if (pass == 1)
|
if (pass == 1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
auto flippedBinaryOp = BfGetFlippedBinaryOp(findBinaryOp);
|
auto flippedBinaryOp = BfGetFlippedBinaryOp(findBinaryOp);
|
||||||
if (flippedBinaryOp != BfBinaryOp_None)
|
if (flippedBinaryOp != BfBinaryOp_None)
|
||||||
findBinaryOp = flippedBinaryOp;
|
findBinaryOp = flippedBinaryOp;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto prevResultType = resultType;
|
auto prevResultType = resultType;
|
||||||
if ((leftValue.mType->IsPrimitiveType()) && (!rightValue.mType->IsTypedPrimitive()))
|
if ((leftValue.mType->IsPrimitiveType()) && (!rightValue.mType->IsTypedPrimitive()))
|
||||||
resultType = leftValue.mType;
|
resultType = leftValue.mType;
|
||||||
|
@ -21567,7 +21579,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Allow all pointer comparisons, but only allow SUBTRACTION between equal pointer types
|
//TODO: Allow all pointer comparisons, but only allow SUBTRACTION between equal pointer types
|
||||||
if (binaryOp == BfBinaryOp_Subtract)
|
if ((binaryOp == BfBinaryOp_Subtract) || (binaryOp == BfBinaryOp_OverflowSubtract))
|
||||||
{
|
{
|
||||||
if (!mModule->CanCast(*otherTypedValue, resultType))
|
if (!mModule->CanCast(*otherTypedValue, resultType))
|
||||||
{
|
{
|
||||||
|
@ -21622,7 +21634,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
|
|
||||||
// One pointer
|
// One pointer
|
||||||
if ((!otherType->IsIntegral()) ||
|
if ((!otherType->IsIntegral()) ||
|
||||||
((binaryOp != BfBinaryOp_Add) && (binaryOp != BfBinaryOp_Subtract)))
|
((binaryOp != BfBinaryOp_Add) && (binaryOp != BfBinaryOp_Subtract) && (binaryOp != BfBinaryOp_OverflowAdd) && (binaryOp != BfBinaryOp_OverflowSubtract)))
|
||||||
{
|
{
|
||||||
_OpFail();
|
_OpFail();
|
||||||
return;
|
return;
|
||||||
|
@ -21632,7 +21644,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
BfIRValue addValue = otherTypedValue->mValue;
|
BfIRValue addValue = otherTypedValue->mValue;
|
||||||
if ((!otherTypedValue->mType->IsSigned()) && (otherTypedValue->mType->mSize < mModule->mSystem->mPtrSize))
|
if ((!otherTypedValue->mType->IsSigned()) && (otherTypedValue->mType->mSize < mModule->mSystem->mPtrSize))
|
||||||
addValue = mModule->mBfIRBuilder->CreateNumericCast(addValue, false, BfTypeCode_UIntPtr);
|
addValue = mModule->mBfIRBuilder->CreateNumericCast(addValue, false, BfTypeCode_UIntPtr);
|
||||||
if (binaryOp == BfBinaryOp_Subtract)
|
if ((binaryOp == BfBinaryOp_Subtract) || (binaryOp == BfBinaryOp_OverflowSubtract))
|
||||||
{
|
{
|
||||||
if (resultTypeSrc == rightExpression)
|
if (resultTypeSrc == rightExpression)
|
||||||
mModule->Fail("Cannot subtract a pointer from an integer", resultTypeSrc);
|
mModule->Fail("Cannot subtract a pointer from an integer", resultTypeSrc);
|
||||||
|
@ -21731,7 +21743,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow integer offsetting
|
// Allow integer offsetting
|
||||||
if ((binaryOp == BfBinaryOp_Add) || (binaryOp == BfBinaryOp_Subtract))
|
if ((binaryOp == BfBinaryOp_Add) || (binaryOp == BfBinaryOp_Subtract) || (binaryOp == BfBinaryOp_OverflowAdd) || (binaryOp == BfBinaryOp_OverflowSubtract))
|
||||||
{
|
{
|
||||||
if (otherType->IsIntegral())
|
if (otherType->IsIntegral())
|
||||||
needsOtherCast = false;
|
needsOtherCast = false;
|
||||||
|
@ -21954,7 +21966,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
if (rightValue.mType->IsIntegral())
|
if (rightValue.mType->IsIntegral())
|
||||||
explicitCast = true;
|
explicitCast = true;
|
||||||
}
|
}
|
||||||
else if (((binaryOp == BfBinaryOp_Add) || (binaryOp == BfBinaryOp_Subtract)) && (resultType->IsChar()) && (otherType->IsInteger()))
|
else if (((binaryOp == BfBinaryOp_Add) || (binaryOp == BfBinaryOp_Subtract) || (binaryOp == BfBinaryOp_OverflowAdd) || (binaryOp == BfBinaryOp_OverflowSubtract)) && (resultType->IsChar()) && (otherType->IsInteger()))
|
||||||
{
|
{
|
||||||
// charVal += intVal;
|
// charVal += intVal;
|
||||||
explicitCast = true;
|
explicitCast = true;
|
||||||
|
@ -21980,14 +21992,15 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((binaryOp == BfBinaryOp_Subtract) && (resultType->IsChar()) && (otherType->IsChar()))
|
if (((binaryOp == BfBinaryOp_Subtract) || (binaryOp == BfBinaryOp_OverflowSubtract)) &&
|
||||||
|
(resultType->IsChar()) && (otherType->IsChar()))
|
||||||
{
|
{
|
||||||
// "wchar - char" subtraction will always fit into int32, because of unicode range
|
// "wchar - char" subtraction will always fit into int32, because of unicode range
|
||||||
resultType = mModule->GetPrimitiveType(BfTypeCode_Int32);
|
resultType = mModule->GetPrimitiveType(BfTypeCode_Int32);
|
||||||
explicitCast = true;
|
explicitCast = true;
|
||||||
}
|
}
|
||||||
else if ((otherType->IsChar()) &&
|
else if ((otherType->IsChar()) &&
|
||||||
((binaryOp == BfBinaryOp_Add) || (binaryOp == BfBinaryOp_Subtract)))
|
((binaryOp == BfBinaryOp_Add) || (binaryOp == BfBinaryOp_Subtract) || (binaryOp == BfBinaryOp_OverflowAdd) || (binaryOp == BfBinaryOp_OverflowSubtract)))
|
||||||
{
|
{
|
||||||
mModule->Fail(StrFormat("Cannot perform operation between types '%s' and '%s'",
|
mModule->Fail(StrFormat("Cannot perform operation between types '%s' and '%s'",
|
||||||
mModule->TypeToString(leftValue.mType).c_str(),
|
mModule->TypeToString(leftValue.mType).c_str(),
|
||||||
|
@ -22142,6 +22155,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convL
|
||||||
|
|
||||||
if ((resultType->IsChar()) &&
|
if ((resultType->IsChar()) &&
|
||||||
((binaryOp == BfBinaryOp_Multiply) ||
|
((binaryOp == BfBinaryOp_Multiply) ||
|
||||||
|
(binaryOp == BfBinaryOp_OverflowMultiply) ||
|
||||||
(binaryOp == BfBinaryOp_Divide) ||
|
(binaryOp == BfBinaryOp_Divide) ||
|
||||||
(binaryOp == BfBinaryOp_Modulus)))
|
(binaryOp == BfBinaryOp_Modulus)))
|
||||||
{
|
{
|
||||||
|
@ -22151,15 +22165,18 @@ void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convL
|
||||||
|
|
||||||
switch (binaryOp)
|
switch (binaryOp)
|
||||||
{
|
{
|
||||||
case BfBinaryOp_Add:
|
case BfBinaryOp_Add:
|
||||||
|
case BfBinaryOp_OverflowAdd:
|
||||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateAdd(convLeftValue, convRightValue), resultType);
|
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateAdd(convLeftValue, convRightValue), resultType);
|
||||||
mModule->CheckRangeError(resultType, opToken);
|
mModule->CheckRangeError(resultType, opToken);
|
||||||
break;
|
break;
|
||||||
case BfBinaryOp_Subtract:
|
case BfBinaryOp_Subtract:
|
||||||
|
case BfBinaryOp_OverflowSubtract:
|
||||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateSub(convLeftValue, convRightValue), resultType);
|
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateSub(convLeftValue, convRightValue), resultType);
|
||||||
mModule->CheckRangeError(resultType, opToken);
|
mModule->CheckRangeError(resultType, opToken);
|
||||||
break;
|
break;
|
||||||
case BfBinaryOp_Multiply:
|
case BfBinaryOp_Multiply:
|
||||||
|
case BfBinaryOp_OverflowMultiply:
|
||||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateMul(convLeftValue, convRightValue), resultType);
|
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateMul(convLeftValue, convRightValue), resultType);
|
||||||
mModule->CheckRangeError(resultType, opToken);
|
mModule->CheckRangeError(resultType, opToken);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -754,6 +754,15 @@ String BfGNUMangler::Mangle(BfMethodInstance* methodInst)
|
||||||
case BfBinaryOp_Multiply:
|
case BfBinaryOp_Multiply:
|
||||||
methodName = "ml";
|
methodName = "ml";
|
||||||
break;
|
break;
|
||||||
|
case BfBinaryOp_OverflowAdd:
|
||||||
|
methodName = "opl";
|
||||||
|
break;
|
||||||
|
case BfBinaryOp_OverflowSubtract:
|
||||||
|
methodName = "omi";
|
||||||
|
break;
|
||||||
|
case BfBinaryOp_OverflowMultiply:
|
||||||
|
methodName = "oml";
|
||||||
|
break;
|
||||||
case BfBinaryOp_Divide:
|
case BfBinaryOp_Divide:
|
||||||
methodName = "dv";
|
methodName = "dv";
|
||||||
break;
|
break;
|
||||||
|
@ -1872,6 +1881,15 @@ void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfMethodInstance* metho
|
||||||
case BfBinaryOp_Multiply:
|
case BfBinaryOp_Multiply:
|
||||||
name += "?D";
|
name += "?D";
|
||||||
break;
|
break;
|
||||||
|
case BfBinaryOp_OverflowAdd:
|
||||||
|
name += "?OH";
|
||||||
|
break;
|
||||||
|
case BfBinaryOp_OverflowSubtract:
|
||||||
|
name += "?OG";
|
||||||
|
break;
|
||||||
|
case BfBinaryOp_OverflowMultiply:
|
||||||
|
name += "?OD";
|
||||||
|
break;
|
||||||
case BfBinaryOp_Divide:
|
case BfBinaryOp_Divide:
|
||||||
name += "?K";
|
name += "?K";
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1549,6 +1549,21 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate)
|
||||||
mToken = BfToken_AndEquals;
|
mToken = BfToken_AndEquals;
|
||||||
mTokenEnd = ++mSrcIdx;
|
mTokenEnd = ++mSrcIdx;
|
||||||
}
|
}
|
||||||
|
else if (mSrc[mSrcIdx] == '+')
|
||||||
|
{
|
||||||
|
mToken = BfToken_AndPlus;
|
||||||
|
mTokenEnd = ++mSrcIdx;
|
||||||
|
}
|
||||||
|
else if (mSrc[mSrcIdx] == '-')
|
||||||
|
{
|
||||||
|
mToken = BfToken_AndMinus;
|
||||||
|
mTokenEnd = ++mSrcIdx;
|
||||||
|
}
|
||||||
|
else if (mSrc[mSrcIdx] == '*')
|
||||||
|
{
|
||||||
|
mToken = BfToken_AndStar;
|
||||||
|
mTokenEnd = ++mSrcIdx;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
mToken = BfToken_Ampersand;
|
mToken = BfToken_Ampersand;
|
||||||
mSyntaxToken = BfSyntaxToken_Token;
|
mSyntaxToken = BfSyntaxToken_Token;
|
||||||
|
|
|
@ -5975,13 +5975,13 @@ void DbgExprEvaluator::PerformBinaryOperation(ASTREF(BfExpression*)& leftExpress
|
||||||
|
|
||||||
// One pointer
|
// One pointer
|
||||||
if ((!otherType->IsInteger()) ||
|
if ((!otherType->IsInteger()) ||
|
||||||
((binaryOp != BfBinaryOp_Add) && (binaryOp != BfBinaryOp_Subtract) && (!isCompare)))
|
((binaryOp != BfBinaryOp_Add) && (binaryOp != BfBinaryOp_Subtract) && (binaryOp != BfBinaryOp_OverflowAdd) && (binaryOp != BfBinaryOp_OverflowSubtract) && (!isCompare)))
|
||||||
{
|
{
|
||||||
Fail("Can only add or subtract integer values from pointers", rightExpression);
|
Fail("Can only add or subtract integer values from pointers", rightExpression);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((binaryOp == BfBinaryOp_Add) || (binaryOp == BfBinaryOp_Subtract))
|
if ((binaryOp == BfBinaryOp_Add) || (binaryOp == BfBinaryOp_Subtract) || (binaryOp == BfBinaryOp_OverflowAdd) || (binaryOp == BfBinaryOp_OverflowSubtract))
|
||||||
{
|
{
|
||||||
auto underlyingType = otherType->GetUnderlyingType();
|
auto underlyingType = otherType->GetUnderlyingType();
|
||||||
mResult.mType = resultType;
|
mResult.mType = resultType;
|
||||||
|
@ -6262,6 +6262,7 @@ void DbgExprEvaluator::PerformBinaryOperation(DbgType* resultType, DbgTypedValue
|
||||||
switch (binaryOp)
|
switch (binaryOp)
|
||||||
{
|
{
|
||||||
case BfBinaryOp_Add:
|
case BfBinaryOp_Add:
|
||||||
|
case BfBinaryOp_OverflowAdd:
|
||||||
if (resultType->mTypeCode == DbgType_Single)
|
if (resultType->mTypeCode == DbgType_Single)
|
||||||
mResult.mSingle = convLeftValue.mSingle + convRightValue.mSingle;
|
mResult.mSingle = convLeftValue.mSingle + convRightValue.mSingle;
|
||||||
else if (resultType->mTypeCode == DbgType_Double)
|
else if (resultType->mTypeCode == DbgType_Double)
|
||||||
|
@ -6270,6 +6271,7 @@ void DbgExprEvaluator::PerformBinaryOperation(DbgType* resultType, DbgTypedValue
|
||||||
mResult.mInt64 = convLeftValue.GetInt64() + convRightValue.GetInt64();
|
mResult.mInt64 = convLeftValue.GetInt64() + convRightValue.GetInt64();
|
||||||
break;
|
break;
|
||||||
case BfBinaryOp_Subtract:
|
case BfBinaryOp_Subtract:
|
||||||
|
case BfBinaryOp_OverflowSubtract:
|
||||||
if (resultType->mTypeCode == DbgType_Single)
|
if (resultType->mTypeCode == DbgType_Single)
|
||||||
mResult.mSingle = convLeftValue.mSingle - convRightValue.mSingle;
|
mResult.mSingle = convLeftValue.mSingle - convRightValue.mSingle;
|
||||||
else if (resultType->mTypeCode == DbgType_Double)
|
else if (resultType->mTypeCode == DbgType_Double)
|
||||||
|
@ -6278,6 +6280,7 @@ void DbgExprEvaluator::PerformBinaryOperation(DbgType* resultType, DbgTypedValue
|
||||||
mResult.mInt64 = convLeftValue.GetInt64() - convRightValue.GetInt64();
|
mResult.mInt64 = convLeftValue.GetInt64() - convRightValue.GetInt64();
|
||||||
break;
|
break;
|
||||||
case BfBinaryOp_Multiply:
|
case BfBinaryOp_Multiply:
|
||||||
|
case BfBinaryOp_OverflowMultiply:
|
||||||
if (resultType->mTypeCode == DbgType_Single)
|
if (resultType->mTypeCode == DbgType_Single)
|
||||||
mResult.mSingle = convLeftValue.mSingle * convRightValue.mSingle;
|
mResult.mSingle = convLeftValue.mSingle * convRightValue.mSingle;
|
||||||
else if (resultType->mTypeCode == DbgType_Double)
|
else if (resultType->mTypeCode == DbgType_Double)
|
||||||
|
|
|
@ -198,6 +198,41 @@ namespace Tests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct StructH
|
||||||
|
{
|
||||||
|
public static int operator+(StructH lhs, int rhs)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int operator+(int lhs, StructH rhs)
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Commutable]
|
||||||
|
public static int operator+(StructH lhs, float rhs)
|
||||||
|
{
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int operator&+(StructH lhs, int rhs)
|
||||||
|
{
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int operator&+(int lhs, StructH rhs)
|
||||||
|
{
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Commutable]
|
||||||
|
public static int operator&+(StructH lhs, float rhs)
|
||||||
|
{
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct StructOp<T, T2> where T : operator T + T2
|
struct StructOp<T, T2> where T : operator T + T2
|
||||||
{
|
{
|
||||||
public T DoIt(T val, T2 val2)
|
public T DoIt(T val, T2 val2)
|
||||||
|
@ -428,6 +463,20 @@ namespace Tests
|
||||||
Test.Assert(10 + sf == 2);
|
Test.Assert(10 + sf == 2);
|
||||||
Test.Assert(sf + 1.0f == 3);
|
Test.Assert(sf + 1.0f == 3);
|
||||||
Test.Assert(2.0f + sf == 3);
|
Test.Assert(2.0f + sf == 3);
|
||||||
|
Test.Assert(sf &+ 10 == 1);
|
||||||
|
Test.Assert(10 &+ sf == 2);
|
||||||
|
Test.Assert(sf &+ 1.0f == 3);
|
||||||
|
Test.Assert(2.0f &+ sf == 3);
|
||||||
|
|
||||||
|
StructH sh = default;
|
||||||
|
Test.Assert(sh + 10 == 1);
|
||||||
|
Test.Assert(10 + sh == 2);
|
||||||
|
Test.Assert(sh + 1.0f == 3);
|
||||||
|
Test.Assert(2.0f + sh == 3);
|
||||||
|
Test.Assert(sh &+ 10 == 4);
|
||||||
|
Test.Assert(10 &+ sh == 5);
|
||||||
|
Test.Assert(sh &+ 1.0f == 6);
|
||||||
|
Test.Assert(2.0f &+ sh == 6);
|
||||||
|
|
||||||
StructG sg = .(100);
|
StructG sg = .(100);
|
||||||
StructG sg2 = .(200);
|
StructG sg2 = .(200);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue