Selaa lähdekoodia

Added '->' support to nullables and Result<T>

Brian Fiete 3 vuotta sitten
vanhempi
commit
36a8c2c6ae

+ 19 - 0
BeefLibs/corlib/src/Nullable.bf

@@ -35,6 +35,15 @@ namespace System
             }
         }
 
+		public T ValueOrDefault
+		{
+			[Inline]
+		    get
+		    {
+		        return mValue;
+		    }
+		}
+
         public ref T ValueRef
         {
 			[Inline]
@@ -96,9 +105,19 @@ namespace System
         [Inline]
         public static explicit operator T(Nullable<T> value)
         {
+			if (!value.mHasValue)
+			    Debug.FatalError("Value requested for null nullable.");
             return value.mValue;
         }
 
+		[Inline]
+		public static ref T operator->(ref Nullable<T> value)
+		{
+			if (!value.mHasValue)
+				Debug.FatalError("Value requested for null nullable.");
+		    return ref value.mValue;
+		}
+
         [Inline, Commutable]
         public static bool operator==(Nullable<T> lhs, T rhs)
         {

+ 62 - 2
BeefLibs/corlib/src/Result.bf

@@ -27,6 +27,22 @@ namespace System
 			}
 		}
 
+		public ref T ValueRef
+		{
+			[Inline]
+			get mut
+			{
+				switch (this)
+				{
+				case .Ok(var ref val): return ref val;
+				case .Err:
+					{
+						Internal.FatalError("Unhandled error in result", 2);
+					}
+				}
+			}
+		}
+
 		[Inline]
 		public static implicit operator Result<T>(T value)
 		{
@@ -39,6 +55,19 @@ namespace System
 			return result.Unwrap();
 		}
 
+		[Inline]
+		public static mut T operator->(ref Result<T> result)
+		{
+			switch (result)
+			{
+			case .Ok(var mut val): return mut val;
+			case .Err:
+				{
+					Internal.FatalError("Unhandled error in result", 2);
+				}
+			}
+		}
+
 		[Inline]
 		public void IgnoreError()
 		{
@@ -116,9 +145,9 @@ namespace System
 			switch (this)
 			{
 			case .Ok(var val): return val;
-			case .Err(var err):
+			case .Err:
 				{
-					Internal.FatalError(scope String()..AppendF("Unhandled error in result:\n {}", err), 2);
+					Internal.FatalError("Unhandled error in result", 2);
 				}
 			}
 		}
@@ -131,16 +160,47 @@ namespace System
 			}
 		}
 
+		public ref T ValueRef
+		{
+			[Inline]
+			get mut
+			{
+				switch (this)
+				{
+				case .Ok(var ref val): return ref val;
+				case .Err:
+					{
+						Internal.FatalError("Unhandled error in result", 2);
+					}
+				}
+			}
+		}
+
+		[Inline]
 		public static implicit operator Result<T, TErr>(T value)
 		{
 		    return .Ok(value);
 		}
 
+		[Inline]
 		public static implicit operator T(Result<T, TErr> result)
 		{
 			return result.Unwrap();
 		}
 
+		[Inline]
+		public static mut T operator->(ref Result<T, TErr> result)
+		{
+			switch (result)
+			{
+			case .Ok(var mut val): return mut val;
+			case .Err:
+				{
+					Internal.FatalError("Unhandled error in result", 2);
+				}
+			}
+		}
+
 		public void IgnoreError()
 		{
 		}

+ 5 - 2
IDEHelper/Backend/BeModule.cpp

@@ -3409,14 +3409,17 @@ BeStoreInst* BeModule::CreateAlignedStore(BeValue* val, BeValue* ptr, int alignm
 
 BeGEPInst* BeModule::CreateGEP(BeValue* ptr, BeValue* idx0, BeValue* idx1)
 {	
+#ifdef _DEBUG
+	BF_ASSERT(ptr->GetType()->IsPointer());
+#endif
+
 	auto inst = mAlloc.Alloc<BeGEPInst>();
 	inst->mPtr = ptr;
 	inst->mIdx0 = idx0;
 	inst->mIdx1 = idx1;		
 	AddInst(inst);	
 	
-#ifdef _DEBUG
-	BF_ASSERT(ptr->GetType()->IsPointer());
+#ifdef _DEBUG	
 	inst->GetType();
 #endif
 

+ 2 - 2
IDEHelper/Compiler/BfExprEvaluator.cpp

@@ -21939,9 +21939,9 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr,
 
 			CheckResultForReading(mResult);
 			
-			if ((unaryOp == BfUnaryOp_Mut) && (!mResult.mType->IsComposite()) && (!mResult.mType->IsGenericParam()))
+			if ((unaryOp == BfUnaryOp_Mut) && (!mResult.mType->IsValueType()) && (!mResult.mType->IsGenericParam()))
 			{
-				// Non-composite types are already mutable, leave them alone...
+				// Non-valuetypes types are already mutable, leave them alone...
 				break;
 			}
 

+ 5 - 2
IDEHelper/Compiler/BfStmtEvaluator.cpp

@@ -1945,9 +1945,7 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD
 
 	if (auto varRefTypeReference = BfNodeDynCast<BfVarRefTypeReference>(varDecl->mTypeRef))
 	{
-		BF_ASSERT(val.IsAddr());
 		isRef = true;
-
 		isLet = varRefTypeReference->mVarToken->GetToken() == BfToken_Let;
 		isVar = varRefTypeReference->mVarToken->GetToken() == BfToken_Var;
 	}
@@ -2010,8 +2008,13 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD
 		localDef->mAddr = AllocLocalVariable(localDef->mResolvedType, localDef->mName);		
 		if ((val.mValue) && (!localDef->mResolvedType->IsValuelessType()) && (!localDef->mResolvedType->IsVar()))
 		{
+			if (localDef->mResolvedType->IsRef())
+				val = MakeAddressable(val, true, true);
+
 			if (val.IsSplat())
+			{
 				AggregateSplatIntoAddr(val, localDef->mAddr);
+			}
 			else
 				mBfIRBuilder->CreateAlignedStore(val.mValue, localDef->mAddr, localDef->mResolvedType->mAlign);
 		}