Writing a (dis-)assembler for 8-bit code in D - blog posts

Dukc ajieskola at gmail.com
Tue Apr 20 10:02:05 UTC 2021


On Monday, 19 April 2021 at 20:05:57 UTC, Brian wrote:
> I'll also take tips for better idiomatic D in general, for my 
> own sake.

Here goes some tips.

Don't bother with `static` before the functions. It does nothing 
in D, unless the definition is local scope (inside a struct, 
class, union or another function). If you want to limit symbol 
visibility, see 
https://dlang.org/spec/attribute.html#visibility_attributes. 
TlDr: `private` means the symbol can only be used in the same 
file. `public` is the default and means the symbol can be 
`import`ed from another file. `export` is used when making .so 
files and tells the symbol must be dynamically linkable.


You probably want to learn about `foreach` loop. For starters, 
you can replace almost all for loops this way: `foreach(i; 0 .. 
array1.length) array2[i] = array1[i];`. There are even better 
ways to do the same, http://ddili.org/ders/d.en/foreach.html is a 
good introduction.

A word of warning about `foreach` though: it should not be used 
if the length of the array is going to change while iterating. In 
my example, `array.length1` is only calculated once, at start of 
the loop, so shortening `array1` in the body would lead to 
out-of-bounds condition.


`static foreach` has a lot of potential to shorten your assembler 
code. For example, instead of

```D
if (op == "nop")
     nop();
else if (op == "lxi")
     lxi();
else if (op == "stax")
     stax();
else if (op == "inx")
     inx();
else if (op == "inr")
     inr();
else if (op == "dcr")
     dcr();
else if (op == "mvi")
     mvi();
<...>
else
     err("unknown opcode: " ~ op);
```

its better to write

```D
sw: switch (op)
{   //iterates over the array at compile time
     static foreach(opStr; ["nop", "lxi", "stax", "inx", "inr", 
"dcr", "mvi", <...>])
     {	case opStr:
         mixin(opStr)(); //inserts a call to function with name 
opStr.
         break sw; //breaks out of the switch statement
     }

     default: err("unknown opcode: " ~ op);
}
```

Even better is if you make a global array of opCodes and pass 
that to `static foreach`. The opcode array needs to be available 
in compile time, so mark it `enum` instead of `immutable`, like: 
`enum opcodes = ["nop", "lxi", "stax", <...>];`



>
> As an unrelated aside: I'm giving a talk about all the 
> different languages I have helped port to OpenBSD (about 40 or 
> so that I can remember as of now).

Wow, that's a lot! Congratulations!




More information about the Digitalmars-d mailing list