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:
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()))
|
||||
{
|
||||
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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue