ASCII art diagram converter: Difference between revisions
Content added Content deleted
(Added an assert to the D entry) |
(Updated D entry) |
||
Line 54: | Line 54: | ||
static void commitCurrent(ref uint anonCount, |
static void commitCurrent(ref uint anonCount, |
||
ref uint totalBits, |
ref uint totalBits, |
||
ref |
ref size_t currentBits, |
||
ref string code, |
ref string code, |
||
ref string currentName) pure @safe { |
ref string currentName) pure @safe { |
||
Line 79: | Line 79: | ||
//else if (currentBits <= ucent.sizeof * 8) |
//else if (currentBits <= ucent.sizeof * 8) |
||
// type = "ucent"; |
// type = "ucent"; |
||
else assert(0, "Too many bits for the item "~ currentName); |
else assert(0, "Too many bits for the item " ~ currentName); |
||
immutable byteOffset = totalBits / 8; |
immutable byteOffset = totalBits / 8; |
||
Line 90: | Line 90: | ||
code ~= "\t\t"; |
code ~= "\t\t"; |
||
if (currentBits == 1) { |
if (currentBits == 1) { |
||
code ~= format("return (_payload[%d] & (1 << (7-%d)))" |
code ~= format("return (_payload[%d] & (1 << (7-%d))) ? true : false;", |
||
" ? true : false;", |
|||
byteOffset, bitOffset); |
byteOffset, bitOffset); |
||
} else if (currentBits < 8) { |
} else if (currentBits < 8) { |
||
Line 97: | Line 96: | ||
mask <<= 7 - bitOffset - currentBits + 1; |
mask <<= 7 - bitOffset - currentBits + 1; |
||
code ~= format("return (_payload[%d] & 0b%08b) >> %d;", |
code ~= format("return (_payload[%d] & 0b%08b) >> %d;", |
||
byteOffset, mask, |
byteOffset, mask, 7 - bitOffset - currentBits + 1); |
||
7 - bitOffset - currentBits + 1); |
|||
} else { |
} else { |
||
assert(currentBits % 8 == 0); |
assert(currentBits % 8 == 0); |
||
Line 129: | Line 127: | ||
");\n\t\t"; |
");\n\t\t"; |
||
code~=format("_payload[%d] |= cast(ubyte) value << %d;", |
code~=format("_payload[%d] |= cast(ubyte) value << %d;", |
||
byteOffset, |
byteOffset, 7 - bitOffset - currentBits + 1); |
||
7 - bitOffset - currentBits + 1); |
|||
} else { |
} else { |
||
assert(currentBits % 8 == 0); |
assert(currentBits % 8 == 0); |
||
Line 157: | Line 154: | ||
immutable diagram = rawDiagram.strip; |
immutable diagram = rawDiagram.strip; |
||
size_t bitCountPerRow = 0, currentBits; |
|||
uint anonCount = 0, totalBits; |
|||
string currentName; |
string currentName; |
||
string code = "struct {\n"; // Anonymous. |
string code = "struct {\n"; // Anonymous. |
||
Line 165: | Line 163: | ||
line = line.strip; |
line = line.strip; |
||
if (line[0] == C.cross) { |
if (line[0] == C.cross) { |
||
commitCurrent(anonCount, totalBits, |
commitCurrent(anonCount, totalBits, currentBits, code, currentName); |
||
currentBits, code, currentName); |
|||
if (bitCountPerRow == 0) |
if (bitCountPerRow == 0) |
||
bitCountPerRow = |
bitCountPerRow = (line.length - 1) / cWidth; |
||
else |
else |
||
assert(bitCountPerRow == (line.length - 1) / cWidth); |
assert(bitCountPerRow == (line.length - 1) / cWidth); |
||
Line 183: | Line 180: | ||
line = line[idx .. $]; |
line = line[idx .. $]; |
||
commitCurrent(anonCount, totalBits, |
commitCurrent(anonCount, totalBits, currentBits, code, currentName); |
||
currentBits, code, currentName); |
|||
currentName = field; |
currentName = field; |
||
currentBits = (field.length + 1) / cWidth; |
currentBits = (field.length + 1) / cWidth; |
||
commitCurrent(anonCount, totalBits, |
commitCurrent(anonCount, totalBits, currentBits, code, currentName); |
||
currentBits, code, currentName); |
|||
} else { |
} else { |
||
// The full row or a continuation of the last. |
// The full row or a continuation of the last. |
||
Line 194: | Line 189: | ||
// At this point, line does not include the first |
// At this point, line does not include the first |
||
// C.pipe, but the length will include the last. |
// C.pipe, but the length will include the last. |
||
currentBits += |
currentBits += line.length / cWidth; |
||
line = line[$ .. $]; |
line = line[$ .. $]; |
||
Line 205: | Line 200: | ||
// hopefully the compiler will optimize it, otherwise |
// hopefully the compiler will optimize it, otherwise |
||
// maybe we could specialize the properties more. |
// maybe we could specialize the properties more. |
||
code ~= "\n\tprivate ubyte[" ~ text((totalBits + 7) / 8) ~ |
code ~= "\n\tprivate ubyte[" ~ text((totalBits + 7) / 8) ~ "] _payload;\n"; |
||
"] _payload;\n"; |
|||
return code ~ "}"; |
return code ~ "}"; |
||
Line 255: | Line 249: | ||
{{out}} |
{{out}} |
||
<pre>[0, 10, 56, 128, 0, 0, 0, 0, 0, 0, 0, 255]</pre> |
<pre>[0, 10, 56, 128, 0, 0, 0, 0, 0, 0, 0, 255]</pre> |
||
Uncommenting the pragma(msg) in the main function, you can see that it generates code like: |
|||
<lang d>struct { |
|||
@property ushort ID() const pure nothrow @safe { |
|||
ushort v = 0; |
|||
version(LittleEndian) { |
|||
v |= (cast(ushort) _payload[0]) << (1 * 8); |
|||
v |= (cast(ushort) _payload[1]) << (0 * 8); |
|||
} else static assert(0); |
|||
return v; |
|||
} |
|||
@property void ID(in ushort value) pure nothrow @safe { |
|||
version(LittleEndian) { |
|||
_payload[0] = (value >> (1 * 8) & 0xff); |
|||
_payload[1] = (value >> (0 * 8) & 0xff); |
|||
} else static assert(0); |
|||
} |
|||
... |
|||
private ubyte[12] _payload; |
|||
}</lang> |
|||
Static support for BigEndian is easy to add. |
Static support for BigEndian is easy to add. |