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

Improved string-to-sized-array casts and initializations

This commit is contained in:
Brian Fiete 2022-09-05 06:28:23 -07:00
parent 1320b495d2
commit c6f2798db7
4 changed files with 55 additions and 1 deletions

View file

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

View file

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

View file

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

View file

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