Просмотр исходного кода

Allow (.) inferred type cast inside ref and * unary operations

Brian Fiete 7 месяцев назад
Родитель
Сommit
124d191bab

+ 4 - 1
IDEHelper/Compiler/BfDeferEvalChecker.cpp

@@ -139,9 +139,12 @@ void BfDeferEvalChecker::Visit(BfUnaryOperatorExpression* unaryOpExpr)
 {
 	switch (unaryOpExpr->mOp)
 	{
+	case BfUnaryOp_Dereference:
+	case BfUnaryOp_Ref:
+	case BfUnaryOp_Not:
 	case BfUnaryOp_Negate:
 	case BfUnaryOp_Positive:
-	case BfUnaryOp_InvertBits:
+	case BfUnaryOp_InvertBits:	
 		VisitChild(unaryOpExpr->mExpression);
 		break;
 // 	case BfUnaryOp_Params:

+ 15 - 5
IDEHelper/Compiler/BfExprEvaluator.cpp

@@ -1471,7 +1471,7 @@ BfTypedValue BfMethodMatcher::ResolveArgTypedValue(BfResolvedArg& resolvedArg, B
 
 				BfExprEvaluator exprEvaluator(mModule);
 				exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags);
-				exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | BfEvalExprFlags_AllowIntUnknown | BfEvalExprFlags_NoAutoComplete);
+				exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | BfEvalExprFlags_AllowIntUnknown | BfEvalExprFlags_AllowRefExpr | BfEvalExprFlags_NoAutoComplete);
 				if ((resolvedArg.mArgFlags & BfArgFlag_ParamsExpr) != 0)
 					exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | BfEvalExprFlags_AllowParamsExpr);
 
@@ -7460,7 +7460,7 @@ void BfExprEvaluator::FinishDeferredEvals(SizedArrayImpl<BfResolvedArg>& argValu
 			{
 				auto expr = BfNodeDynCast<BfExpression>(argValues[argIdx].mExpression);
 				if (expr != NULL)
-					argValue = mModule->CreateValueFromExpression(expr, argValues[argIdx].mExpectedType);
+					argValue = mModule->CreateValueFromExpression(expr, argValues[argIdx].mExpectedType, BfEvalExprFlags_NoCast);
 			}
 		}
 	}
@@ -8955,7 +8955,7 @@ BfTypedValue BfExprEvaluator::ResolveArgValue(BfResolvedArg& resolvedArg, BfType
 			{
 				BfExprEvaluator exprEvaluator(mModule);
 				exprEvaluator.mReceivingValue = receivingValue;
-				BfEvalExprFlags flags = (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast);
+				BfEvalExprFlags flags = (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast | BfEvalExprFlags_AllowRefExpr);
 				if ((paramKind == BfParamKind_Params) || (paramKind == BfParamKind_DelegateParam))
 					flags = (BfEvalExprFlags)(flags | BfEvalExprFlags_AllowParamsExpr);
 
@@ -22405,15 +22405,25 @@ void BfExprEvaluator::PerformUnaryOperation(BfExpression* unaryOpExpr, BfUnaryOp
 		BfType* prevExpedcting = mExpectingType;
 		switch (unaryOp)
 		{
+		case BfUnaryOp_Ref:
+			// Allow
+			break;
+		case BfUnaryOp_Dereference:
+			if (mExpectingType != NULL)
+			{
+				if (mExpectingType->IsRef())
+					mExpectingType = mExpectingType->GetUnderlyingType();
+				mExpectingType = mModule->CreatePointerType(mExpectingType);
+			}
+			break;
 		case BfUnaryOp_Negate:
 		case BfUnaryOp_Positive:
 		case BfUnaryOp_InvertBits:
 			// If we're expecting an int64 or uint64 then just leave the type as unknown
 			if ((mExpectingType != NULL) && (mExpectingType->IsInteger()) && (mExpectingType->mSize == 8))
 				mExpectingType = NULL;
-
 			// Otherwise keep expecting type
-			break;
+			break;		
 		default:
 			mExpectingType = NULL;
 		}

+ 15 - 0
IDEHelper/Tests/src/MethodCalls.bf

@@ -1,5 +1,6 @@
 using System;
 using System.Collections;
+using System.Numerics;
 
 namespace Tests
 {
@@ -217,6 +218,16 @@ namespace Tests
 			return span[0];
 		}
 
+		public static float GetFirstFloat(float[3] fVals)
+		{
+			return fVals[0];
+		}
+
+		public static float GetFirstFloatRef(ref float[3] fVals)
+		{
+			return fVals[0];
+		}
+
 		[Test]
 		public static void TestBasics()
 		{
@@ -290,6 +301,10 @@ namespace Tests
 			fList.Add(1.2f);
 			Test.Assert(ParamsTest(params fList) == 1.2f);
 			Test.Assert(ParamsTest2(params fList) == 1.2f);
+
+			float4 fVals = .(123, 234, 345, 456);
+			Test.Assert(GetFirstFloat(*(.)&fVals) == 123);
+			Test.Assert(GetFirstFloatRef(ref *(.)&fVals) == 123);
 		}
 	}
 }