1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 11:38:21 +02:00

Added constant string appending with + operator, const string fixes

This commit is contained in:
Brian Fiete 2020-02-28 09:20:43 -08:00
parent 41cb0052b2
commit c92bc523db
14 changed files with 158 additions and 34 deletions

View file

@ -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)

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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;
}

View file

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

View file

@ -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())
{

View file

@ -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);

View file

@ -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)

View file

@ -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);

View file

@ -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)

View file

@ -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;

View file

@ -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; }

View file

@ -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>())
{

View file

@ -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");
}
}
}