mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 19:48:20 +02:00
Reworked binary operators and transformability
This commit is contained in:
parent
230b71cecb
commit
b49e513494
5 changed files with 45 additions and 64 deletions
|
@ -831,7 +831,10 @@ void BfDefBuilder::ParseAttributes(BfAttributeDirective* attributes, BfMethodDef
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
methodDef->mCommutableKind = BfCommutableKind_Forward;
|
if (methodDef->mIsOperator)
|
||||||
|
methodDef->mCommutableKind = BfCommutableKind_Operator;
|
||||||
|
else
|
||||||
|
methodDef->mCommutableKind = BfCommutableKind_Forward;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,9 @@ BfBaseClassWalker::BfBaseClassWalker(BfType* typeA, BfType* typeB, BfModule* mod
|
||||||
{
|
{
|
||||||
mMayBeFromInterface = false;
|
mMayBeFromInterface = false;
|
||||||
|
|
||||||
|
if (typeB == typeA)
|
||||||
|
typeB = NULL;
|
||||||
|
|
||||||
if ((typeA != NULL) && (!typeA->IsInterface()))
|
if ((typeA != NULL) && (!typeA->IsInterface()))
|
||||||
mTypes[0] = typeA->ToTypeInstance();
|
mTypes[0] = typeA->ToTypeInstance();
|
||||||
else
|
else
|
||||||
|
@ -19731,13 +19734,12 @@ 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);
|
||||||
BfBinaryOp oppositeBinaryOp = BfGetOppositeBinaryOp(findBinaryOp);
|
|
||||||
BfBinaryOp flippedBinaryOp = BfGetFlippedBinaryOp(findBinaryOp);
|
|
||||||
BfBinaryOp flippedOppositeBinaryOp = BfGetFlippedBinaryOp(oppositeBinaryOp);
|
|
||||||
|
|
||||||
for (int pass = 0; pass < 2; pass++)
|
for (int pass = 0; pass < 2; pass++)
|
||||||
{
|
{
|
||||||
|
BfBinaryOp oppositeBinaryOp = BfGetOppositeBinaryOp(findBinaryOp);
|
||||||
bool foundOp = false;
|
bool foundOp = false;
|
||||||
|
bool foundCommutableOps = false;
|
||||||
|
|
||||||
SizedArray<BfResolvedArg, 2> args;
|
SizedArray<BfResolvedArg, 2> args;
|
||||||
BfResolvedArg leftArg;
|
BfResolvedArg leftArg;
|
||||||
|
@ -19776,6 +19778,16 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
|
|
||||||
for (auto operatorDef : checkType->mTypeDef->mOperators)
|
for (auto operatorDef : checkType->mTypeDef->mOperators)
|
||||||
{
|
{
|
||||||
|
if (operatorDef->mCommutableKind == BfCommutableKind_Operator)
|
||||||
|
{
|
||||||
|
foundCommutableOps = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (pass == 1)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
bool allowOp = operatorDef->mOperatorDeclaration->mBinOp == findBinaryOp;
|
bool allowOp = operatorDef->mOperatorDeclaration->mBinOp == findBinaryOp;
|
||||||
if ((isComparison) && (operatorDef->mOperatorDeclaration->mBinOp == BfBinaryOp_Compare))
|
if ((isComparison) && (operatorDef->mOperatorDeclaration->mBinOp == BfBinaryOp_Compare))
|
||||||
allowOp = true;
|
allowOp = true;
|
||||||
|
@ -19809,7 +19821,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (operatorDef->mOperatorDeclaration->mBinOp == oppositeBinaryOp)
|
else if ((operatorDef->mOperatorDeclaration->mBinOp == oppositeBinaryOp) && (operatorDef->mCommutableKind == BfCommutableKind_Operator))
|
||||||
oppositeOperatorDefs.Add(operatorDef);
|
oppositeOperatorDefs.Add(operatorDef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19861,8 +19873,8 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
methodMatcher.FlushAmbiguityError();
|
methodMatcher.FlushAmbiguityError();
|
||||||
|
|
||||||
auto matchedOp = ((BfOperatorDeclaration*)methodMatcher.mBestMethodDef->mMethodDeclaration)->mBinOp;
|
auto matchedOp = ((BfOperatorDeclaration*)methodMatcher.mBestMethodDef->mMethodDeclaration)->mBinOp;
|
||||||
bool invertResult = matchedOp == oppositeBinaryOp;
|
bool invertResult = matchedOp == oppositeBinaryOp;
|
||||||
|
|
||||||
auto methodDef = methodMatcher.mBestMethodDef;
|
auto methodDef = methodMatcher.mBestMethodDef;
|
||||||
auto autoComplete = GetAutoComplete();
|
auto autoComplete = GetAutoComplete();
|
||||||
bool wasCapturingMethodInfo = false;
|
bool wasCapturingMethodInfo = false;
|
||||||
|
@ -19961,33 +19973,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
works = true;
|
works = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((flippedBinaryOp != BfBinaryOp_None) && (opConstraint.mBinaryOp == flippedBinaryOp))
|
|
||||||
{
|
|
||||||
if ((mModule->CanCast(args[1].mTypedValue, opConstraint.mLeftType)) &&
|
|
||||||
(mModule->CanCast(args[0].mTypedValue, opConstraint.mRightType)))
|
|
||||||
{
|
|
||||||
works = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (((oppositeBinaryOp != BfBinaryOp_None) && (opConstraint.mBinaryOp == oppositeBinaryOp)) ||
|
|
||||||
(opConstraint.mBinaryOp == BfBinaryOp_Compare))
|
|
||||||
{
|
|
||||||
if ((mModule->CanCast(args[0].mTypedValue, opConstraint.mRightType)) &&
|
|
||||||
(mModule->CanCast(args[1].mTypedValue, opConstraint.mLeftType)))
|
|
||||||
{
|
|
||||||
works = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((flippedOppositeBinaryOp != BfBinaryOp_None) && (opConstraint.mBinaryOp == flippedOppositeBinaryOp))
|
|
||||||
{
|
|
||||||
if ((mModule->CanCast(args[1].mTypedValue, opConstraint.mRightType)) &&
|
|
||||||
(mModule->CanCast(args[0].mTypedValue, opConstraint.mLeftType)))
|
|
||||||
{
|
|
||||||
works = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((isComparison) && (opConstraint.mBinaryOp == BfBinaryOp_Compare))
|
if ((isComparison) && (opConstraint.mBinaryOp == BfBinaryOp_Compare))
|
||||||
{
|
{
|
||||||
if ((mModule->CanCast(args[0].mTypedValue, opConstraint.mLeftType)) &&
|
if ((mModule->CanCast(args[0].mTypedValue, opConstraint.mLeftType)) &&
|
||||||
|
@ -20041,38 +20027,16 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!foundOp) || (pass == 1))
|
if (!foundCommutableOps)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
switch (findBinaryOp)
|
|
||||||
{
|
|
||||||
case BfBinaryOp_Equality:
|
|
||||||
case BfBinaryOp_StrictEquality:
|
|
||||||
case BfBinaryOp_InEquality:
|
|
||||||
case BfBinaryOp_StrictInEquality:
|
|
||||||
case BfBinaryOp_Compare:
|
|
||||||
// Still works
|
|
||||||
break;
|
|
||||||
case BfBinaryOp_LessThan:
|
|
||||||
findBinaryOp = BfBinaryOp_GreaterThanOrEqual;
|
|
||||||
break;
|
|
||||||
case BfBinaryOp_LessThanOrEqual:
|
|
||||||
findBinaryOp = BfBinaryOp_GreaterThan;
|
|
||||||
break;
|
|
||||||
case BfBinaryOp_GreaterThan:
|
|
||||||
findBinaryOp = BfBinaryOp_LessThanOrEqual;
|
|
||||||
break;
|
|
||||||
case BfBinaryOp_GreaterThanOrEqual:
|
|
||||||
findBinaryOp = BfBinaryOp_LessThan;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
findBinaryOp = BfBinaryOp_None;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (pass == 1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
findBinaryOp = BfGetFlippedBinaryOp(findBinaryOp);
|
||||||
if (findBinaryOp == BfBinaryOp_None)
|
if (findBinaryOp == BfBinaryOp_None)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -694,6 +694,7 @@ enum BfImportKind : int8
|
||||||
enum BfCommutableKind : int8
|
enum BfCommutableKind : int8
|
||||||
{
|
{
|
||||||
BfCommutableKind_None,
|
BfCommutableKind_None,
|
||||||
|
BfCommutableKind_Operator,
|
||||||
BfCommutableKind_Forward,
|
BfCommutableKind_Forward,
|
||||||
BfCommutableKind_Reverse,
|
BfCommutableKind_Reverse,
|
||||||
};
|
};
|
||||||
|
|
|
@ -52,7 +52,8 @@ namespace Tests
|
||||||
static
|
static
|
||||||
{
|
{
|
||||||
public static int CompareIt<T>(this T self, T other)
|
public static int CompareIt<T>(this T self, T other)
|
||||||
where bool: operator T < T
|
where bool : operator T < T
|
||||||
|
where bool : operator T > T
|
||||||
{
|
{
|
||||||
if(self < other)
|
if(self < other)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -30,6 +30,12 @@ namespace Tests
|
||||||
newVal.mA = val.mA + 1;
|
newVal.mA = val.mA + 1;
|
||||||
return newVal;
|
return newVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Commutable]
|
||||||
|
public static bool operator<(StructA lhs, StructB rhs)
|
||||||
|
{
|
||||||
|
return lhs.mA < rhs.mB;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct StructB
|
struct StructB
|
||||||
|
@ -226,6 +232,12 @@ namespace Tests
|
||||||
StructB sb1;
|
StructB sb1;
|
||||||
sb1.mB = 12;
|
sb1.mB = 12;
|
||||||
|
|
||||||
|
Test.Assert(sa1 < sb0);
|
||||||
|
Test.Assert(!(sa1 >= sb0));
|
||||||
|
|
||||||
|
Test.Assert(sb0 > sa1);
|
||||||
|
Test.Assert(!(sb0 <= sa1));
|
||||||
|
|
||||||
StructA sa3 = sa0 + sb0;
|
StructA sa3 = sa0 + sb0;
|
||||||
Test.Assert(sa3.mA == 1012);
|
Test.Assert(sa3.mA == 1012);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue