diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 862bd6db..2e3e2732 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -20796,7 +20796,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod if ((leftValue.mValue.IsConst()) && (rightValue.mValue.IsConst())) skipOpOverload = true; } - + if (!skipOpOverload) { BfBinaryOp findBinaryOp = binaryOp; @@ -20843,7 +20843,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod break; bool foundExactMatch = false; - Array oppositeOperatorDefs; + SizedArray oppositeOperatorDefs; for (auto operatorDef : checkType->mTypeDef->mOperators) { @@ -21135,10 +21135,19 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod if (pass == 1) break; - findBinaryOp = BfGetFlippedBinaryOp(findBinaryOp); - if (findBinaryOp == BfBinaryOp_None) - break; + auto flippedBinaryOp = BfGetFlippedBinaryOp(findBinaryOp); + if (flippedBinaryOp != BfBinaryOp_None) + findBinaryOp = flippedBinaryOp; } + + auto prevResultType = resultType; + if (leftValue.mType->IsPrimitiveType()) + resultType = leftValue.mType; + if (rightValue.mType->IsPrimitiveType()) + resultType = rightValue.mType; + + if ((prevResultType->IsTypedPrimitive()) && (resultType->IsPrimitiveType())) + explicitCast = true; } } diff --git a/IDEHelper/Tests/src/Operators.bf b/IDEHelper/Tests/src/Operators.bf index 9944ced7..0c8c2f13 100644 --- a/IDEHelper/Tests/src/Operators.bf +++ b/IDEHelper/Tests/src/Operators.bf @@ -102,6 +102,80 @@ namespace Tests } } + struct StructD + { + int mVal; + + public this(int val) + { + mVal = val; + } + + public static implicit operator int(StructD x) + { + return x.mVal; + } + + public static implicit operator StructD(int x) + { + return default(StructD); + } + } + + struct StructE + { + float mVal; + + public this(float val) + { + mVal = val; + } + + public static implicit operator float(StructE x) + { + return x.mVal; + } + + public static implicit operator StructE(float x) + { + return .(x); + } + + public static StructE operator+(StructE lhs, StructE rhs) + { + return .(1); + } + + public static int operator+(StructE lhs, int rhs) + { + return 2; + } + + public static int operator+(int lhs, StructE rhs) + { + return 3; + } + } + + struct StructF + { + public static int operator+(StructF lhs, int rhs) + { + return 1; + } + + public static int operator+(int lhs, StructF rhs) + { + return 2; + } + + [Commutable] + public static int operator+(StructF lhs, float rhs) + { + return 3; + } + } + struct StructOp where T : operator T + T2 { public T DoIt(T val, T2 val2) @@ -317,6 +391,22 @@ namespace Tests FlagsRegister fr = .(true, false, true, true); Test.Assert(fr == (uint8)0b10110000); + StructD sd = .(9); + Test.Assert(sd + 10 == 19); + Test.Assert(10 + sd == 19); + + StructE se = .(9); + Test.Assert(se + 10 == 2); + Test.Assert(10 + se == 3); + Test.Assert(se + 1.2f == 1); + Test.Assert(1.2f + se == 1); + + StructF sf = default; + Test.Assert(sf + 10 == 1); + Test.Assert(10 + sf == 2); + Test.Assert(sf + 1.0f == 3); + Test.Assert(2.0f + sf == 3); + /*let oai = OuterOp.InnerOp.Op(1.0f, 100); Test.Assert(oai == 101.0f);