1 2 + >r
becomes something like SET PUSH, 0x1
SET PUSH, 0x2
SET A, POP
ADD A, POP
SET X, SP // back up data stack pointer
SET SP, Y // switch to return stack
SET PUSH, A
Thoughts?The first thing to do is to write a DCPU-16 assembler in Forth, and use that to write the primitives. That's pretty simple -- just look at the 6502 assembler: http://www.forth.org/fd/FD-V03N5.pdf
Some Forth systems have metacompilers so they can retarget themselves to different architectures. http://www.ultratechnology.com/meta.html
Using a metacompiler with a Forth DCPU-16 assembler would be the best way to go. Then you could easily experiment with different threading schemes, stack architectures, etc.
Edit: Just to clarify about the interpreter point, I'd expect something like "1 2 + >r" to be represented at run time as four words in memory and there'd be an interpreter, written in machine code, reading code word sequences and jumping to small bits of machine code to either do a built-in function or push the call stack.
Now I'm curious how you'd encode subroutine calls. Your example was completely inlined but the call-sequence will be critical in determining how compact the code ends up.
Also, were you thinking of using a cross-compiler and keeping the dictionary out of the DCPU-16s memory? Let me know if you create a public repo. I'd be interested to see what you come up with!
: A dup * ;
: B 2 A A 1 A ;
would look like: A:
SET Y, SP
SET SP, X // switch to data
SET PUSH, PEEK
SET A, POP
SET B, POP
MUL A, B
SET PUSH, A
SET X, SP
SET SP, Y // switch to return
SET PC, POP
B:
SET Y, SP
SET SP, X // switch to data
SET PUSH, 2
SET X, SP
SET SP, Y // switch to return
JSR A
JSR A
SET Y, SP
SET SP, X // switch to data
SET PUSH, 1
SET X, SP
SET SP, Y // switch to return
JSR A
As you can see, a little bulky, but doable. Optimizing stack operations to make better use of the registers can get rather nasty- still thinking about the best way to approach it. I'm definitely thinking in terms of a cross-compiler, and ignoring things like defining words for the sake of simplicity, at least at first. I'll drop you a comment if I get a prototype working.