mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 19:48:20 +02:00
Added concept of strict equality
This commit is contained in:
parent
308605a7dd
commit
abeda6909b
13 changed files with 249 additions and 79 deletions
|
@ -420,14 +420,6 @@ namespace System.Collections
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int LastIndexOf(T item)
|
|
||||||
{
|
|
||||||
for (int i = mSize - 1; i >= 0; i--)
|
|
||||||
if (mItems[i] == item)
|
|
||||||
return i;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int IndexOf(T item, int index)
|
public int IndexOf(T item, int index)
|
||||||
{
|
{
|
||||||
for (int i = index; i < mSize; i++)
|
for (int i = index; i < mSize; i++)
|
||||||
|
@ -444,6 +436,46 @@ namespace System.Collections
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int IndexOfStrict(T item)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < mSize; i++)
|
||||||
|
if (mItems[i] === item)
|
||||||
|
return i;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int IndexOfStrict(T item, int index)
|
||||||
|
{
|
||||||
|
for (int i = index; i < mSize; i++)
|
||||||
|
if (mItems[i] === item)
|
||||||
|
return i;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int IndexOfStrict(T item, int index, int count)
|
||||||
|
{
|
||||||
|
for (int i = index; i < index + count; i++)
|
||||||
|
if (mItems[i] === item)
|
||||||
|
return i;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int LastIndexOf(T item)
|
||||||
|
{
|
||||||
|
for (int i = mSize - 1; i >= 0; i--)
|
||||||
|
if (mItems[i] == item)
|
||||||
|
return i;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int LastIndexOfStrict(T item)
|
||||||
|
{
|
||||||
|
for (int i = mSize - 1; i >= 0; i--)
|
||||||
|
if (mItems[i] === item)
|
||||||
|
return i;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
public void Insert(int index, T item)
|
public void Insert(int index, T item)
|
||||||
{
|
{
|
||||||
var item; // This creates a copy - required if item is a ref to an element
|
var item; // This creates a copy - required if item is a ref to an element
|
||||||
|
@ -577,6 +609,31 @@ namespace System.Collections
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool RemoveStrict(T item)
|
||||||
|
{
|
||||||
|
int index = IndexOfStrict(item);
|
||||||
|
if (index >= 0)
|
||||||
|
{
|
||||||
|
RemoveAt(index);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result<T> GetAndRemove(T item)
|
||||||
|
{
|
||||||
|
int index = IndexOf(item);
|
||||||
|
if (index >= 0)
|
||||||
|
{
|
||||||
|
T val = mItems[index];
|
||||||
|
RemoveAt(index);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
return .Err;
|
||||||
|
}
|
||||||
|
|
||||||
/// The method returns the index of the given value in the list. If the
|
/// The method returns the index of the given value in the list. If the
|
||||||
/// list does not contain the given value, the method returns a negative
|
/// list does not contain the given value, the method returns a negative
|
||||||
/// integer. The bitwise complement operator (~) can be applied to a
|
/// integer. The bitwise complement operator (~) can be applied to a
|
||||||
|
|
|
@ -147,6 +147,22 @@ namespace System
|
||||||
mLength = 0;
|
mLength = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int IndexOf(T item)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < mLength; i++)
|
||||||
|
if (mPtr[i] == item)
|
||||||
|
return i;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int IndexOfStrict(T item)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < mLength; i++)
|
||||||
|
if (mPtr[i] === item)
|
||||||
|
return i;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
public void RemoveFromStart(int length) mut
|
public void RemoveFromStart(int length) mut
|
||||||
{
|
{
|
||||||
Debug.Assert((uint)length <= (uint)mLength);
|
Debug.Assert((uint)length <= (uint)mLength);
|
||||||
|
|
|
@ -328,8 +328,8 @@ namespace IDE.Compiler
|
||||||
if (oldIdx <= expectedOldIdx)
|
if (oldIdx <= expectedOldIdx)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
Utils.WriteTextFile(@"c:\temp\old.txt", oldText);
|
Utils.WriteTextFile(@"c:\temp\old.txt", oldText).IgnoreError();
|
||||||
Utils.WriteTextFile(@"c:\temp\new.txt", newText);
|
Utils.WriteTextFile(@"c:\temp\new.txt", newText).IgnoreError();
|
||||||
Debug.FatalError("Reformat failed");
|
Debug.FatalError("Reformat failed");
|
||||||
#endif
|
#endif
|
||||||
break; // Error - abort
|
break; // Error - abort
|
||||||
|
|
|
@ -1303,6 +1303,8 @@ const char* Beefy::BfTokenToString(BfToken token)
|
||||||
return "mixin";
|
return "mixin";
|
||||||
case BfToken_Mut:
|
case BfToken_Mut:
|
||||||
return "mut";
|
return "mut";
|
||||||
|
case BfToken_NameOf:
|
||||||
|
return "nameof";
|
||||||
case BfToken_Namespace:
|
case BfToken_Namespace:
|
||||||
return "namespace";
|
return "namespace";
|
||||||
case BfToken_New:
|
case BfToken_New:
|
||||||
|
@ -1385,8 +1387,12 @@ const char* Beefy::BfTokenToString(BfToken token)
|
||||||
return "=";
|
return "=";
|
||||||
case BfToken_CompareEquals:
|
case BfToken_CompareEquals:
|
||||||
return "==";
|
return "==";
|
||||||
|
case BfToken_CompareStrictEquals:
|
||||||
|
return "===";
|
||||||
case BfToken_CompareNotEquals:
|
case BfToken_CompareNotEquals:
|
||||||
return "!=";
|
return "!=";
|
||||||
|
case BfToken_CompareStrictNotEquals:
|
||||||
|
return "!==";
|
||||||
case BfToken_LessEquals:
|
case BfToken_LessEquals:
|
||||||
return "<=";
|
return "<=";
|
||||||
case BfToken_GreaterEquals:
|
case BfToken_GreaterEquals:
|
||||||
|
@ -1559,7 +1565,9 @@ int Beefy::BfGetBinaryOpPrecendence(BfBinaryOp binOp)
|
||||||
case BfBinaryOp_LessThanOrEqual:
|
case BfBinaryOp_LessThanOrEqual:
|
||||||
return 5;
|
return 5;
|
||||||
case BfBinaryOp_Equality:
|
case BfBinaryOp_Equality:
|
||||||
|
case BfBinaryOp_StrictEquality:
|
||||||
case BfBinaryOp_InEquality:
|
case BfBinaryOp_InEquality:
|
||||||
|
case BfBinaryOp_StrictInEquality:
|
||||||
return 4;
|
return 4;
|
||||||
case BfBinaryOp_ConditionalAnd:
|
case BfBinaryOp_ConditionalAnd:
|
||||||
return 3;
|
return 3;
|
||||||
|
@ -1590,7 +1598,9 @@ const char* Beefy::BfGetOpName(BfBinaryOp binOp)
|
||||||
case BfBinaryOp_LeftShift: return "<<";
|
case BfBinaryOp_LeftShift: return "<<";
|
||||||
case BfBinaryOp_RightShift: return ">>";
|
case BfBinaryOp_RightShift: return ">>";
|
||||||
case BfBinaryOp_Equality: return "==";
|
case BfBinaryOp_Equality: return "==";
|
||||||
|
case BfBinaryOp_StrictEquality: return "===";
|
||||||
case BfBinaryOp_InEquality: return "!=";
|
case BfBinaryOp_InEquality: return "!=";
|
||||||
|
case BfBinaryOp_StrictInEquality: return "!==";
|
||||||
case BfBinaryOp_GreaterThan: return ">";
|
case BfBinaryOp_GreaterThan: return ">";
|
||||||
case BfBinaryOp_LessThan: return "<";
|
case BfBinaryOp_LessThan: return "<";
|
||||||
case BfBinaryOp_GreaterThanOrEqual: return ">=";
|
case BfBinaryOp_GreaterThanOrEqual: return ">=";
|
||||||
|
@ -1655,8 +1665,12 @@ BfBinaryOp Beefy::BfTokenToBinaryOp(BfToken token)
|
||||||
return BfBinaryOp_RightShift;
|
return BfBinaryOp_RightShift;
|
||||||
case BfToken_CompareEquals:
|
case BfToken_CompareEquals:
|
||||||
return BfBinaryOp_Equality;
|
return BfBinaryOp_Equality;
|
||||||
|
case BfToken_CompareStrictEquals:
|
||||||
|
return BfBinaryOp_StrictEquality;
|
||||||
case BfToken_CompareNotEquals:
|
case BfToken_CompareNotEquals:
|
||||||
return BfBinaryOp_InEquality;
|
return BfBinaryOp_InEquality;
|
||||||
|
case BfToken_CompareStrictNotEquals:
|
||||||
|
return BfBinaryOp_StrictInEquality;
|
||||||
case BfToken_RChevron:
|
case BfToken_RChevron:
|
||||||
return BfBinaryOp_GreaterThan;
|
return BfBinaryOp_GreaterThan;
|
||||||
case BfToken_LChevron:
|
case BfToken_LChevron:
|
||||||
|
@ -1770,8 +1784,12 @@ BfBinaryOp Beefy::BfGetOppositeBinaryOp(BfBinaryOp origOp)
|
||||||
{
|
{
|
||||||
case BfBinaryOp_Equality:
|
case BfBinaryOp_Equality:
|
||||||
return BfBinaryOp_InEquality;
|
return BfBinaryOp_InEquality;
|
||||||
|
case BfBinaryOp_StrictEquality:
|
||||||
|
return BfBinaryOp_StrictInEquality;
|
||||||
case BfBinaryOp_InEquality:
|
case BfBinaryOp_InEquality:
|
||||||
return BfBinaryOp_Equality;
|
return BfBinaryOp_Equality;
|
||||||
|
case BfBinaryOp_StrictInEquality:
|
||||||
|
return BfBinaryOp_StrictEquality;
|
||||||
case BfBinaryOp_LessThan:
|
case BfBinaryOp_LessThan:
|
||||||
return BfBinaryOp_GreaterThanOrEqual;
|
return BfBinaryOp_GreaterThanOrEqual;
|
||||||
case BfBinaryOp_LessThanOrEqual:
|
case BfBinaryOp_LessThanOrEqual:
|
||||||
|
@ -1808,6 +1826,11 @@ BfBinaryOp Beefy::BfGetFlippedBinaryOp(BfBinaryOp origOp)
|
||||||
return BfBinaryOp_None;
|
return BfBinaryOp_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Beefy::BfBinOpEqualityCheck(BfBinaryOp binOp)
|
||||||
|
{
|
||||||
|
return (binOp >= BfBinaryOp_Equality) && (binOp <= BfBinaryOp_StrictInEquality);
|
||||||
|
}
|
||||||
|
|
||||||
bool Beefy::BfIsCommentBlock(BfCommentKind commentKind)
|
bool Beefy::BfIsCommentBlock(BfCommentKind commentKind)
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
|
|
|
@ -146,6 +146,7 @@ enum BfToken : uint8
|
||||||
BfToken_Let,
|
BfToken_Let,
|
||||||
BfToken_Mixin,
|
BfToken_Mixin,
|
||||||
BfToken_Mut,
|
BfToken_Mut,
|
||||||
|
BfToken_NameOf,
|
||||||
BfToken_Namespace,
|
BfToken_Namespace,
|
||||||
BfToken_New,
|
BfToken_New,
|
||||||
BfToken_Null,
|
BfToken_Null,
|
||||||
|
@ -187,7 +188,9 @@ enum BfToken : uint8
|
||||||
BfToken_Yield,
|
BfToken_Yield,
|
||||||
BfToken_AssignEquals,
|
BfToken_AssignEquals,
|
||||||
BfToken_CompareEquals,
|
BfToken_CompareEquals,
|
||||||
|
BfToken_CompareStrictEquals,
|
||||||
BfToken_CompareNotEquals,
|
BfToken_CompareNotEquals,
|
||||||
|
BfToken_CompareStrictNotEquals,
|
||||||
BfToken_LessEquals,
|
BfToken_LessEquals,
|
||||||
BfToken_GreaterEquals,
|
BfToken_GreaterEquals,
|
||||||
BfToken_Spaceship,
|
BfToken_Spaceship,
|
||||||
|
@ -1706,7 +1709,9 @@ enum BfBinaryOp
|
||||||
BfBinaryOp_LeftShift,
|
BfBinaryOp_LeftShift,
|
||||||
BfBinaryOp_RightShift,
|
BfBinaryOp_RightShift,
|
||||||
BfBinaryOp_Equality,
|
BfBinaryOp_Equality,
|
||||||
|
BfBinaryOp_StrictEquality,
|
||||||
BfBinaryOp_InEquality,
|
BfBinaryOp_InEquality,
|
||||||
|
BfBinaryOp_StrictInEquality,
|
||||||
BfBinaryOp_GreaterThan,
|
BfBinaryOp_GreaterThan,
|
||||||
BfBinaryOp_LessThan,
|
BfBinaryOp_LessThan,
|
||||||
BfBinaryOp_GreaterThanOrEqual,
|
BfBinaryOp_GreaterThanOrEqual,
|
||||||
|
@ -3199,6 +3204,7 @@ bool BfTokenIsKeyword(BfToken token);
|
||||||
BfBinaryOp BfAssignOpToBinaryOp(BfAssignmentOp assignmentOp);
|
BfBinaryOp BfAssignOpToBinaryOp(BfAssignmentOp assignmentOp);
|
||||||
BfBinaryOp BfGetOppositeBinaryOp(BfBinaryOp origOp);
|
BfBinaryOp BfGetOppositeBinaryOp(BfBinaryOp origOp);
|
||||||
BfBinaryOp BfGetFlippedBinaryOp(BfBinaryOp origOp);
|
BfBinaryOp BfGetFlippedBinaryOp(BfBinaryOp origOp);
|
||||||
|
bool BfBinOpEqualityCheck(BfBinaryOp binOp);
|
||||||
int BfGetBinaryOpPrecendence(BfBinaryOp binOp);
|
int BfGetBinaryOpPrecendence(BfBinaryOp binOp);
|
||||||
const char* BfGetOpName(BfBinaryOp binOp);
|
const char* BfGetOpName(BfBinaryOp binOp);
|
||||||
const char* BfGetOpName(BfUnaryOp unaryOp);
|
const char* BfGetOpName(BfUnaryOp unaryOp);
|
||||||
|
|
|
@ -2061,6 +2061,19 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
||||||
AddParam(methodDef, mSystem->mDirectSelfTypeRef, "rhs");
|
AddParam(methodDef, mSystem->mDirectSelfTypeRef, "rhs");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (needsEqualsMethod)
|
||||||
|
{
|
||||||
|
auto methodDef = new BfMethodDef();
|
||||||
|
mCurTypeDef->mMethods.push_back(methodDef);
|
||||||
|
methodDef->mDeclaringType = mCurTypeDef;
|
||||||
|
methodDef->mName = BF_METHODNAME_DEFAULT_STRICT_EQUALS;
|
||||||
|
methodDef->mReturnTypeRef = mSystem->mDirectBoolTypeRef;
|
||||||
|
methodDef->mProtection = BfProtection_Private;
|
||||||
|
methodDef->mIsStatic = true;
|
||||||
|
AddParam(methodDef, mSystem->mDirectSelfTypeRef, "lhs");
|
||||||
|
AddParam(methodDef, mSystem->mDirectSelfTypeRef, "rhs");
|
||||||
|
}
|
||||||
|
|
||||||
HashContext inlineHashCtx;
|
HashContext inlineHashCtx;
|
||||||
|
|
||||||
if (mCurSource != NULL)
|
if (mCurSource != NULL)
|
||||||
|
|
|
@ -18009,10 +18009,12 @@ bool BfExprEvaluator::CheckConstCompare(BfBinaryOp binaryOp, BfAstNode* opToken,
|
||||||
switch (binaryOp)
|
switch (binaryOp)
|
||||||
{
|
{
|
||||||
case BfBinaryOp_Equality:
|
case BfBinaryOp_Equality:
|
||||||
|
case BfBinaryOp_StrictEquality:
|
||||||
if (rightConst->mInt64 < minValue)
|
if (rightConst->mInt64 < minValue)
|
||||||
constResult = 0;
|
constResult = 0;
|
||||||
break;
|
break;
|
||||||
case BfBinaryOp_InEquality:
|
case BfBinaryOp_InEquality:
|
||||||
|
case BfBinaryOp_StrictInEquality:
|
||||||
if (rightConst->mInt64 < minValue)
|
if (rightConst->mInt64 < minValue)
|
||||||
constResult = 1;
|
constResult = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -18033,12 +18035,14 @@ bool BfExprEvaluator::CheckConstCompare(BfBinaryOp binaryOp, BfAstNode* opToken,
|
||||||
switch (binaryOp)
|
switch (binaryOp)
|
||||||
{
|
{
|
||||||
case BfBinaryOp_Equality:
|
case BfBinaryOp_Equality:
|
||||||
|
case BfBinaryOp_StrictEquality:
|
||||||
if (rightConst->mInt64 < minValue)
|
if (rightConst->mInt64 < minValue)
|
||||||
constResult = 0;
|
constResult = 0;
|
||||||
else if (rightConst->mInt64 > maxValue)
|
else if (rightConst->mInt64 > maxValue)
|
||||||
constResult = 0;
|
constResult = 0;
|
||||||
break;
|
break;
|
||||||
case BfBinaryOp_InEquality:
|
case BfBinaryOp_InEquality:
|
||||||
|
case BfBinaryOp_StrictInEquality:
|
||||||
if (rightConst->mInt64 < minValue)
|
if (rightConst->mInt64 < minValue)
|
||||||
constResult = 1;
|
constResult = 1;
|
||||||
else if (rightConst->mInt64 > maxValue)
|
else if (rightConst->mInt64 > maxValue)
|
||||||
|
@ -18332,7 +18336,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
};
|
};
|
||||||
|
|
||||||
// This case fixes cases like "c == 0" where "0" is technically an int but can be reduced
|
// This case fixes cases like "c == 0" where "0" is technically an int but can be reduced
|
||||||
if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_InEquality))
|
if (BfBinOpEqualityCheck(binaryOp))
|
||||||
{
|
{
|
||||||
if ((resultType != otherType) && (resultTypedValue->mValue.IsConst()) && (mModule->CanCast(*resultTypedValue, otherType)))
|
if ((resultType != otherType) && (resultTypedValue->mValue.IsConst()) && (mModule->CanCast(*resultTypedValue, otherType)))
|
||||||
{
|
{
|
||||||
|
@ -18351,9 +18355,9 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((otherType->IsNull()) && ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_InEquality)))
|
if ((otherType->IsNull()) && (BfBinOpEqualityCheck(binaryOp)))
|
||||||
{
|
{
|
||||||
bool isEquality = (binaryOp == BfBinaryOp_Equality);
|
bool isEquality = (binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality);
|
||||||
|
|
||||||
if ((resultType->IsValueType()) && (!resultType->IsFunction()))
|
if ((resultType->IsValueType()) && (!resultType->IsFunction()))
|
||||||
{
|
{
|
||||||
|
@ -18408,7 +18412,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for constant equality checks (mostly for strings)
|
// Check for constant equality checks (mostly for strings)
|
||||||
if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_InEquality))
|
if (BfBinOpEqualityCheck(binaryOp))
|
||||||
{
|
{
|
||||||
auto leftConstant = mModule->mBfIRBuilder->GetConstant(leftValue.mValue);
|
auto leftConstant = mModule->mBfIRBuilder->GetConstant(leftValue.mValue);
|
||||||
auto rightConstant = mModule->mBfIRBuilder->GetConstant(rightValue.mValue);
|
auto rightConstant = mModule->mBfIRBuilder->GetConstant(rightValue.mValue);
|
||||||
|
@ -18423,7 +18427,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
if (rightStringPoolIdx != -1)
|
if (rightStringPoolIdx != -1)
|
||||||
{
|
{
|
||||||
bool isEqual = leftStringPoolIdx == rightStringPoolIdx;
|
bool isEqual = leftStringPoolIdx == rightStringPoolIdx;
|
||||||
if (binaryOp == BfBinaryOp_InEquality)
|
if ((binaryOp == BfBinaryOp_InEquality) || (binaryOp == BfBinaryOp_StrictInEquality))
|
||||||
isEqual = !isEqual;
|
isEqual = !isEqual;
|
||||||
mResult = BfTypedValue(mModule->GetConstValue(isEqual ? 1 : 0, boolType), boolType);
|
mResult = BfTypedValue(mModule->GetConstValue(isEqual ? 1 : 0, boolType), boolType);
|
||||||
return;
|
return;
|
||||||
|
@ -18434,7 +18438,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
if (eqResult != -1)
|
if (eqResult != -1)
|
||||||
{
|
{
|
||||||
bool isEqual = eqResult == 1;
|
bool isEqual = eqResult == 1;
|
||||||
if (binaryOp == BfBinaryOp_InEquality)
|
if ((binaryOp == BfBinaryOp_InEquality) || (binaryOp == BfBinaryOp_StrictInEquality))
|
||||||
isEqual = !isEqual;
|
isEqual = !isEqual;
|
||||||
mResult = BfTypedValue(mModule->GetConstValue(isEqual ? 1 : 0, boolType), boolType);
|
mResult = BfTypedValue(mModule->GetConstValue(isEqual ? 1 : 0, boolType), boolType);
|
||||||
return;
|
return;
|
||||||
|
@ -18447,7 +18451,9 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
{
|
{
|
||||||
// As an optimization, we don't call user operator overloads for null checks
|
// As an optimization, we don't call user operator overloads for null checks
|
||||||
bool skipOpOverload = false;
|
bool skipOpOverload = false;
|
||||||
if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_InEquality))
|
if ((binaryOp == BfBinaryOp_StrictEquality) || (binaryOp == BfBinaryOp_StrictInEquality))
|
||||||
|
skipOpOverload = true;
|
||||||
|
else if (BfBinOpEqualityCheck(binaryOp))
|
||||||
{
|
{
|
||||||
auto leftConstant = mModule->mBfIRBuilder->GetConstant(leftValue.mValue);
|
auto leftConstant = mModule->mBfIRBuilder->GetConstant(leftValue.mValue);
|
||||||
auto rightConstant = mModule->mBfIRBuilder->GetConstant(rightValue.mValue);
|
auto rightConstant = mModule->mBfIRBuilder->GetConstant(rightValue.mValue);
|
||||||
|
@ -18456,7 +18462,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
skipOpOverload = true;
|
skipOpOverload = true;
|
||||||
if ((rightConstant != NULL) && (rightConstant->IsNull()))
|
if ((rightConstant != NULL) && (rightConstant->IsNull()))
|
||||||
skipOpOverload = true;
|
skipOpOverload = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!skipOpOverload)
|
if (!skipOpOverload)
|
||||||
{
|
{
|
||||||
|
@ -18593,9 +18599,11 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
switch (useBinaryOp)
|
switch (useBinaryOp)
|
||||||
{
|
{
|
||||||
case BfBinaryOp_Equality:
|
case BfBinaryOp_Equality:
|
||||||
|
case BfBinaryOp_StrictEquality:
|
||||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(mResult.mValue, zeroVal), boolType);
|
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(mResult.mValue, zeroVal), boolType);
|
||||||
break;
|
break;
|
||||||
case BfBinaryOp_InEquality:
|
case BfBinaryOp_InEquality:
|
||||||
|
case BfBinaryOp_StrictInEquality:
|
||||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpNE(mResult.mValue, zeroVal), boolType);
|
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpNE(mResult.mValue, zeroVal), boolType);
|
||||||
break;
|
break;
|
||||||
case BfBinaryOp_GreaterThan:
|
case BfBinaryOp_GreaterThan:
|
||||||
|
@ -18665,9 +18673,11 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
break;
|
break;
|
||||||
|
|
||||||
switch (findBinaryOp)
|
switch (findBinaryOp)
|
||||||
{
|
{
|
||||||
case BfBinaryOp_Equality:
|
case BfBinaryOp_Equality:
|
||||||
case BfBinaryOp_InEquality:
|
case BfBinaryOp_StrictEquality:
|
||||||
|
case BfBinaryOp_InEquality:
|
||||||
|
case BfBinaryOp_StrictInEquality:
|
||||||
case BfBinaryOp_Compare:
|
case BfBinaryOp_Compare:
|
||||||
// Still works
|
// Still works
|
||||||
break;
|
break;
|
||||||
|
@ -18729,7 +18739,8 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
mResult = BfTypedValue(diffValue, intPtrType);
|
mResult = BfTypedValue(diffValue, intPtrType);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if ((binaryOp != BfBinaryOp_Equality) && (binaryOp != BfBinaryOp_InEquality) &&
|
else if ((binaryOp != BfBinaryOp_Equality) && (binaryOp != BfBinaryOp_StrictEquality) &&
|
||||||
|
(binaryOp != BfBinaryOp_InEquality) && (binaryOp != BfBinaryOp_StrictInEquality) &&
|
||||||
(binaryOp != BfBinaryOp_LessThan) && (binaryOp != BfBinaryOp_LessThanOrEqual) &&
|
(binaryOp != BfBinaryOp_LessThan) && (binaryOp != BfBinaryOp_LessThanOrEqual) &&
|
||||||
(binaryOp != BfBinaryOp_GreaterThan) && (binaryOp != BfBinaryOp_GreaterThanOrEqual))
|
(binaryOp != BfBinaryOp_GreaterThan) && (binaryOp != BfBinaryOp_GreaterThanOrEqual))
|
||||||
{
|
{
|
||||||
|
@ -18737,8 +18748,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((binaryOp != BfBinaryOp_Equality) && (binaryOp != BfBinaryOp_InEquality)) ||
|
if ((!BfBinOpEqualityCheck(binaryOp)) || (resultType != otherType))
|
||||||
(resultType != otherType))
|
|
||||||
{
|
{
|
||||||
resultType = mModule->GetPrimitiveType(BfTypeCode_UIntPtr);
|
resultType = mModule->GetPrimitiveType(BfTypeCode_UIntPtr);
|
||||||
explicitCast = true;
|
explicitCast = true;
|
||||||
|
@ -18748,13 +18758,13 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
{
|
{
|
||||||
if (otherType->IsNull())
|
if (otherType->IsNull())
|
||||||
{
|
{
|
||||||
if ((binaryOp != BfBinaryOp_Equality) && (binaryOp != BfBinaryOp_InEquality))
|
if (!BfBinOpEqualityCheck(binaryOp))
|
||||||
{
|
{
|
||||||
mModule->Fail(StrFormat("Invalid operation between '%s' and null", mModule->TypeToString(resultType).c_str()), opToken);
|
mModule->Fail(StrFormat("Invalid operation between '%s' and null", mModule->TypeToString(resultType).c_str()), opToken);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (binaryOp == BfBinaryOp_Equality)
|
if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality))
|
||||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateIsNull(resultTypedValue->mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
|
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateIsNull(resultTypedValue->mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
|
||||||
else
|
else
|
||||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateIsNotNull(resultTypedValue->mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
|
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateIsNotNull(resultTypedValue->mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
|
||||||
|
@ -18796,9 +18806,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
mResult = BfTypedValue(mModule->CreateIndexedValue(underlyingType, resultTypedValue->mValue, addValue), resultType);
|
mResult = BfTypedValue(mModule->CreateIndexedValue(underlyingType, resultTypedValue->mValue, addValue), resultType);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if ((resultType->IsFunction()) || (resultType->IsPointer()) || (resultType->IsObject()) || (resultType->IsInterface()) || (resultType->IsGenericParam()))
|
if ((resultType->IsFunction()) || (resultType->IsPointer()) || (resultType->IsObject()) || (resultType->IsInterface()) || (resultType->IsGenericParam()))
|
||||||
{
|
{
|
||||||
if ((binaryOp == BfBinaryOp_Add) &&
|
if ((binaryOp == BfBinaryOp_Add) &&
|
||||||
|
@ -18809,7 +18817,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((binaryOp != BfBinaryOp_Equality) && (binaryOp != BfBinaryOp_InEquality))
|
if (!BfGetBinaryOpPrecendence(binaryOp))
|
||||||
{
|
{
|
||||||
//mModule->Fail("Invalid operation for objects", opToken);
|
//mModule->Fail("Invalid operation for objects", opToken);
|
||||||
_OpFail();
|
_OpFail();
|
||||||
|
@ -18827,14 +18835,14 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
{
|
{
|
||||||
if (resultType->IsFunction())
|
if (resultType->IsFunction())
|
||||||
{
|
{
|
||||||
if (binaryOp == BfBinaryOp_Equality)
|
if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality))
|
||||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0), resultTypedValue->mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
|
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0), resultTypedValue->mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
|
||||||
else
|
else
|
||||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpNE(mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0), resultTypedValue->mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
|
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpNE(mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0), resultTypedValue->mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (binaryOp == BfBinaryOp_Equality)
|
if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality))
|
||||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateIsNull(resultTypedValue->mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
|
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateIsNull(resultTypedValue->mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
|
||||||
else
|
else
|
||||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateIsNotNull(resultTypedValue->mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
|
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateIsNotNull(resultTypedValue->mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
|
||||||
|
@ -18845,7 +18853,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
auto convertedValue = mModule->CastToValue(otherTypeSrc, *otherTypedValue, resultType, BfCastFlags_NoBox);
|
auto convertedValue = mModule->CastToValue(otherTypeSrc, *otherTypedValue, resultType, BfCastFlags_NoBox);
|
||||||
if (!convertedValue)
|
if (!convertedValue)
|
||||||
return;
|
return;
|
||||||
if (binaryOp == BfBinaryOp_Equality)
|
if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality))
|
||||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(resultTypedValue->mValue, convertedValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
|
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(resultTypedValue->mValue, convertedValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
|
||||||
else
|
else
|
||||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpNE(resultTypedValue->mValue, convertedValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
|
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpNE(resultTypedValue->mValue, convertedValue), mModule->GetPrimitiveType(BfTypeCode_Boolean));
|
||||||
|
@ -18909,7 +18917,10 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
auto typeInst = leftValue.mType->ToTypeInstance();
|
auto typeInst = leftValue.mType->ToTypeInstance();
|
||||||
if (typeInst != NULL)
|
if (typeInst != NULL)
|
||||||
{
|
{
|
||||||
moduleMethodInstance = mModule->GetMethodByName(typeInst, BF_METHODNAME_DEFAULT_EQUALS);
|
if ((binaryOp == BfBinaryOp_StrictEquality) || (binaryOp == BfBinaryOp_StrictInEquality))
|
||||||
|
moduleMethodInstance = mModule->GetMethodByName(typeInst, BF_METHODNAME_DEFAULT_STRICT_EQUALS);
|
||||||
|
else
|
||||||
|
moduleMethodInstance = mModule->GetMethodByName(typeInst, BF_METHODNAME_DEFAULT_EQUALS);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -18933,7 +18944,8 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
resolvedArg.mTypedValue = rightValue;
|
resolvedArg.mTypedValue = rightValue;
|
||||||
argValues.push_back(resolvedArg);
|
argValues.push_back(resolvedArg);
|
||||||
mResult = CreateCall(opToken, BfTypedValue(), BfTypedValue(), moduleMethodInstance.mMethodInstance->mMethodDef, moduleMethodInstance, false, argValues);
|
mResult = CreateCall(opToken, BfTypedValue(), BfTypedValue(), moduleMethodInstance.mMethodInstance->mMethodDef, moduleMethodInstance, false, argValues);
|
||||||
if ((mResult) && (binaryOp == BfBinaryOp_InEquality))
|
if ((mResult) &&
|
||||||
|
((binaryOp == BfBinaryOp_InEquality) || (binaryOp == BfBinaryOp_StrictInEquality)))
|
||||||
mResult.mValue = mModule->mBfIRBuilder->CreateNot(mResult.mValue);
|
mResult.mValue = mModule->mBfIRBuilder->CreateNot(mResult.mValue);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -18961,7 +18973,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
|
|
||||||
if (leftValue.mType == rightValue.mType)
|
if (leftValue.mType == rightValue.mType)
|
||||||
{
|
{
|
||||||
if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_InEquality))
|
if (BfBinOpEqualityCheck(binaryOp))
|
||||||
{
|
{
|
||||||
auto intCoercibleType = mModule->GetIntCoercibleType(leftValue.mType);
|
auto intCoercibleType = mModule->GetIntCoercibleType(leftValue.mType);
|
||||||
if (intCoercibleType != NULL)
|
if (intCoercibleType != NULL)
|
||||||
|
@ -18970,7 +18982,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
auto intRHS = mModule->GetIntCoercible(rightValue);
|
auto intRHS = mModule->GetIntCoercible(rightValue);
|
||||||
auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
|
auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
|
||||||
|
|
||||||
if (binaryOp == BfBinaryOp_Equality)
|
if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality))
|
||||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(intLHS.mValue, intRHS.mValue), boolType);
|
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(intLHS.mValue, intRHS.mValue), boolType);
|
||||||
else
|
else
|
||||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpNE(intLHS.mValue, intRHS.mValue), boolType);
|
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpNE(intLHS.mValue, intRHS.mValue), boolType);
|
||||||
|
@ -19021,7 +19033,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
|
|
||||||
if (resultType->IsMethodRef() && otherType->IsMethodRef())
|
if (resultType->IsMethodRef() && otherType->IsMethodRef())
|
||||||
{
|
{
|
||||||
if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_InEquality))
|
if (BfBinOpEqualityCheck(binaryOp))
|
||||||
{
|
{
|
||||||
auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
|
auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean);
|
||||||
|
|
||||||
|
@ -19029,7 +19041,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
BfMethodRefType* rhsMethodRefType = (BfMethodRefType*)rightValue.mType;
|
BfMethodRefType* rhsMethodRefType = (BfMethodRefType*)rightValue.mType;
|
||||||
if (lhsMethodRefType->mMethodRef != rhsMethodRefType->mMethodRef)
|
if (lhsMethodRefType->mMethodRef != rhsMethodRefType->mMethodRef)
|
||||||
{
|
{
|
||||||
mResult = BfTypedValue(mModule->GetConstValue((binaryOp == BfBinaryOp_Equality) ? 0 : 1, boolType), boolType);
|
mResult = BfTypedValue(mModule->GetConstValue(((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality)) ? 0 : 1, boolType), boolType);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19056,13 +19068,15 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
if (leftValue.mType != rightValue.mType)
|
if (leftValue.mType != rightValue.mType)
|
||||||
{
|
{
|
||||||
bool isBitwiseExpr =
|
bool isBitwiseExpr =
|
||||||
(binaryOp == BfBinaryOp_BitwiseAnd) |
|
(binaryOp == BfBinaryOp_BitwiseAnd) ||
|
||||||
(binaryOp == BfBinaryOp_BitwiseOr) |
|
(binaryOp == BfBinaryOp_BitwiseOr) ||
|
||||||
(binaryOp == BfBinaryOp_ExclusiveOr) |
|
(binaryOp == BfBinaryOp_ExclusiveOr) ||
|
||||||
(binaryOp == BfBinaryOp_LeftShift) |
|
(binaryOp == BfBinaryOp_LeftShift) ||
|
||||||
(binaryOp == BfBinaryOp_RightShift) |
|
(binaryOp == BfBinaryOp_RightShift) ||
|
||||||
(binaryOp == BfBinaryOp_Equality) |
|
(binaryOp == BfBinaryOp_Equality) ||
|
||||||
(binaryOp == BfBinaryOp_InEquality);
|
(binaryOp == BfBinaryOp_InEquality) ||
|
||||||
|
(binaryOp == BfBinaryOp_StrictEquality) ||
|
||||||
|
(binaryOp == BfBinaryOp_StrictInEquality);
|
||||||
|
|
||||||
if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift))
|
if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift))
|
||||||
{
|
{
|
||||||
|
@ -19170,10 +19184,12 @@ void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convL
|
||||||
switch (binaryOp)
|
switch (binaryOp)
|
||||||
{
|
{
|
||||||
case BfBinaryOp_Equality:
|
case BfBinaryOp_Equality:
|
||||||
|
case BfBinaryOp_StrictEquality:
|
||||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 1),
|
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 1),
|
||||||
mModule->GetPrimitiveType(BfTypeCode_Boolean));
|
mModule->GetPrimitiveType(BfTypeCode_Boolean));
|
||||||
break;
|
break;
|
||||||
case BfBinaryOp_InEquality:
|
case BfBinaryOp_InEquality:
|
||||||
|
case BfBinaryOp_StrictInEquality:
|
||||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 0),
|
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 0),
|
||||||
mModule->GetPrimitiveType(BfTypeCode_Boolean));
|
mModule->GetPrimitiveType(BfTypeCode_Boolean));
|
||||||
break;
|
break;
|
||||||
|
@ -19195,10 +19211,12 @@ void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convL
|
||||||
switch (binaryOp)
|
switch (binaryOp)
|
||||||
{
|
{
|
||||||
case BfBinaryOp_Equality:
|
case BfBinaryOp_Equality:
|
||||||
|
case BfBinaryOp_StrictEquality:
|
||||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(convLeftValue, convRightValue),
|
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(convLeftValue, convRightValue),
|
||||||
mModule->GetPrimitiveType(BfTypeCode_Boolean));
|
mModule->GetPrimitiveType(BfTypeCode_Boolean));
|
||||||
break;
|
break;
|
||||||
case BfBinaryOp_InEquality:
|
case BfBinaryOp_InEquality:
|
||||||
|
case BfBinaryOp_StrictInEquality:
|
||||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpNE(convLeftValue, convRightValue),
|
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpNE(convLeftValue, convRightValue),
|
||||||
mModule->GetPrimitiveType(BfTypeCode_Boolean));
|
mModule->GetPrimitiveType(BfTypeCode_Boolean));
|
||||||
break;
|
break;
|
||||||
|
@ -19298,11 +19316,13 @@ void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convL
|
||||||
case BfBinaryOp_Modulus:
|
case BfBinaryOp_Modulus:
|
||||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateRem(convLeftValue, convRightValue, resultType->IsSigned()), resultType);
|
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateRem(convLeftValue, convRightValue, resultType->IsSigned()), resultType);
|
||||||
break;
|
break;
|
||||||
case BfBinaryOp_Equality:
|
case BfBinaryOp_Equality:
|
||||||
|
case BfBinaryOp_StrictEquality:
|
||||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(convLeftValue, convRightValue),
|
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(convLeftValue, convRightValue),
|
||||||
mModule->GetPrimitiveType(BfTypeCode_Boolean));
|
mModule->GetPrimitiveType(BfTypeCode_Boolean));
|
||||||
break;
|
break;
|
||||||
case BfBinaryOp_InEquality:
|
case BfBinaryOp_InEquality:
|
||||||
|
case BfBinaryOp_StrictInEquality:
|
||||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpNE(convLeftValue, convRightValue),
|
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpNE(convLeftValue, convRightValue),
|
||||||
mModule->GetPrimitiveType(BfTypeCode_Boolean));
|
mModule->GetPrimitiveType(BfTypeCode_Boolean));
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -2538,7 +2538,7 @@ BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPers
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (refNode != NULL)
|
if (refNode != NULL)
|
||||||
refNode = BfNodeToNonTemporary(refNode);
|
refNode = BfNodeToNonTemporary(refNode);
|
||||||
|
|
||||||
//BF_ASSERT(refNode != NULL);
|
//BF_ASSERT(refNode != NULL);
|
||||||
|
@ -3973,11 +3973,11 @@ void BfModule::CreateDynamicCastMethod()
|
||||||
mCurMethodState->mHadReturn = true;
|
mCurMethodState->mHadReturn = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfModule::EmitEquals(BfTypedValue leftValue, BfTypedValue rightValue, BfIRBlock exitBB)
|
void BfModule::EmitEquals(BfTypedValue leftValue, BfTypedValue rightValue, BfIRBlock exitBB, bool strictEquals)
|
||||||
{
|
{
|
||||||
BfExprEvaluator exprEvaluator(this);
|
BfExprEvaluator exprEvaluator(this);
|
||||||
exprEvaluator.mExpectingType = mCurMethodInstance->mReturnType;
|
exprEvaluator.mExpectingType = mCurMethodInstance->mReturnType;
|
||||||
exprEvaluator.PerformBinaryOperation((BfAstNode*)NULL, (BfAstNode*)NULL, BfBinaryOp_Equality, NULL, BfBinOpFlag_None, leftValue, rightValue);
|
exprEvaluator.PerformBinaryOperation((BfAstNode*)NULL, (BfAstNode*)NULL, strictEquals ? BfBinaryOp_StrictEquality : BfBinaryOp_Equality, NULL, BfBinOpFlag_None, leftValue, rightValue);
|
||||||
BfTypedValue result = exprEvaluator.GetResult();
|
BfTypedValue result = exprEvaluator.GetResult();
|
||||||
if ((result) && (!result.mType->IsVar()))
|
if ((result) && (!result.mType->IsVar()))
|
||||||
{
|
{
|
||||||
|
@ -4036,7 +4036,7 @@ void BfModule::CreateFakeCallerMethod(const String& funcName)
|
||||||
mBfIRBuilder->CreateRetVoid();
|
mBfIRBuilder->CreateRetVoid();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfModule::CreateValueTypeEqualsMethod()
|
void BfModule::CreateValueTypeEqualsMethod(bool strictEquals)
|
||||||
{
|
{
|
||||||
if (mCurMethodInstance->mIsUnspecialized)
|
if (mCurMethodInstance->mIsUnspecialized)
|
||||||
return;
|
return;
|
||||||
|
@ -4109,7 +4109,7 @@ void BfModule::CreateValueTypeEqualsMethod()
|
||||||
mBfIRBuilder->SetInsertPoint(bodyBB);
|
mBfIRBuilder->SetInsertPoint(bodyBB);
|
||||||
BfTypedValue leftValue = BfTypedValue(mBfIRBuilder->CreateInBoundsGEP(mCurMethodState->mLocals[0]->mValue, GetDefaultValue(intPtrType), loadedItr), sizedArrayType->mElementType, BfTypedValueKind_Addr);
|
BfTypedValue leftValue = BfTypedValue(mBfIRBuilder->CreateInBoundsGEP(mCurMethodState->mLocals[0]->mValue, GetDefaultValue(intPtrType), loadedItr), sizedArrayType->mElementType, BfTypedValueKind_Addr);
|
||||||
BfTypedValue rightValue = BfTypedValue(mBfIRBuilder->CreateInBoundsGEP(mCurMethodState->mLocals[1]->mValue, GetDefaultValue(intPtrType), loadedItr), sizedArrayType->mElementType, BfTypedValueKind_Addr);
|
BfTypedValue rightValue = BfTypedValue(mBfIRBuilder->CreateInBoundsGEP(mCurMethodState->mLocals[1]->mValue, GetDefaultValue(intPtrType), loadedItr), sizedArrayType->mElementType, BfTypedValueKind_Addr);
|
||||||
EmitEquals(leftValue, rightValue, exitBB);
|
EmitEquals(leftValue, rightValue, exitBB, strictEquals);
|
||||||
auto incValue = mBfIRBuilder->CreateAdd(loadedItr, mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 1));
|
auto incValue = mBfIRBuilder->CreateAdd(loadedItr, mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 1));
|
||||||
mBfIRBuilder->CreateStore(incValue, itr);
|
mBfIRBuilder->CreateStore(incValue, itr);
|
||||||
mBfIRBuilder->CreateBr(loopBB);
|
mBfIRBuilder->CreateBr(loopBB);
|
||||||
|
@ -4122,7 +4122,7 @@ void BfModule::CreateValueTypeEqualsMethod()
|
||||||
{
|
{
|
||||||
BfTypedValue leftValue = BfTypedValue(mBfIRBuilder->CreateInBoundsGEP(mCurMethodState->mLocals[0]->mValue, 0, dataIdx), sizedArrayType->mElementType, BfTypedValueKind_Addr);
|
BfTypedValue leftValue = BfTypedValue(mBfIRBuilder->CreateInBoundsGEP(mCurMethodState->mLocals[0]->mValue, 0, dataIdx), sizedArrayType->mElementType, BfTypedValueKind_Addr);
|
||||||
BfTypedValue rightValue = BfTypedValue(mBfIRBuilder->CreateInBoundsGEP(mCurMethodState->mLocals[1]->mValue, 0, dataIdx), sizedArrayType->mElementType, BfTypedValueKind_Addr);
|
BfTypedValue rightValue = BfTypedValue(mBfIRBuilder->CreateInBoundsGEP(mCurMethodState->mLocals[1]->mValue, 0, dataIdx), sizedArrayType->mElementType, BfTypedValueKind_Addr);
|
||||||
EmitEquals(leftValue, rightValue, exitBB);
|
EmitEquals(leftValue, rightValue, exitBB, strictEquals);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4144,7 +4144,7 @@ void BfModule::CreateValueTypeEqualsMethod()
|
||||||
BfTypedValue leftValue = exprEvaluator.DoImplicitArgCapture(NULL, methodInstance, methodRefType->GetParamIdxFromDataIdx(dataIdx), failed, BfImplicitParamKind_General, leftTypedVal);
|
BfTypedValue leftValue = exprEvaluator.DoImplicitArgCapture(NULL, methodInstance, methodRefType->GetParamIdxFromDataIdx(dataIdx), failed, BfImplicitParamKind_General, leftTypedVal);
|
||||||
BfTypedValue rightValue = exprEvaluator.DoImplicitArgCapture(NULL, methodInstance, methodRefType->GetParamIdxFromDataIdx(dataIdx), failed, BfImplicitParamKind_General, rightTypedVal);
|
BfTypedValue rightValue = exprEvaluator.DoImplicitArgCapture(NULL, methodInstance, methodRefType->GetParamIdxFromDataIdx(dataIdx), failed, BfImplicitParamKind_General, rightTypedVal);
|
||||||
BF_ASSERT(!failed);
|
BF_ASSERT(!failed);
|
||||||
EmitEquals(leftValue, rightValue, exitBB);
|
EmitEquals(leftValue, rightValue, exitBB, strictEquals);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (compareTypeInst->IsEnum())
|
else if (compareTypeInst->IsEnum())
|
||||||
|
@ -4165,7 +4165,7 @@ void BfModule::CreateValueTypeEqualsMethod()
|
||||||
BfTypedValue leftPayload = ExtractValue(leftTypedVal, NULL, 1);
|
BfTypedValue leftPayload = ExtractValue(leftTypedVal, NULL, 1);
|
||||||
BfTypedValue rightPayload = ExtractValue(rightTypedVal, NULL, 1);
|
BfTypedValue rightPayload = ExtractValue(rightTypedVal, NULL, 1);
|
||||||
|
|
||||||
EmitEquals(leftValue, rightValue, exitBB);
|
EmitEquals(leftValue, rightValue, exitBB, strictEquals);
|
||||||
|
|
||||||
int enumCount = 0;
|
int enumCount = 0;
|
||||||
for (auto& fieldRef : compareTypeInst->mFieldInstances)
|
for (auto& fieldRef : compareTypeInst->mFieldInstances)
|
||||||
|
@ -4214,7 +4214,7 @@ void BfModule::CreateValueTypeEqualsMethod()
|
||||||
rightTuple = Cast(NULL, rightPayload, fieldInstance->mResolvedType, BfCastFlags_Force);
|
rightTuple = Cast(NULL, rightPayload, fieldInstance->mResolvedType, BfCastFlags_Force);
|
||||||
}
|
}
|
||||||
|
|
||||||
EmitEquals(leftTuple, rightTuple, exitBB);
|
EmitEquals(leftTuple, rightTuple, exitBB, strictEquals);
|
||||||
mBfIRBuilder->CreateBr(matchedBlock);
|
mBfIRBuilder->CreateBr(matchedBlock);
|
||||||
|
|
||||||
mBfIRBuilder->AddSwitchCase(switchVal, mBfIRBuilder->CreateConst(dscrType->mTypeDef->mTypeCode, enumIdx), caseBlock);
|
mBfIRBuilder->AddSwitchCase(switchVal, mBfIRBuilder->CreateConst(dscrType->mTypeDef->mTypeCode, enumIdx), caseBlock);
|
||||||
|
@ -4238,7 +4238,7 @@ void BfModule::CreateValueTypeEqualsMethod()
|
||||||
BfTypedValue rightTypedVal = exprEvaluator.LoadLocal(mCurMethodState->mLocals[1]);
|
BfTypedValue rightTypedVal = exprEvaluator.LoadLocal(mCurMethodState->mLocals[1]);
|
||||||
BfTypedValue rightUnionTypedVal = ExtractValue(rightTypedVal, NULL, 1);
|
BfTypedValue rightUnionTypedVal = ExtractValue(rightTypedVal, NULL, 1);
|
||||||
|
|
||||||
EmitEquals(leftUnionTypedVal, rightUnionTypedVal, exitBB);
|
EmitEquals(leftUnionTypedVal, rightUnionTypedVal, exitBB, strictEquals);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -4266,7 +4266,7 @@ void BfModule::CreateValueTypeEqualsMethod()
|
||||||
rightValue = LoadValue(rightValue);
|
rightValue = LoadValue(rightValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
EmitEquals(leftValue, rightValue, exitBB);
|
EmitEquals(leftValue, rightValue, exitBB, strictEquals);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto baseTypeInst = compareTypeInst->mBaseType;
|
auto baseTypeInst = compareTypeInst->mBaseType;
|
||||||
|
@ -4276,7 +4276,7 @@ void BfModule::CreateValueTypeEqualsMethod()
|
||||||
BfTypedValue rightOrigValue(mCurMethodState->mLocals[1]->mValue, compareTypeInst, true);
|
BfTypedValue rightOrigValue(mCurMethodState->mLocals[1]->mValue, compareTypeInst, true);
|
||||||
BfTypedValue leftValue = Cast(NULL, leftOrigValue, baseTypeInst);
|
BfTypedValue leftValue = Cast(NULL, leftOrigValue, baseTypeInst);
|
||||||
BfTypedValue rightValue = Cast(NULL, rightOrigValue, baseTypeInst);
|
BfTypedValue rightValue = Cast(NULL, rightOrigValue, baseTypeInst);
|
||||||
EmitEquals(leftValue, rightValue, exitBB);
|
EmitEquals(leftValue, rightValue, exitBB, strictEquals);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9927,7 +9927,7 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
|
||||||
BfConstResolver constResolver(this);
|
BfConstResolver constResolver(this);
|
||||||
if (allowNonConstArgs)
|
if (allowNonConstArgs)
|
||||||
constResolver.mBfEvalExprFlags = (BfEvalExprFlags)(constResolver.mBfEvalExprFlags | BfEvalExprFlags_AllowNonConst);
|
constResolver.mBfEvalExprFlags = (BfEvalExprFlags)(constResolver.mBfEvalExprFlags | BfEvalExprFlags_AllowNonConst);
|
||||||
|
|
||||||
bool inPropSet = false;
|
bool inPropSet = false;
|
||||||
SizedArray<BfResolvedArg, 2> argValues;
|
SizedArray<BfResolvedArg, 2> argValues;
|
||||||
for (BfExpression* arg : attributesDirective->mArguments)
|
for (BfExpression* arg : attributesDirective->mArguments)
|
||||||
|
@ -10109,7 +10109,9 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
|
||||||
resolvedArg.mTypedValue = constResolver.Resolve(arg);
|
resolvedArg.mTypedValue = constResolver.Resolve(arg);
|
||||||
|
|
||||||
if (!inPropSet)
|
if (!inPropSet)
|
||||||
|
{
|
||||||
argValues.push_back(resolvedArg);
|
argValues.push_back(resolvedArg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (autoComplete != NULL)
|
if (autoComplete != NULL)
|
||||||
|
@ -10128,7 +10130,7 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
|
||||||
attrTypeDef = attrTypeInst->mTypeDef;
|
attrTypeDef = attrTypeInst->mTypeDef;
|
||||||
|
|
||||||
bool success = true;
|
bool success = true;
|
||||||
|
|
||||||
bool isFailurePass = false;
|
bool isFailurePass = false;
|
||||||
for (int pass = 0; pass < 2; pass++)
|
for (int pass = 0; pass < 2; pass++)
|
||||||
{
|
{
|
||||||
|
@ -17655,13 +17657,19 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
||||||
}
|
}
|
||||||
else if (methodDef->mName == BF_METHODNAME_DEFAULT_EQUALS)
|
else if (methodDef->mName == BF_METHODNAME_DEFAULT_EQUALS)
|
||||||
{
|
{
|
||||||
CreateValueTypeEqualsMethod();
|
CreateValueTypeEqualsMethod(false);
|
||||||
|
skipBody = true;
|
||||||
|
skipEndChecks = true;
|
||||||
|
}
|
||||||
|
else if (methodDef->mName == BF_METHODNAME_DEFAULT_STRICT_EQUALS)
|
||||||
|
{
|
||||||
|
CreateValueTypeEqualsMethod(true);
|
||||||
skipBody = true;
|
skipBody = true;
|
||||||
skipEndChecks = true;
|
skipEndChecks = true;
|
||||||
}
|
}
|
||||||
else if ((methodDef->mName == BF_METHODNAME_EQUALS) && (typeDef == mCompiler->mValueTypeTypeDef))
|
else if ((methodDef->mName == BF_METHODNAME_EQUALS) && (typeDef == mCompiler->mValueTypeTypeDef))
|
||||||
{
|
{
|
||||||
CreateValueTypeEqualsMethod();
|
CreateValueTypeEqualsMethod(false);
|
||||||
skipBody = true;
|
skipBody = true;
|
||||||
skipEndChecks = true;
|
skipEndChecks = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1745,7 +1745,7 @@ public:
|
||||||
void EmitGCMarkMembers();
|
void EmitGCMarkMembers();
|
||||||
void EmitGCFindTLSMembers();
|
void EmitGCFindTLSMembers();
|
||||||
void EmitIteratorBlock(bool& skipBody);
|
void EmitIteratorBlock(bool& skipBody);
|
||||||
void EmitEquals(BfTypedValue leftValue, BfTypedValue rightValue, BfIRBlock exitBB);
|
void EmitEquals(BfTypedValue leftValue, BfTypedValue rightValue, BfIRBlock exitBB, bool strictEquals);
|
||||||
void CreateFakeCallerMethod(const String& funcName);
|
void CreateFakeCallerMethod(const String& funcName);
|
||||||
void CallChainedMethods(BfMethodInstance* methodInstance, bool reverse = false);
|
void CallChainedMethods(BfMethodInstance* methodInstance, bool reverse = false);
|
||||||
void AddHotDataReferences(BfHotDataReferenceBuilder* builder);
|
void AddHotDataReferences(BfHotDataReferenceBuilder* builder);
|
||||||
|
@ -1753,7 +1753,7 @@ public:
|
||||||
void ProcessMethod_ProcessDeferredLocals(int startIdx = 0);
|
void ProcessMethod_ProcessDeferredLocals(int startIdx = 0);
|
||||||
void ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup = false);
|
void ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup = false);
|
||||||
void CreateDynamicCastMethod();
|
void CreateDynamicCastMethod();
|
||||||
void CreateValueTypeEqualsMethod();
|
void CreateValueTypeEqualsMethod(bool strictEquals);
|
||||||
BfIRFunction GetIntrinsic(BfMethodInstance* methodInstance, bool reportFailure = false);
|
BfIRFunction GetIntrinsic(BfMethodInstance* methodInstance, bool reportFailure = false);
|
||||||
BfIRFunction GetBuiltInFunc(BfBuiltInFuncType funcType);
|
BfIRFunction GetBuiltInFunc(BfBuiltInFuncType funcType);
|
||||||
BfIRValue CreateFunctionFrom(BfMethodInstance* methodInstance, bool tryExisting, bool isInlined);
|
BfIRValue CreateFunctionFrom(BfMethodInstance* methodInstance, bool tryExisting, bool isInlined);
|
||||||
|
|
|
@ -3750,7 +3750,8 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
||||||
if (methodDef->mMethodDeclaration == NULL)
|
if (methodDef->mMethodDeclaration == NULL)
|
||||||
{
|
{
|
||||||
// Internal methods don't need decls
|
// Internal methods don't need decls
|
||||||
if (methodDef->mName == BF_METHODNAME_DEFAULT_EQUALS)
|
if ((methodDef->mName == BF_METHODNAME_DEFAULT_EQUALS) ||
|
||||||
|
(methodDef->mName == BF_METHODNAME_DEFAULT_STRICT_EQUALS))
|
||||||
declRequired = false;
|
declRequired = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1377,8 +1377,17 @@ void BfParser::NextToken(int endIdx)
|
||||||
case '!':
|
case '!':
|
||||||
if (mSrc[mSrcIdx] == '=')
|
if (mSrc[mSrcIdx] == '=')
|
||||||
{
|
{
|
||||||
mToken = BfToken_CompareNotEquals;
|
if (mSrc[mSrcIdx + 1] == '=')
|
||||||
mTokenEnd = ++mSrcIdx;
|
{
|
||||||
|
mToken = BfToken_CompareStrictNotEquals;
|
||||||
|
++mSrcIdx;
|
||||||
|
mTokenEnd = ++mSrcIdx;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mToken = BfToken_CompareNotEquals;
|
||||||
|
mTokenEnd = ++mSrcIdx;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mToken = BfToken_Bang;
|
mToken = BfToken_Bang;
|
||||||
|
@ -1387,8 +1396,17 @@ void BfParser::NextToken(int endIdx)
|
||||||
case '=':
|
case '=':
|
||||||
if (mSrc[mSrcIdx] == '=')
|
if (mSrc[mSrcIdx] == '=')
|
||||||
{
|
{
|
||||||
mToken = BfToken_CompareEquals;
|
if (mSrc[mSrcIdx + 1] == '=')
|
||||||
mTokenEnd = ++mSrcIdx;
|
{
|
||||||
|
mToken = BfToken_CompareStrictEquals;
|
||||||
|
++mSrcIdx;
|
||||||
|
mTokenEnd = ++mSrcIdx;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mToken = BfToken_CompareEquals;
|
||||||
|
mTokenEnd = ++mSrcIdx;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (mSrc[mSrcIdx] == '>')
|
else if (mSrc[mSrcIdx] == '>')
|
||||||
{
|
{
|
||||||
|
|
|
@ -657,6 +657,7 @@ enum BfCallingConvention : uint8
|
||||||
#define BF_METHODNAME_INVOKE "Invoke"
|
#define BF_METHODNAME_INVOKE "Invoke"
|
||||||
#define BF_METHODNAME_TO_STRING "ToString"
|
#define BF_METHODNAME_TO_STRING "ToString"
|
||||||
#define BF_METHODNAME_DEFAULT_EQUALS "__Equals"
|
#define BF_METHODNAME_DEFAULT_EQUALS "__Equals"
|
||||||
|
#define BF_METHODNAME_DEFAULT_STRICT_EQUALS "__StrictEquals"
|
||||||
|
|
||||||
enum BfOptimize : int8
|
enum BfOptimize : int8
|
||||||
{
|
{
|
||||||
|
|
|
@ -5646,7 +5646,7 @@ void DbgExprEvaluator::PerformBinaryOperation(ASTREF(BfExpression*)& leftExpress
|
||||||
if ((resultTypedValue->mIsLiteral) && (resultType->IsPointer()))
|
if ((resultTypedValue->mIsLiteral) && (resultType->IsPointer()))
|
||||||
{
|
{
|
||||||
// If we're comparing against a string literal like 'str == "Hey!"', handle that
|
// If we're comparing against a string literal like 'str == "Hey!"', handle that
|
||||||
if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_InEquality))
|
if (BfBinOpEqualityCheck(binaryOp))
|
||||||
{
|
{
|
||||||
DbgType* useType = otherType;
|
DbgType* useType = otherType;
|
||||||
useType = useType->RemoveModifiers();
|
useType = useType->RemoveModifiers();
|
||||||
|
@ -5689,7 +5689,7 @@ void DbgExprEvaluator::PerformBinaryOperation(ASTREF(BfExpression*)& leftExpress
|
||||||
|
|
||||||
auto boolType = mDbgModule->GetPrimitiveType(DbgType_Bool, GetLanguage());
|
auto boolType = mDbgModule->GetPrimitiveType(DbgType_Bool, GetLanguage());
|
||||||
mResult.mType = boolType;
|
mResult.mType = boolType;
|
||||||
mResult.mBool = isEq == (binaryOp == BfBinaryOp_Equality);
|
mResult.mBool = isEq == ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5708,9 +5708,9 @@ void DbgExprEvaluator::PerformBinaryOperation(ASTREF(BfExpression*)& leftExpress
|
||||||
return;
|
return;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
if ((otherType->IsNull()) && ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_InEquality)))
|
if ((otherType->IsNull()) && BfBinOpEqualityCheck(binaryOp))
|
||||||
{
|
{
|
||||||
bool isEquality = (binaryOp == BfBinaryOp_Equality);
|
bool isEquality = (binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality);
|
||||||
|
|
||||||
if (resultType->IsValueType())
|
if (resultType->IsValueType())
|
||||||
{
|
{
|
||||||
|
@ -5801,7 +5801,8 @@ void DbgExprEvaluator::PerformBinaryOperation(ASTREF(BfExpression*)& leftExpress
|
||||||
mResult.mType = intPtrType;
|
mResult.mType = intPtrType;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if ((binaryOp != BfBinaryOp_Equality) && (binaryOp != BfBinaryOp_InEquality) &&
|
else if ((binaryOp != BfBinaryOp_Equality) && (binaryOp != BfBinaryOp_StrictEquality) &
|
||||||
|
(binaryOp != BfBinaryOp_InEquality) && (binaryOp != BfBinaryOp_StrictInEquality) &&
|
||||||
(binaryOp != BfBinaryOp_LessThan) && (binaryOp != BfBinaryOp_LessThanOrEqual) &&
|
(binaryOp != BfBinaryOp_LessThan) && (binaryOp != BfBinaryOp_LessThanOrEqual) &&
|
||||||
(binaryOp != BfBinaryOp_GreaterThan) && (binaryOp != BfBinaryOp_GreaterThanOrEqual))
|
(binaryOp != BfBinaryOp_GreaterThan) && (binaryOp != BfBinaryOp_GreaterThanOrEqual))
|
||||||
{
|
{
|
||||||
|
@ -5817,7 +5818,7 @@ void DbgExprEvaluator::PerformBinaryOperation(ASTREF(BfExpression*)& leftExpress
|
||||||
{
|
{
|
||||||
if (otherType->IsNull())
|
if (otherType->IsNull())
|
||||||
{
|
{
|
||||||
if ((binaryOp != BfBinaryOp_Equality) && (binaryOp != BfBinaryOp_InEquality))
|
if (!BfBinOpEqualityCheck(binaryOp))
|
||||||
{
|
{
|
||||||
Fail(StrFormat("Invalid operation between '%s' and null", resultType->ToString().c_str()), opToken);
|
Fail(StrFormat("Invalid operation between '%s' and null", resultType->ToString().c_str()), opToken);
|
||||||
return;
|
return;
|
||||||
|
@ -5870,7 +5871,7 @@ void DbgExprEvaluator::PerformBinaryOperation(ASTREF(BfExpression*)& leftExpress
|
||||||
|
|
||||||
if ((resultType->IsPointer()) || (resultType->IsBfObject()) || (resultType->IsInterface()) /*|| (resultType->IsGenericParam())*/)
|
if ((resultType->IsPointer()) || (resultType->IsBfObject()) || (resultType->IsInterface()) /*|| (resultType->IsGenericParam())*/)
|
||||||
{
|
{
|
||||||
if ((binaryOp != BfBinaryOp_Equality) && (binaryOp != BfBinaryOp_InEquality))
|
if (!BfBinOpEqualityCheck(binaryOp))
|
||||||
{
|
{
|
||||||
if (resultType->IsPointer())
|
if (resultType->IsPointer())
|
||||||
Fail("Invalid operation for pointers", opToken);
|
Fail("Invalid operation for pointers", opToken);
|
||||||
|
@ -5882,7 +5883,7 @@ void DbgExprEvaluator::PerformBinaryOperation(ASTREF(BfExpression*)& leftExpress
|
||||||
if (otherType->IsNull())
|
if (otherType->IsNull())
|
||||||
{
|
{
|
||||||
mResult.mType = mDbgModule->GetPrimitiveType(DbgType_Bool, GetLanguage());
|
mResult.mType = mDbgModule->GetPrimitiveType(DbgType_Bool, GetLanguage());
|
||||||
if (binaryOp == BfBinaryOp_Equality)
|
if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality))
|
||||||
mResult.mBool = resultTypedValue->mPtr == NULL;
|
mResult.mBool = resultTypedValue->mPtr == NULL;
|
||||||
else
|
else
|
||||||
mResult.mBool = resultTypedValue->mPtr != NULL;
|
mResult.mBool = resultTypedValue->mPtr != NULL;
|
||||||
|
@ -5898,7 +5899,7 @@ void DbgExprEvaluator::PerformBinaryOperation(ASTREF(BfExpression*)& leftExpress
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mResult.mType = mDbgModule->GetPrimitiveType(DbgType_Bool, GetLanguage());
|
mResult.mType = mDbgModule->GetPrimitiveType(DbgType_Bool, GetLanguage());
|
||||||
if (binaryOp == BfBinaryOp_Equality)
|
if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality))
|
||||||
mResult.mBool = resultTypedValue->mPtr == convertedValue.mPtr;
|
mResult.mBool = resultTypedValue->mPtr == convertedValue.mPtr;
|
||||||
else
|
else
|
||||||
mResult.mBool = resultTypedValue->mPtr != convertedValue.mPtr;
|
mResult.mBool = resultTypedValue->mPtr != convertedValue.mPtr;
|
||||||
|
@ -6035,10 +6036,12 @@ void DbgExprEvaluator::PerformBinaryOperation(DbgType* resultType, DbgTypedValue
|
||||||
switch (binaryOp)
|
switch (binaryOp)
|
||||||
{
|
{
|
||||||
case BfBinaryOp_Equality:
|
case BfBinaryOp_Equality:
|
||||||
|
case BfBinaryOp_StrictEquality:
|
||||||
mResult.mType = mDbgModule->GetPrimitiveType(DbgType_Bool, GetLanguage());
|
mResult.mType = mDbgModule->GetPrimitiveType(DbgType_Bool, GetLanguage());
|
||||||
mResult.mBool = true;
|
mResult.mBool = true;
|
||||||
break;
|
break;
|
||||||
case BfBinaryOp_InEquality:
|
case BfBinaryOp_InEquality:
|
||||||
|
case BfBinaryOp_StrictInEquality:
|
||||||
mResult.mType = mDbgModule->GetPrimitiveType(DbgType_Bool, GetLanguage());
|
mResult.mType = mDbgModule->GetPrimitiveType(DbgType_Bool, GetLanguage());
|
||||||
mResult.mBool = false;
|
mResult.mBool = false;
|
||||||
break;
|
break;
|
||||||
|
@ -6063,10 +6066,12 @@ void DbgExprEvaluator::PerformBinaryOperation(DbgType* resultType, DbgTypedValue
|
||||||
mResult.mType = mDbgModule->GetPrimitiveType(DbgType_Bool, GetLanguage());
|
mResult.mType = mDbgModule->GetPrimitiveType(DbgType_Bool, GetLanguage());
|
||||||
switch (binaryOp)
|
switch (binaryOp)
|
||||||
{
|
{
|
||||||
case BfBinaryOp_Equality:
|
case BfBinaryOp_Equality:
|
||||||
|
case BfBinaryOp_StrictEquality:
|
||||||
mResult.mBool = convLeftValue.mBool == convRightValue.mBool;
|
mResult.mBool = convLeftValue.mBool == convRightValue.mBool;
|
||||||
break;
|
break;
|
||||||
case BfBinaryOp_InEquality:
|
case BfBinaryOp_InEquality:
|
||||||
|
case BfBinaryOp_StrictInEquality:
|
||||||
mResult.mBool = convLeftValue.mBool != convRightValue.mBool;
|
mResult.mBool = convLeftValue.mBool != convRightValue.mBool;
|
||||||
break;
|
break;
|
||||||
case BfBinaryOp_ConditionalAnd:
|
case BfBinaryOp_ConditionalAnd:
|
||||||
|
@ -6182,6 +6187,7 @@ void DbgExprEvaluator::PerformBinaryOperation(DbgType* resultType, DbgTypedValue
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BfBinaryOp_Equality:
|
case BfBinaryOp_Equality:
|
||||||
|
case BfBinaryOp_StrictEquality:
|
||||||
mResult.mType = mDbgModule->GetPrimitiveType(DbgType_Bool, GetLanguage());
|
mResult.mType = mDbgModule->GetPrimitiveType(DbgType_Bool, GetLanguage());
|
||||||
if (resultType->mTypeCode == DbgType_Single)
|
if (resultType->mTypeCode == DbgType_Single)
|
||||||
mResult.mBool = convLeftValue.mSingle == convRightValue.mSingle;
|
mResult.mBool = convLeftValue.mSingle == convRightValue.mSingle;
|
||||||
|
@ -6191,6 +6197,7 @@ void DbgExprEvaluator::PerformBinaryOperation(DbgType* resultType, DbgTypedValue
|
||||||
mResult.mBool = convLeftValue.GetInt64() == convRightValue.GetInt64();
|
mResult.mBool = convLeftValue.GetInt64() == convRightValue.GetInt64();
|
||||||
break;
|
break;
|
||||||
case BfBinaryOp_InEquality:
|
case BfBinaryOp_InEquality:
|
||||||
|
case BfBinaryOp_StrictInEquality:
|
||||||
mResult.mType = mDbgModule->GetPrimitiveType(DbgType_Bool, GetLanguage());
|
mResult.mType = mDbgModule->GetPrimitiveType(DbgType_Bool, GetLanguage());
|
||||||
if (resultType->mTypeCode == DbgType_Single)
|
if (resultType->mTypeCode == DbgType_Single)
|
||||||
mResult.mBool = convLeftValue.mSingle != convRightValue.mSingle;
|
mResult.mBool = convLeftValue.mSingle != convRightValue.mSingle;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue