Skip to content

Commit

Permalink
Refactor foreachApplyUtf to remove duplicate array literal logic
Browse files Browse the repository at this point in the history
  • Loading branch information
dkorpel authored and dlang-bot committed Jan 11, 2024
1 parent e64aaee commit 713879e
Showing 1 changed file with 36 additions and 86 deletions.
122 changes: 36 additions & 86 deletions compiler/src/dmd/dinterpret.d
Original file line number Diff line number Diff line change
Expand Up @@ -7270,6 +7270,33 @@ private Expression interpret_aaApply(UnionExp* pue, InterState* istate, Expressi
return eresult;
}

/// Returns: equivalent `StringExp` from `ArrayLiteralExp ale` containing only `IntegerExp` elements
StringExp arrayLiteralToString(ArrayLiteralExp ale)
{
const len = ale.elements ? ale.elements.length : 0;
const size = ale.type.nextOf().size();

StringExp impl(T)()
{
T[] result = new T[len];
foreach (i; 0 .. len)
result[i] = cast(T) (*ale.elements)[i].isIntegerExp().getInteger();
return new StringExp(ale.loc, result[], len, cast(ubyte) size);
}

switch (size)
{
case 1:
return impl!char();
case 2:
return impl!wchar();
case 4:
return impl!dchar();
default:
assert(0);
}
}

/* Decoding UTF strings for foreach loops. Duplicates the functionality of
* the twelve _aApplyXXn functions in aApply.d in the runtime.
*/
Expand Down Expand Up @@ -7306,8 +7333,10 @@ private Expression foreachApplyUtf(UnionExp* pue, InterState* istate, Expression
str = resolveSlice(str, &strTmp);

auto se = str.isStringExp();
auto ale = str.isArrayLiteralExp();
if (!se && !ale)
if (auto ale = str.isArrayLiteralExp())
se = arrayLiteralToString(ale);

if (!se)
{
error(str.loc, "CTFE internal error: cannot foreach `%s`", str.toChars());
return CTFEExp.cantexp;
Expand All @@ -7316,7 +7345,7 @@ private Expression foreachApplyUtf(UnionExp* pue, InterState* istate, Expression

Expression eresult = null; // ded-store to prevent spurious warning

// Buffers for encoding; also used for decoding array literals
// Buffers for encoding
char[4] utf8buf = void;
wchar[2] utf16buf = void;

Expand All @@ -7330,90 +7359,11 @@ private Expression foreachApplyUtf(UnionExp* pue, InterState* istate, Expression
dchar rawvalue; // Holds the decoded dchar
size_t currentIndex = indx; // The index of the decoded character

if (ale)
{
// If it is an array literal, copy the code points into the buffer
size_t buflen = 1; // #code points in the buffer
size_t n = 1; // #code points in this char
size_t sz = cast(size_t)ale.type.nextOf().size();

switch (sz)
{
case 1:
if (rvs)
{
// find the start of the string
--indx;
buflen = 1;
while (indx > 0 && buflen < 4)
{
Expression r = (*ale.elements)[indx];
char x = cast(char)r.isIntegerExp().getInteger();
if ((x & 0xC0) != 0x80)
break;
--indx;
++buflen;
}
}
else
buflen = (indx + 4 > len) ? len - indx : 4;
for (size_t i = 0; i < buflen; ++i)
{
Expression r = (*ale.elements)[indx + i];
utf8buf[i] = cast(char)r.isIntegerExp().getInteger();
}
n = 0;
errmsg = utf_decodeChar(utf8buf[0 .. buflen], n, rawvalue);
break;

case 2:
if (rvs)
{
// find the start of the string
--indx;
buflen = 1;
Expression r = (*ale.elements)[indx];
ushort x = cast(ushort)r.isIntegerExp().getInteger();
if (indx > 0 && x >= 0xDC00 && x <= 0xDFFF)
{
--indx;
++buflen;
}
}
else
buflen = (indx + 2 > len) ? len - indx : 2;
for (size_t i = 0; i < buflen; ++i)
{
Expression r = (*ale.elements)[indx + i];
utf16buf[i] = cast(ushort)r.isIntegerExp().getInteger();
}
n = 0;
errmsg = utf_decodeWchar(utf16buf[0 .. buflen], n, rawvalue);
break;

case 4:
{
if (rvs)
--indx;
Expression r = (*ale.elements)[indx];
rawvalue = cast(dchar)r.isIntegerExp().getInteger();
n = 1;
}
break;
// String literals
size_t saveindx; // used for reverse iteration

default:
assert(0);
}
if (!rvs)
indx += n;
}
else
switch (se.sz)
{
// String literals
size_t saveindx; // used for reverse iteration

switch (se.sz)
{
case 1:
{
if (rvs)
Expand Down Expand Up @@ -7457,8 +7407,8 @@ private Expression foreachApplyUtf(UnionExp* pue, InterState* istate, Expression

default:
assert(0);
}
}

if (errmsg)
{
error(deleg.loc, "`%.*s`", cast(int)errmsg.length, errmsg.ptr);
Expand Down

0 comments on commit 713879e

Please sign in to comment.