Back button and Forth
This weekend I had a few minutes free after the wife and kids went to sleep and so I put together a little virtual machine:
It is built on top of the Self.js code base, and came out of a thought that has been ringing around my head since about 1994.
"What if each word in Forth were a message send to the top of the stack?"
This is dangerous thought indeed, as it provides for a pure postfix language, wherein each element on the stack defines its own dictionary. In effect, you recompose the problem of Forth as "a fuck ton of little forths". Each object becomes its own DSL, interpreting the remainder of The Input Buffer (TIB in forth parlance) as a message send to itself. On object may decide to replace itself with another object on top of the stack, or may squirrel itself away, or just pop itself off in a fit of pique.
How this interpreter works is it treats any Array as the input buffer (read program or script). So when you call the .eval() method on the array it will pop off the first element and send it to the top of the stack. There is special code for handling the undefined stack object, which basically does a push the message as an object or as itself if you can't figure it out. If the object on the top of the stack responds to the message it evaluates it returning the new state of the stack as the result of the function. There is also code for invoking globals there as well from the window space. And finally all other messages simply get pushed onto the stack as themselves. This allows you to send a number to a number and have the both numbers pushed onto the stack.
Arithmetic is handled by extending Number.prototype to handle a bunch of messages in a more Forth like manner:
This allows us to abuse the string message send semantics on numbers to do our dynamic dispatch via:
Where we are accessing the prototype's function property and dispatching it to the remainder of the stack (stack.after(0)).
Similarly, I've patched Strings, Arrays, and Objects to each have their own fetch method similar to the classical @ word in Forth.
This can be used by using an index entity @ expression to fetch the element out of the thing. So:
Will produce 'bar'. Where as:
2 'hello world' @
1, 2, '+' 'eval'
This week I hope to hook up my web toolkit, and build an editor that allows one to write Forth.js programs in a graphical environment similar to my Phos environment, which would also work nicely with Self.js.
Since I'm well on my way to having working Lisp, Self, and Forth ( read prefix, infix, postfix) languages running on a shared code base, I'm pretty certain I could pull off a multi-lingual toolkit in under 1k LOC.