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 uint currentBits,
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;


uint bitCountPerRow = 0, anonCount = 0, totalBits, currentBits;
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 = cast(uint)(line.length - 1) / cWidth;
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 += cast(uint)line.length / cWidth;
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.