mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 12:32:20 +02:00
Improved string-to-sized-array casts and initializations
This commit is contained in:
parent
1320b495d2
commit
c6f2798db7
4 changed files with 55 additions and 1 deletions
|
@ -3942,9 +3942,11 @@ void BfExprEvaluator::GetLiteral(BfAstNode* refNode, const BfVariant& variant)
|
||||||
if ((mExpectingType != NULL) && (mExpectingType->IsSizedArray()))
|
if ((mExpectingType != NULL) && (mExpectingType->IsSizedArray()))
|
||||||
{
|
{
|
||||||
auto sizedArray = (BfSizedArrayType*)mExpectingType;
|
auto sizedArray = (BfSizedArrayType*)mExpectingType;
|
||||||
|
|
||||||
if (sizedArray->mElementType == mModule->GetPrimitiveType(BfTypeCode_Char8))
|
if (sizedArray->mElementType == mModule->GetPrimitiveType(BfTypeCode_Char8))
|
||||||
{
|
{
|
||||||
|
if (sizedArray->IsUndefSizedArray())
|
||||||
|
sizedArray = mModule->CreateSizedArrayType(sizedArray->mElementType, variant.mString->GetLength());
|
||||||
|
|
||||||
if (variant.mString->GetLength() > sizedArray->mElementCount)
|
if (variant.mString->GetLength() > sizedArray->mElementCount)
|
||||||
{
|
{
|
||||||
mModule->Fail(StrFormat("String literal is too long to fit into '%s'", mModule->TypeToString(sizedArray).c_str()), refNode);
|
mModule->Fail(StrFormat("String literal is too long to fit into '%s'", mModule->TypeToString(sizedArray).c_str()), refNode);
|
||||||
|
|
|
@ -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<BfIRValue> 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
|
// Check user-defined operators
|
||||||
|
|
|
@ -1750,6 +1750,17 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD
|
||||||
BfExprEvaluator valExprEvaluator(this);
|
BfExprEvaluator valExprEvaluator(this);
|
||||||
valExprEvaluator.mAllowReadOnlyReference = isReadOnly;
|
valExprEvaluator.mAllowReadOnlyReference = isReadOnly;
|
||||||
initValue = CreateValueFromExpression(valExprEvaluator, varDecl->mInitializer, expectedType, (BfEvalExprFlags)(BfEvalExprFlags_NoCast | BfEvalExprFlags_AllowRefExpr | BfEvalExprFlags_VariableDeclaration));
|
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);
|
auto boolType = GetPrimitiveType(BfTypeCode_Boolean);
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,8 @@ namespace Tests
|
||||||
{
|
{
|
||||||
class Strings
|
class Strings
|
||||||
{
|
{
|
||||||
|
const String cString = "Abc";
|
||||||
|
|
||||||
static void FormatString(String outString, String format, params Object[] args)
|
static void FormatString(String outString, String format, params Object[] args)
|
||||||
{
|
{
|
||||||
outString.AppendF(format, params args);
|
outString.AppendF(format, params args);
|
||||||
|
@ -32,6 +34,11 @@ namespace Tests
|
||||||
StringView sv = "Abcd";
|
StringView sv = "Abcd";
|
||||||
sv.Length--;
|
sv.Length--;
|
||||||
Test.Assert(sv == "Abc");
|
Test.Assert(sv == "Abc");
|
||||||
|
|
||||||
|
char8[?] arr0 = "Abcd";
|
||||||
|
char8[?] arr1 = cString;
|
||||||
|
Test.Assert(arr0.Count == 4);
|
||||||
|
Test.Assert(arr1.Count == 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue