I wrote a stack based language for the 6502 before. It's actually really trivial to do.
If you have stack code that looks like this: "foo bar qux baz" and want to convert it to assembly, all you have to do is insert JSR instructions between the words:
JSR foo
JSR bar
JSR qux
JSR baz
To define subroutines, insert a label and an RTS function around code blocks. For example, to define a subroutine called qux using the code ": qux foo bar", the output would be:
qux:
JSR foo
JSR bar
RTS
The last thing needed is the ability to push literals onto the stack. In my language I defined literals as things between parenthesis. I compiled them by outputting a PUSH_LITERAL assembly macro. Code like "foo (5) (6) bar" would be compiled as:
JSR foo
PUSH_LITERAL 5
PUSH_LITERAL 6
JSR bar
That's it! You could implement an entire compiler in 50 lines of code. (of course, writing a proper FORTH requires more than this toy example)
Cool! Does it include a FORTH 6502 assembler written in FORTH?
I love writing assembly code in RPN with Forth macros!
You can write FORTH code with loops and conditionals and any kind of logic and parameters, that dynamically assembles machine code! Much better than your typical macro assembler.
Here's some 6502 assembler for an Apple ][ SUPDUP terminal emulator that does ram card bank switching:
Mitch Bradley's 68k forth lets you use interactive conditionals and loops in the top level outer interpreter!
I think he wrote a paper about that feature, which I might be able to dig up ... Here's something related he wrote about refactoring the outer interpreter, but not what I'm thinking of:
Hey, as long as you're modernizing FORTH, how about a new version of COLOR FORTH with support for millions of colors, proportional antialiased fonts, retina displays, and even transparency?
Then you could write opaque, transparent or invisible code and comments!
Blinking text and scrolling marquees would at least bring it into the late 1990's.
In ColorForth, color is part of the syntax - it matters whether or not some text is white or green or yellow, in the same way that "//" matters in C or indentation matters in Python. What would the use of millions of indistinguishably-fine syntax cases be? What are benevolent uses of transparent source code?
OTOH, ColorForth is really cool, and admirable for its minimalism and effectiveness. A featureful port to a modern platform would be really fun to play with.
Well it started out as a joke, but then I'm afraid it's starting to making sense.
The blink attribute could be a control structure! Blinking text would only execute when you could see it, so you could write a blinking word "BEEP," and you'd hear it beeping on and off as it blinked!
Or you could change a "DO" loop into a "DON'T" loop by making it transparent.
And you could extend IF ELSE THEN to support a partially transparent MAYBE clause, whose probability of executing was proportional to its alpha channel.
When looking at the FORTH code in Github that Mitch linked to, I realized that Github supports colored syntax highlighting for FORTH! (Or at least it tries.)
But it colored the "Primitive control flow words" like if/do/while/etc red by mistake, because it didn't realize that particular code was actually defining those words instead of just using them.
It's pretty hard to write a code syntax colorizer for a language that does't actually have any syntax.
And all the millions of different colors would give people something more aesthetically pleasing to argue about than tabs versus spaces (two other transparently invisible but eternally controversial elements of programming language syntax).
If you have stack code that looks like this: "foo bar qux baz" and want to convert it to assembly, all you have to do is insert JSR instructions between the words:
JSR foo JSR bar JSR qux JSR baz
To define subroutines, insert a label and an RTS function around code blocks. For example, to define a subroutine called qux using the code ": qux foo bar", the output would be:
qux: JSR foo JSR bar RTS
The last thing needed is the ability to push literals onto the stack. In my language I defined literals as things between parenthesis. I compiled them by outputting a PUSH_LITERAL assembly macro. Code like "foo (5) (6) bar" would be compiled as:
JSR foo PUSH_LITERAL 5 PUSH_LITERAL 6 JSR bar
That's it! You could implement an entire compiler in 50 lines of code. (of course, writing a proper FORTH requires more than this toy example)