Răsfoiți Sursa

Added constant string appending with + operator, const string fixes

Brian Fiete 5 ani în urmă
părinte
comite
c92bc523db

+ 1 - 1
IDEHelper/Backend/BeCOFFObject.cpp

@@ -1247,7 +1247,7 @@ void BeCOFFObject::DbgOutputLocalVar(BeDbgFunction* dbgFunc, BeDbgVariable* dbgV
 	{
 		if (auto beConst = BeValueDynCast<BeConstant>(dbgVar->mValue))
 		{
-			if (!beConst->mType->IsPointer())
+			if ((beConst->mType != NULL) && (!beConst->mType->IsPointer()))
 			{
 				int64 writeVal = beConst->mInt64;
 				if (beConst->mType->mTypeCode == BfTypeCode_Single)

+ 8 - 0
IDEHelper/Backend/BeContext.cpp

@@ -170,6 +170,14 @@ bool BeContext::AreTypesEqual(BeType* lhs, BeType* rhs)
 		return true;
 	case BeTypeCode_Pointer:
 		return AreTypesEqual(((BePointerType*)lhs)->mElementType, ((BePointerType*)rhs)->mElementType);	
+	case BeTypeCode_SizedArray:
+		{
+			auto lhsSizedArray = (BeSizedArrayType*)lhs;
+			auto rhsSizedArray = (BeSizedArrayType*)rhs;
+			if (lhsSizedArray->mLength != rhsSizedArray->mLength)
+				return false;
+			return AreTypesEqual(lhsSizedArray->mElementType, rhsSizedArray->mElementType);
+		}
 	}
 	return false;
 }

+ 10 - 1
IDEHelper/Backend/BeIRCodeGen.cpp

@@ -561,6 +561,14 @@ void BeIRCodeGen::Read(BeType*& beType)
 		return;
 	}
 
+	if (typeKind == BfIRType::TypeKind::TypeKind_SizedArray)
+	{
+		CMD_PARAM(BeType*, elementType);
+		CMD_PARAM(int, length);
+		beType = mBeContext->CreateSizedArrayType(elementType, length);
+		return;
+	}
+
 	int typeId = (int)ReadSLEB128();
 	auto& typeEntry = GetTypeEntry(typeId);
 	if (typeKind == BfIRType::TypeKind::TypeKind_TypeId)
@@ -1631,9 +1639,10 @@ void BeIRCodeGen::HandleNextCmd()
 			{
 				globalVariable->mAlign = varType->mAlign;
 				BF_ASSERT(varType->mAlign > 0);
+				BF_ASSERT(mBeContext->AreTypesEqual(varType, initializer->GetType()));
 			}
 			else
-				globalVariable->mAlign = -1;
+				globalVariable->mAlign = -1;			
 			
 			SetResult(curId, globalVariable);
 		}

+ 12 - 3
IDEHelper/Compiler/BfConstResolver.cpp

@@ -74,6 +74,7 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo
 					(toType == mResult.mType)))
 			{
 				auto constant = mModule->mBfIRBuilder->GetConstant(mResult.mValue);
+				
 				if (constant->mTypeCode == BfTypeCode_NullPtr)
 				{
 					return mModule->GetDefaultTypedValue(toType);
@@ -82,7 +83,15 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo
 				{
 					int stringId = mModule->GetStringPoolIdx(mResult.mValue);
 					BF_ASSERT(stringId >= 0);
-					return BfTypedValue(mModule->GetConstValue(stringId), toType);
+
+					if ((flags & BfConstResolveFlag_RemapFromStringId) != 0)
+					{
+						ignoreWrites.Restore();
+						mModule->mBfIRBuilder->PopulateType(mResult.mType);
+						return BfTypedValue(mModule->GetStringObjectValue(stringId), mResult.mType);
+					}
+
+					return BfTypedValue(mModule->GetConstValue32(stringId), toType);
 				}
 			}
 		}
@@ -168,7 +177,7 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo
 		mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock);
 	}*/
 
-	mModule->FixIntUnknown(mResult);
+	mModule->FixIntUnknown(mResult);	
 
 	return mResult;
 }
@@ -360,7 +369,7 @@ bool BfConstResolver::PrepareMethodArguments(BfAstNode* targetSrc, BfMethodMatch
 		auto arrayType = mModule->mBfIRBuilder->GetSizedArrayType(mModule->mBfIRBuilder->MapType(expandedParamsElementType), (int)expandedParamsConstValues.size());
 		auto constArray = mModule->mBfIRBuilder->CreateConstArray(arrayType, expandedParamsConstValues);
 		llvmArgs.push_back(constArray);
-	}
+	}	
 
 	return true;
 }

+ 1 - 0
IDEHelper/Compiler/BfConstResolver.h

@@ -15,6 +15,7 @@ enum BfConstResolveFlags
 	BfConstResolveFlag_ExplicitCast = 1,
 	BfConstResolveFlag_NoCast = 2,
 	BfConstResolveFlag_AllowSoftFail = 4,
+	BfConstResolveFlag_RemapFromStringId = 8
 };
 
 class BfConstResolver : public BfExprEvaluator

+ 45 - 7
IDEHelper/Compiler/BfExprEvaluator.cpp

@@ -17351,6 +17351,30 @@ bool BfExprEvaluator::CheckConstCompare(BfBinaryOp binaryOp, BfAstNode* opToken,
 	return false;
 }
 
+void BfExprEvaluator::AddStrings(const BfTypedValue& leftValue, const BfTypedValue& rightValue, BfAstNode* refNode)
+{
+	if ((leftValue.mValue.IsConst()) && (rightValue.mValue.IsConst()))
+	{
+		String* lhsStr = mModule->GetStringPoolString(leftValue.mValue, mModule->mBfIRBuilder);
+		String* rhsStr = mModule->GetStringPoolString(rightValue.mValue, mModule->mBfIRBuilder);
+
+		if ((lhsStr != NULL) && (rhsStr != NULL))
+		{
+			String resultStr = *lhsStr + *rhsStr;
+
+			BfVariant variant;
+			variant.mTypeCode = BfTypeCode_CharPtr;
+			variant.mString = &resultStr;
+
+			GetLiteral(refNode, variant);
+			return;
+		}
+	}
+
+	mModule->Fail("Strings can only be added when they are constants. Consider allocating a string and using Concat.", refNode);
+	return;
+}
+
 void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNode* rightExpression, BfBinaryOp binaryOp, BfAstNode* opToken, BfBinOpFlags flags, BfTypedValue leftValue, BfTypedValue rightValue)
 {
 	bool noClassify = (flags & BfBinOpFlag_NoClassify) != 0;
@@ -17905,6 +17929,13 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
 		
 	if (resultType->IsPointer() && otherType->IsPointer())
 	{
+		if ((binaryOp == BfBinaryOp_Add) && (resultType == otherType) &&
+			(resultType->GetUnderlyingType() == mModule->GetPrimitiveType(BfTypeCode_Char8)))			
+		{
+			AddStrings(leftValue, rightValue, opToken);
+			return;
+		}
+
 		//TODO: Allow all pointer comparisons, but only allow SUBTRACTION between equal pointer types
 		if (binaryOp == BfBinaryOp_Subtract)
 		{			
@@ -17993,17 +18024,24 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
 		return;
 	}	
 	
+	
+
 	if ((resultType->IsFunction()) || (resultType->IsPointer()) || (resultType->IsObject()) || (resultType->IsInterface()) || (resultType->IsGenericParam()))
 	{
-		//if ((resultType->IsFunction()) || (resultType->IsObject()) || (resultType->IsInterface()) || (resultType->IsGenericParam()))
+		if ((binaryOp == BfBinaryOp_Add) && 
+			(resultType->IsInstanceOf(mModule->mCompiler->mStringTypeDef)) && 
+			(otherType->IsInstanceOf(mModule->mCompiler->mStringTypeDef)))
 		{
-			if ((binaryOp != BfBinaryOp_Equality) && (binaryOp != BfBinaryOp_InEquality))
-			{
-				//mModule->Fail("Invalid operation for objects", opToken);
-				_OpFail();
-				return;
-			}
+			AddStrings(leftValue, rightValue, opToken);			
+			return;
 		}
+		
+		if ((binaryOp != BfBinaryOp_Equality) && (binaryOp != BfBinaryOp_InEquality))
+		{
+			//mModule->Fail("Invalid operation for objects", opToken);
+			_OpFail();
+			return;
+		}		
 
 		if (resultType->IsInterface())
 		{

+ 1 - 0
IDEHelper/Compiler/BfExprEvaluator.h

@@ -346,6 +346,7 @@ public:
 	void LookupQualifiedStaticField(BfQualifiedNameNode* nameNode, bool ignoreIdentifierNotFoundError);	
 	void LookupQualifiedStaticField(BfAstNode* nameNode, BfIdentifierNode* nameLeft, BfIdentifierNode* nameRight, bool ignoreIdentifierNotFoundError);
 	bool CheckConstCompare(BfBinaryOp binaryOp, BfAstNode* opToken, const BfTypedValue& leftValue, const BfTypedValue& rightValue);
+	void AddStrings(const BfTypedValue& leftValue, const BfTypedValue& rightValue, BfAstNode* refNode);
 	void PerformBinaryOperation(BfType* resultType, BfIRValue convLeftValue, BfIRValue convRightValue, BfBinaryOp binaryOp, BfAstNode* opToken);
 	void PerformBinaryOperation(BfAstNode* leftExpression, BfAstNode* rightExpression, BfBinaryOp binaryOp, BfAstNode* opToken, BfBinOpFlags flags, BfTypedValue leftValue, BfTypedValue rightValue);
 	void PerformBinaryOperation(BfExpression* leftNode, BfExpression* rightNode, BfBinaryOp binaryOp, BfTokenNode* opToken, BfBinOpFlags flags, BfTypedValue leftValue);

+ 34 - 5
IDEHelper/Compiler/BfIRBuilder.cpp

@@ -1736,10 +1736,16 @@ void BfIRBuilder::Write(BfTypeCode typeCode)
 	mStream.Write((uint8)typeCode);	
 }
 
-void BfIRBuilder::Write(BfIRTypeData type)
+void BfIRBuilder::Write(const BfIRTypeData& type)
 {
 	mStream.Write((uint8)type.mKind);
-	if (type.mKind != BfIRTypeData::TypeKind_None)
+	if (type.mKind == BfIRTypeData::TypeKind_SizedArray)
+	{
+		auto sizedArrayType = (BfConstantSizedArrayType*)GetConstantById(type.mId);
+		Write(sizedArrayType->mType);
+		WriteSLEB128(sizedArrayType->mLength);
+	}
+	else if (type.mKind != BfIRTypeData::TypeKind_None)
 		WriteSLEB128(type.mId);
 }
  
@@ -2423,6 +2429,12 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
 									staticValue = ConstToMemory(staticValue);
 									wasMadeAddr = true;									
 								}
+								else if (resolvedFieldType->IsPointer())
+								{
+									int stringId = constant->mInt32;
+									const StringImpl& str = mModule->mContext->mStringObjectIdMap[stringId].mString;
+									staticValue = mModule->GetStringCharPtr(str);
+								}
 								else
 								{
 									int stringId = constant->mInt32;									
@@ -3260,9 +3272,26 @@ BfIRType BfIRBuilder::GetPointerTo(BfIRType type)
 
 BfIRType BfIRBuilder::GetSizedArrayType(BfIRType elementType, int length)
 {
-	BfIRType retType = WriteCmd(BfIRCmd_GetSizedArrayType, elementType, length);
-	NEW_CMD_INSERTED_IRTYPE;
-	return retType;
+	if (mIgnoreWrites)
+	{
+		auto constSizedArrayType = mTempAlloc.Alloc<BfConstantSizedArrayType>();
+		constSizedArrayType->mConstType = BfConstType_SizedArrayType;
+		constSizedArrayType->mType = elementType;
+		constSizedArrayType->mLength = length;
+
+		int chunkId = mTempAlloc.GetChunkedId(constSizedArrayType);
+
+		BfIRType retType;
+		retType.mKind = BfIRTypeData::TypeKind_SizedArray;
+		retType.mId = chunkId;
+		return retType;
+	}
+	else
+	{
+		BfIRType retType = WriteCmd(BfIRCmd_GetSizedArrayType, elementType, length);
+		NEW_CMD_INSERTED_IRTYPE;
+		return retType;
+	}
 }
 
 BfIRValue BfIRBuilder::CreateConstStruct(BfIRType type, const BfSizedArray<BfIRValue>& values)

+ 12 - 3
IDEHelper/Compiler/BfIRBuilder.h

@@ -125,7 +125,8 @@ enum BfConstType
 	BfConstType_TypeOf,
 	BfConstType_AggZero,
 	BfConstType_Array,
-	BfConstType_Undef
+	BfConstType_Undef,
+	BfConstType_SizedArrayType
 
 };
 
@@ -543,6 +544,7 @@ struct BfIRTypeData
 		TypeKind_TypeInstId,
 		TypeKind_TypeInstPtrId,
 		TypeKind_Stream,
+		TypeKind_SizedArray
 	};
 
 	TypeKind mKind;
@@ -766,6 +768,13 @@ public:
 	}
 };
 
+struct BfConstantSizedArrayType
+{
+	BfConstType mConstType;
+	BfIRType mType;
+	intptr mLength;
+};
+
 struct BfConstantUndef
 {
 	BfConstType mConstType;
@@ -894,9 +903,9 @@ public:
 	void Write(int val);
 	void Write(int64 val);
 	void Write(const StringImpl& str);
-	void Write(const BfIRValue& irValue);	
+	void Write(const BfIRValue& irValue);
 	void Write(BfTypeCode typeCode);
-	void Write(BfIRTypeData type);	
+	void Write(const BfIRTypeData& type);	
 	void Write(BfIRFunctionType func);
 	void Write(BfIRFunction funcType);
 	void Write(BfIRBlock block);

+ 8 - 0
IDEHelper/Compiler/BfIRCodeGen.cpp

@@ -510,6 +510,14 @@ void BfIRCodeGen::Read(llvm::Type*& llvmType)
 		return;
 	}
 
+	if (typeKind == BfIRType::TypeKind::TypeKind_SizedArray)
+	{
+		CMD_PARAM(llvm::Type*, elementType);
+		CMD_PARAM(int, length);
+		llvmType = llvm::ArrayType::get(elementType, length);
+		return;
+	}
+
 	int typeId = (int)ReadSLEB128();
 	auto& typeEntry = GetTypeEntry(typeId);
 	if (typeKind == BfIRType::TypeKind::TypeKind_TypeId)

+ 6 - 11
IDEHelper/Compiler/BfModule.cpp

@@ -1442,19 +1442,15 @@ BfIRValue BfModule::CreateStringCharPtr(const StringImpl& str, int stringId, boo
 {	
 	String stringDataName = StrFormat("__bfStrData%d", stringId);
 
-	BfIRType strCharType;
-	//
-	{		
-		SetAndRestoreValue<bool> prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, mWantsIRIgnoreWrites);
-		strCharType = mBfIRBuilder->GetSizedArrayType(mBfIRBuilder->GetPrimitiveType(BfTypeCode_Char8), (int)str.length() + 1);
-	}
-
+	auto charType = GetPrimitiveType(BfTypeCode_Char8);
+ 	BfIRType irStrCharType = mBfIRBuilder->GetSizedArrayType(mBfIRBuilder->MapType(charType), (int)str.length() + 1);
+ 	
 	BfIRValue strConstant;
 	if (define)
 	{		
 		strConstant = mBfIRBuilder->CreateConstString(str);		
 	}
-	BfIRValue gv = mBfIRBuilder->CreateGlobalVariable(strCharType,
+	BfIRValue gv = mBfIRBuilder->CreateGlobalVariable(irStrCharType,
 		true, BfIRLinkageType_External,
 		strConstant, stringDataName);
 
@@ -1501,7 +1497,8 @@ BfIRValue BfModule::CreateStringObjectValue(const StringImpl& str, int stringId,
 		
 		stringValData = mBfIRBuilder->CreateConstStruct(mBfIRBuilder->MapTypeInst(stringTypeInst, BfIRPopulateType_Full), typeValueParams);
 	}
-	
+		
+	mBfIRBuilder->PopulateType(stringTypeInst);
 	auto stringValLiteral = mBfIRBuilder->CreateGlobalVariable(
 		mBfIRBuilder->MapTypeInst(stringTypeInst),
 		true,
@@ -3283,8 +3280,6 @@ void BfModule::ResolveConstField(BfTypeInstance* typeInstance, BfFieldInstance*
 		SetAndRestoreValue<bool> prevIgnoreWrite(mBfIRBuilder->mIgnoreWrites, true);
 		SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, NULL);
 		
-		BfConstResolver constResolver(this);
-
 		BfMethodState methodState;
 		SetAndRestoreValue<BfMethodState*> prevMethodState(mCurMethodState, &methodState);
 		methodState.mTempKind = BfMethodState::TempKind_Static;

+ 3 - 1
IDEHelper/Compiler/BfResolvedTypeUtils.h

@@ -409,10 +409,11 @@ public:
 	BfTypeInstance* FindUnderlyingTypeInstance();
 
 	virtual BfModule* GetModule();
-
+	
 	int GetStride() { return BF_ALIGN(mSize, mAlign); }	
 	bool IsSizeAligned() { return (mSize == 0) || (mSize % mAlign == 0); }
 	virtual bool NeedsExplicitAlignment() { return !IsSizeAligned(); }
+	virtual bool IsInstanceOf(BfTypeDef* typeDef) { return false; }
 
 	virtual bool HasBeenReferenced() { return mDefineState != BfTypeDefineState_Undefined; }
 	virtual bool HasTypeFailed() { return false; }
@@ -1671,6 +1672,7 @@ public:
 	
 	~BfTypeInstance();	
 
+	virtual bool IsInstanceOf(BfTypeDef* typeDef) { return typeDef == mTypeDef; }
 	virtual BfModule* GetModule() override { return mModule; }
 	virtual BfTypeInstance* ToTypeInstance() override { return this; }
 	virtual bool IsDependentOnUnderlyingType() override { return true; }

+ 2 - 2
IDEHelper/Compiler/BfStmtEvaluator.cpp

@@ -1479,9 +1479,9 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD
 			if (isConst)
 			{
 				BfConstResolver constResolver(this);
-				initValue = constResolver.Resolve(varDecl->mInitializer, resolvedType);
+				initValue = constResolver.Resolve(varDecl->mInitializer, resolvedType, BfConstResolveFlag_RemapFromStringId);
 				if (!initValue)
-					initValue = GetDefaultTypedValue(resolvedType);
+					initValue = GetDefaultTypedValue(resolvedType);				
 			}
 			else if (varDecl->mInitializer->IsA<BfUninitializedExpression>())				
 			{				

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

@@ -240,5 +240,20 @@ namespace Tests
 			Test.Assert(iVal == 123);
 			Test.Assert(iVal == 123.0f);
 		}
+
+		const String cStrD = "D";
+		const char8* cStrPD = "D";
+
+		[Test]
+		public static void TestStringOp()
+		{
+			const String cStr1 = "A" + "B";
+			const String cStr2 = cStr1 + "C" + cStrD;
+			Test.Assert(cStr2 == "ABCD");
+
+			const char8* cStr3 = "A" + "B";
+			const char8* cStr4 = cStr1 + "C" + cStrPD;
+			Test.Assert(StringView(cStr4) == "ABCD");
+		}
 	}
 }