diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 9a1a4afa..b14fb4f6 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -3942,9 +3942,11 @@ void BfExprEvaluator::GetLiteral(BfAstNode* refNode, const BfVariant& variant) if ((mExpectingType != NULL) && (mExpectingType->IsSizedArray())) { auto sizedArray = (BfSizedArrayType*)mExpectingType; - if (sizedArray->mElementType == mModule->GetPrimitiveType(BfTypeCode_Char8)) { + if (sizedArray->IsUndefSizedArray()) + sizedArray = mModule->CreateSizedArrayType(sizedArray->mElementType, variant.mString->GetLength()); + if (variant.mString->GetLength() > sizedArray->mElementCount) { mModule->Fail(StrFormat("String literal is too long to fit into '%s'", mModule->TypeToString(sizedArray).c_str()), refNode); diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 34684377..b00bf11e 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -14006,6 +14006,40 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp } } } + else if (toType->IsSizedArray()) + { + auto sizedArray = (BfSizedArrayType*)toType; + if (sizedArray->mElementType == GetPrimitiveType(BfTypeCode_Char8)) + { + int stringId = GetStringPoolIdx(typedVal.mValue, mBfIRBuilder); + if (stringId >= 0) + { + BfStringPoolEntry* entry = NULL; + if (mContext->mStringObjectIdMap.TryGetValue(stringId, &entry)) + { + String& string = entry->mString; + + if (string.GetLength() > sizedArray->mElementCount) + { + if (!ignoreErrors) + Fail(StrFormat("String literal is too long to fit into '%s'", TypeToString(sizedArray).c_str()), srcNode); + } + + Array charValues; + for (int i = 0; i < (int)BF_MIN(string.GetLength(), sizedArray->mElementCount); i++) + { + char c = string[i]; + charValues.Add(mBfIRBuilder->CreateConst(BfTypeCode_Char8, (int)(uint8)c)); + } + + if (sizedArray->mElementCount > charValues.size()) + charValues.Add(mBfIRBuilder->CreateConst(BfTypeCode_Char8, 0)); + + return mBfIRBuilder->CreateConstAgg(mBfIRBuilder->MapType(sizedArray), charValues); + } + } + } + } } // Check user-defined operators diff --git a/IDEHelper/Compiler/BfStmtEvaluator.cpp b/IDEHelper/Compiler/BfStmtEvaluator.cpp index 28ef11cd..2b379691 100644 --- a/IDEHelper/Compiler/BfStmtEvaluator.cpp +++ b/IDEHelper/Compiler/BfStmtEvaluator.cpp @@ -1750,6 +1750,17 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD BfExprEvaluator valExprEvaluator(this); valExprEvaluator.mAllowReadOnlyReference = isReadOnly; initValue = CreateValueFromExpression(valExprEvaluator, varDecl->mInitializer, expectedType, (BfEvalExprFlags)(BfEvalExprFlags_NoCast | BfEvalExprFlags_AllowRefExpr | BfEvalExprFlags_VariableDeclaration)); + + if ((initValue) && (resolvedType->IsUndefSizedArray())) + { + int stringId = GetStringPoolIdx(initValue.mValue, mBfIRBuilder); + if (stringId >= 0) + { + BfStringPoolEntry* entry = NULL; + if (mContext->mStringObjectIdMap.TryGetValue(stringId, &entry)) + resolvedType = CreateSizedArrayType(((BfSizedArrayType*)resolvedType)->mElementType, entry->mString.mLength); + } + } auto boolType = GetPrimitiveType(BfTypeCode_Boolean); diff --git a/IDEHelper/Tests/src/Strings.bf b/IDEHelper/Tests/src/Strings.bf index ce189508..2e00fd44 100644 --- a/IDEHelper/Tests/src/Strings.bf +++ b/IDEHelper/Tests/src/Strings.bf @@ -5,6 +5,8 @@ namespace Tests { class Strings { + const String cString = "Abc"; + static void FormatString(String outString, String format, params Object[] args) { outString.AppendF(format, params args); @@ -32,6 +34,11 @@ namespace Tests StringView sv = "Abcd"; sv.Length--; Test.Assert(sv == "Abc"); + + char8[?] arr0 = "Abcd"; + char8[?] arr1 = cString; + Test.Assert(arr0.Count == 4); + Test.Assert(arr1.Count == 3); } } }