Minimalistic Forth-like virtual machine

Hi, there!

I’ve written semi-toy virtual stack machine (a pipe dream has come true ). To be honest I did not write it from a clean sheet of paper - I used these lessons as a “cheat sheet”.

No, I’m not Forth programmer (Lord forbid ), but I think that

• Forth is a gem, without any doubt
• implementing something Forth-like is a good way to learn some other language.

About the implementation itself: of course, it is not a fully-blown one:

``````\$ zig-out/bin/zf
zf> .dict
bye . cr .dict .dstk .rstk .cstk .code dup drop
+ - * / mod = <> > < 0= 0<> 0> 0< max min : ;
if else then do i loop (
zf>
zf> 1 2 3
zf> .dstk
dstk[3] = 0x0000000000000003 <- top
dstk[2] = 0x0000000000000002
dstk[1] = 0x0000000000000001
zf>
``````

But even with this minimalistic set of predefined words we can do something kinda useful:

``````zf> : τετραγωνίζω dup * . ;
zf> 7 τετραγωνίζω cr
49
zf>
``````

Greek word “τετραγωνίζω” (tetragonizo) means “to square”.

More complicated example:

``````zf> : divisable-by-three 3 mod 0= ;
zf> : test do i dup divisable-by-three if . else drop then loop cr ;
zf> 30 1 test
3 6 9 12 15 18 21 24 27
``````

That’s it.

4 Likes

Woah, nice! I’m super into this. I don’t have anything insightful to add, but I’ve bookmarked your project to dive into later. Looks really cool!

@ratfactor thanks for positive response!

``````zf> : var create 1 allot ;
zf> : km 1000 * ;
zf> : hour 3600 * ;
zf> var distance
zf> var time
zf> var speed
zf> 100 km distance !
zf> 1 hour time !
zf> distance @ time @ / speed !
zf> .data
data[0] = 0x00000000000186a0 ('distance')
data[1] = 0x0000000000000e10 ('time')
data[2] = 0x000000000000001b ('speed')
zf> : take-and-print @ . cr ;
zf> speed take-and-print
27
``````

got speed in [m/s].