mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 21:21:48 +03:00
Make hex strings implicitly convert to integer arrays
This commit is contained in:
parent
3e9bc4ee17
commit
4e3cc5c6c6
6 changed files with 34 additions and 38 deletions
|
@ -1,27 +1,23 @@
|
||||||
Hex strings can now be cast to integer arrays
|
Hex strings now convert to integer arrays
|
||||||
|
|
||||||
Hex strings are the most efficient way to embed binary data into source files.
|
Hex strings are the most efficient way to embed binary data into source files.
|
||||||
However, they couldn't easily be used to initialize a `short[]`, `int[]` or `long[]` because re-interpret casting arrays is not allowed during CTFE.
|
However, they couldn't easily be used to initialize a `short[]`, `int[]` or `long[]` because re-interpret casting arrays is not allowed during CTFE.
|
||||||
Now, hex strings can be cast to integer arrays with element types larger than `byte`.
|
Now, hex strings implicitly convert to all integer arrays.
|
||||||
A big endian byte order is assumed, consistent with how integer literals are written.
|
A big endian byte order is assumed, consistent with how integer literals are written.
|
||||||
|
|
||||||
---
|
---
|
||||||
immutable uint[] data = cast(immutable uint[]) x"AABBCCDD";
|
immutable uint[] data = x"AABBCCDD";
|
||||||
|
|
||||||
static assert(data[0] == 0xAABBCCDD);
|
static assert(data[0] == 0xAABBCCDD);
|
||||||
---
|
---
|
||||||
|
|
||||||
Character postfixes can now also be used for integers of size 2 or 4, while an `L` postfix can be used for size 8:
|
Character postfixes can now also be used to explicitly set an element size of 2 or 4.
|
||||||
|
|
||||||
---
|
---
|
||||||
immutable ushort[] f = x"80 3F"w;
|
immutable ushort[] f = x"80 3F"w;
|
||||||
static assert(f[0] == 0x803F);
|
static assert(f[0] == 0x803F);
|
||||||
|
|
||||||
immutable int[] g = x"80 35 FF FD"d;
|
immutable ubyte[] g = x"80 35"w; // error: size mismatch
|
||||||
static assert(g[0] == 0x803FFFFD);
|
|
||||||
|
|
||||||
auto h = x"0011 2233 4455 6677"L;
|
|
||||||
static assert(h[0] == 0x0011_2233_4455_6677);
|
|
||||||
static assert(is(typeof(h) == immutable ulong[]));
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Formerly, they would pad each byte with 1 or 3 zeros, which did not serve a purpose (See [Issue 24363](https://issues.dlang.org/show_bug.cgi?id=24363)).
|
Formerly, they would pad each byte with 1 or 3 zeros, which did not serve a purpose (See [Issue 24363](https://issues.dlang.org/show_bug.cgi?id=24363)).
|
||||||
|
|
|
@ -703,6 +703,11 @@ MATCH implicitConvTo(Expression e, Type t)
|
||||||
return MATCH.nomatch;
|
return MATCH.nomatch;
|
||||||
m = MATCH.constant;
|
m = MATCH.constant;
|
||||||
}
|
}
|
||||||
|
if (e.hexString && tn.isintegral && (tn.size == e.sz || (!e.committed && (e.len % tn.size) == 0)))
|
||||||
|
{
|
||||||
|
m = MATCH.convert;
|
||||||
|
return m;
|
||||||
|
}
|
||||||
if (!e.committed)
|
if (!e.committed)
|
||||||
{
|
{
|
||||||
switch (tn.ty)
|
switch (tn.ty)
|
||||||
|
@ -719,9 +724,6 @@ MATCH implicitConvTo(Expression e, Type t)
|
||||||
if (e.postfix != 'd')
|
if (e.postfix != 'd')
|
||||||
m = MATCH.convert;
|
m = MATCH.convert;
|
||||||
return m;
|
return m;
|
||||||
case Tint8:
|
|
||||||
case Tuns8:
|
|
||||||
break;
|
|
||||||
case Tenum:
|
case Tenum:
|
||||||
if (tn.isTypeEnum().sym.isSpecial())
|
if (tn.isTypeEnum().sym.isSpecial())
|
||||||
{
|
{
|
||||||
|
@ -735,14 +737,6 @@ MATCH implicitConvTo(Expression e, Type t)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (e.hexString)
|
|
||||||
{
|
|
||||||
if (tn.isintegral && tn.size == e.sz)
|
|
||||||
{
|
|
||||||
m = MATCH.convert;
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -1884,6 +1878,19 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
|
||||||
Type tb = t.toBasetype();
|
Type tb = t.toBasetype();
|
||||||
Type typeb = e.type.toBasetype();
|
Type typeb = e.type.toBasetype();
|
||||||
|
|
||||||
|
if (e.hexString && !e.committed)
|
||||||
|
{
|
||||||
|
const szx = cast(ubyte) tb.nextOf().size();
|
||||||
|
if (szx != se.sz && (e.len % szx) == 0)
|
||||||
|
{
|
||||||
|
import dmd.utils: arrayCastBigEndian;
|
||||||
|
const data = cast(const ubyte[]) e.peekString();
|
||||||
|
se.setData(arrayCastBigEndian(data, szx).ptr, data.length / szx, szx);
|
||||||
|
se.type = t;
|
||||||
|
return se;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//printf("\ttype = %s\n", e.type.toChars());
|
//printf("\ttype = %s\n", e.type.toChars());
|
||||||
if (tb.ty == Tdelegate && typeb.ty != Tdelegate)
|
if (tb.ty == Tdelegate && typeb.ty != Tdelegate)
|
||||||
{
|
{
|
||||||
|
|
|
@ -4245,22 +4245,22 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
||||||
|
|
||||||
if (e.hexString)
|
if (e.hexString)
|
||||||
{
|
{
|
||||||
const data = cast(const ubyte[]) e.peekString();
|
const data = cast(const ubyte[]) e.peekString(); // peek before size is set to something larger than 1
|
||||||
switch (e.postfix)
|
switch (e.postfix)
|
||||||
{
|
{
|
||||||
case 'L':
|
|
||||||
e.sz = 8;
|
|
||||||
e.type = Type.tuns64.immutableOf().arrayOf();
|
|
||||||
break;
|
|
||||||
case 'd':
|
case 'd':
|
||||||
|
e.committed = true;
|
||||||
e.sz = 4;
|
e.sz = 4;
|
||||||
e.type = Type.tdstring;
|
e.type = Type.tdstring;
|
||||||
break;
|
break;
|
||||||
case 'w':
|
case 'w':
|
||||||
|
e.committed = true;
|
||||||
e.sz = 2;
|
e.sz = 2;
|
||||||
e.type = Type.twstring;
|
e.type = Type.twstring;
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
|
e.committed = true;
|
||||||
|
goto default;
|
||||||
default:
|
default:
|
||||||
e.type = Type.tstring;
|
e.type = Type.tstring;
|
||||||
e.sz = 1;
|
e.sz = 1;
|
||||||
|
@ -4271,7 +4271,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
||||||
e.type.toChars(), e.sz, cast(int) e.len);
|
e.type.toChars(), e.sz, cast(int) e.len);
|
||||||
|
|
||||||
e.setData(arrayCastBigEndian(data, e.sz).ptr, e.len / e.sz, e.sz);
|
e.setData(arrayCastBigEndian(data, e.sz).ptr, e.len / e.sz, e.sz);
|
||||||
e.committed = true;
|
|
||||||
}
|
}
|
||||||
else switch (e.postfix)
|
else switch (e.postfix)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1569,12 +1569,6 @@ class Lexer
|
||||||
}
|
}
|
||||||
t.setString(stringbuffer);
|
t.setString(stringbuffer);
|
||||||
stringPostfix(t);
|
stringPostfix(t);
|
||||||
if (*p == 'L')
|
|
||||||
{
|
|
||||||
t.postfix = 'L';
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TOK.hexadecimalString;
|
return TOK.hexadecimalString;
|
||||||
default:
|
default:
|
||||||
if (c >= '0' && c <= '9')
|
if (c >= '0' && c <= '9')
|
||||||
|
|
|
@ -13,10 +13,10 @@ fail_compilation/hexstring.d(39): Error: array cast from `string` to `immutable(
|
||||||
fail_compilation/hexstring.d(39): perhaps remove postfix `c` from hex string
|
fail_compilation/hexstring.d(39): perhaps remove postfix `c` from hex string
|
||||||
fail_compilation/hexstring.d(40): Error: hex string with `dstring` type needs to be multiple of 4 bytes, not 5
|
fail_compilation/hexstring.d(40): Error: hex string with `dstring` type needs to be multiple of 4 bytes, not 5
|
||||||
fail_compilation/hexstring.d(41): Error: cannot implicitly convert expression `x"44332211"d` of type `dstring` to `immutable(float[])`
|
fail_compilation/hexstring.d(41): Error: cannot implicitly convert expression `x"44332211"d` of type `dstring` to `immutable(float[])`
|
||||||
|
fail_compilation/hexstring.d(42): Error: cannot implicitly convert expression `x"2211"w` of type `wstring` to `immutable(ubyte[])`
|
||||||
fail_compilation/hexstring.d(28): Error: cannot implicitly convert expression `x"123F"` of type `string` to `ubyte[]`
|
fail_compilation/hexstring.d(28): Error: cannot implicitly convert expression `x"123F"` of type `string` to `ubyte[]`
|
||||||
---
|
---
|
||||||
*/
|
*/
|
||||||
|
|
||||||
immutable ubyte[] s0 = x"123F";
|
immutable ubyte[] s0 = x"123F";
|
||||||
static assert(s0[0] == 0x12);
|
static assert(s0[0] == 0x12);
|
||||||
static assert(s0[1] == 0x3F);
|
static assert(s0[1] == 0x3F);
|
||||||
|
@ -39,3 +39,4 @@ immutable ushort[] f10 = cast(immutable ushort[]) (x"1122" ~ "");
|
||||||
immutable uint[] f11 = cast(immutable uint[]) x"AABBCCDD"c;
|
immutable uint[] f11 = cast(immutable uint[]) x"AABBCCDD"c;
|
||||||
immutable uint[] f12 = x"1122334455"d;
|
immutable uint[] f12 = x"1122334455"d;
|
||||||
immutable float[] f13 = x"11223344"d;
|
immutable float[] f13 = x"11223344"d;
|
||||||
|
immutable ubyte[] f14 = x"1122"w;
|
||||||
|
|
|
@ -247,14 +247,13 @@ void testHexstring()
|
||||||
static assert(x[0] == 0xFFAADDEE);
|
static assert(x[0] == 0xFFAADDEE);
|
||||||
assert(x[0] == 0xFFAADDEE);
|
assert(x[0] == 0xFFAADDEE);
|
||||||
|
|
||||||
static assert(is(typeof(x""L) == immutable(ulong)[]));
|
static immutable ulong[] y = x"1122334455667788AABBCCDDEEFF0099";
|
||||||
static immutable ulong[] y = x"1122334455667788AABBCCDDEEFF0099"L;
|
|
||||||
static assert(y[0] == 0x1122334455667788);
|
static assert(y[0] == 0x1122334455667788);
|
||||||
static assert(y[1] == 0xAABBCCDDEEFF0099);
|
static assert(y[1] == 0xAABBCCDDEEFF0099);
|
||||||
assert(y[0] == 0x1122334455667788);
|
assert(y[0] == 0x1122334455667788);
|
||||||
assert(y[1] == 0xAABBCCDDEEFF0099);
|
assert(y[1] == 0xAABBCCDDEEFF0099);
|
||||||
|
|
||||||
immutable long[] c = x"1122334455667788AABBCCDDEEFF0099"L;
|
immutable long[] c = x"1122334455667788AABBCCDDEEFF0099";
|
||||||
assert(c[0] == 0x1122334455667788);
|
assert(c[0] == 0x1122334455667788);
|
||||||
assert(c[1] == 0xAABBCCDDEEFF0099);
|
assert(c[1] == 0xAABBCCDDEEFF0099);
|
||||||
|
|
||||||
|
@ -264,7 +263,7 @@ void testHexstring()
|
||||||
|
|
||||||
// Test printing StringExp with size 8
|
// Test printing StringExp with size 8
|
||||||
enum toStr(immutable ulong[] v) = v.stringof;
|
enum toStr(immutable ulong[] v) = v.stringof;
|
||||||
static assert(toStr!y == `x"88776655443322119900FFEEDDCCBBAA"L`);
|
static assert(toStr!y == `x"88776655443322119900FFEEDDCCBBAA"`);
|
||||||
|
|
||||||
// Hex string postfixes
|
// Hex string postfixes
|
||||||
// https://issues.dlang.org/show_bug.cgi?id=24363
|
// https://issues.dlang.org/show_bug.cgi?id=24363
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue