Recursive delegate type?
Timon Gehr
timon.gehr at gmx.ch
Tue Apr 22 20:04:52 UTC 2025
On 4/22/25 21:53, WB wrote:
> Most typed programming languages, other than maybe Haskell or Ocaml can
> do it, but throwing it here, as a puzzle:
>
>
> ```d
>
> alias OpCodeHandler = void function(OpCode *ops, Reg *regs, void*);
>
>
> private string next(string offset = "1", string dispatch_table = "d",
> string ops = "ops", string pc = "pc", string args = ", regs") {
> return `return (cast(OpCodeHandler*)(` ~ dispatch_table ~ `))[*((` ~
> ops ~ `) + (` ~ offset ~ `))]((` ~ ops ~ `) + (` ~ offset ~ `)` ~ args ~
> `, (` ~ dispatch_table ~ `));`;
> }
>
>
> void add_int(OpCode *ops, Reg *regs, void* d) {
> regs[0].Int += 1;
> mixin(next(/*offset=*/"2"));
> }
> ...
>
> static __gshared OpCodeHandler[256] dispatch = [
> &add_int,
> ...
> ];
>
> ```
>
> So the 3rd argument to the function (`d`), is actually of type
> `OpCodeHandler*`, but obviously that is not an option:
>
>
> ```d
> alias OpCodeHandler = void function(OpCode *ops, Reg *regs,
> OpCodeHandler*);
> ```
>
> Any ideas, how to make it prettier, and avoid casts? I doubt it is
> possible.
>
>
D does not support equirecursion, but there is isorecursion:
```d
struct OpCodeHandler{
void function(OpCode *ops, Reg *regs, OpCodeHandler*) payload;
alias this=payload;
}
```
You can also unwrap it once:
```d
alias OpCodeHandler=void function(OpCode *ops, Reg *regs,
OpCodeHandlerWrapper*);
struct OpCodeHandlerWrapper{
OpCodeHandler payload;
alias this=payload;
}
```
You may have to wrap and even unwrap manually sometimes, but there are
no _unsafe_ casts required, at least.
More information about the Digitalmars-d
mailing list