Forth is one of the languages where you have to know the internals to write it, but the internals are really simple.
https://git.sr.ht/~crc_/retroforth/tree/master/item/doc/Nga.... - this is the "literate" version, there are a few variants of the source in the tree if you look.
[0]https://github.com/nornagon/jonesforth/blob/master/jonesfort...
Eventually you'll build your own forth (seems to be a right of passage!)
Richard W. M. Jones's Jonesforth is pretty interesting reading, and maybe the best explanation around of how to build a Forth, but keep in mind he wasn't by any means a Forth expert when he wrote it; at first he had the rotation direction backwards for ROT. But he was already a first-class hacker, and that matters more.
But more recently my understanding of Forth has changed. I never did understand why such a janky programming language had such enthusiastic fans; even though C doesn't have closures, C is a better programming language for any situation that doesn't involve an existing Forth codebase, and for many situations that do.
My epiphany was that Forth isn't a programming language. I mean, it does have a programming language in it, but it's not a very good programming language, just the tiniest step past assembly language that can give you structured control flow and nested expressions. What's excellent about Forth is that it contains an interactive programming system with virtual memory, multithreading, compile-time metaprogramming, higher-order run-time programming, and instant recompilation, in about 8 kilobytes of memory. You can even get a substantial fraction of it in much less than that.
You know how it's useful to be able to log into the flaky web or database server and run some commands to see what's going on, maybe restart an errant process or two, or tweak a config file parameter? (Even if you don't actually do this because you push all your config changes through Git and Kubernetes, surely you've at least felt the temptation if you've ever administered a server.) Forth gives you an interactive shell on almost the tiniest microcontrollers, and it's a scriptable interactive shell that has full access to the machine's I/O ports and memory. Which is what you want when you're trying to get a weird new peripheral working. You want an interactive environment (maybe like target debugging with GDB, but with a more efficient scripting language, or OpenOCD), not a batch-mode setup where every new experiment requires waiting for a compile and reflash.
It's in that spirit that Frank Sergeant described his 66-byte target-debugging stub/bootloader for the 68HC11, which has 192 bytes of RAM, as a "three-instruction Forth": https://pages.cs.wisc.edu/~bolo/shipyard/3ins4th.html It clearly isn't a programming language he's after.
And, from that point of view, things like Gforth and Jonesforth are likely to mislead, because they're "Forth without Forth": the Forth language, but without the Forth "operating system", and only runnable in environments that are far too large to justify the tradeoffs Forth makes. They do work, but they aren't compelling.
I think this is sort of like conflating Unix with bash. People who use Unix intensively tend to use bash intensively (or, previously, tcsh or ksh, and nowadays sometimes oil, zsh, or fish, but usually bash). And part of the reason for that is that you can actually whip up some pretty cool stuff pretty quickly as a shell script. For example, here's a thing I wrote in a few minutes the other day which generates a random incorrect acronym expansion for "STC" (reformatted for readability):
echo stc | while :;
do
dd of=/tmp/tmp.c.$$ bs=1 count=1 2>/dev/null;
c=$(cat /tmp/tmp.c.$$);
if [ -z "$c" ]; then break; fi;
grep "^$c" /usr/share/dict/words |
shuf -n 1 |
tr '\n' ' ';
done; echo
Result: spoil transform circumference
But imagine trying to apply bash in an environment without disk caching for your filesystem, multitasking, grep, cat, dd, shuf, tr, or /usr/share/dict/words. All you're left with is the programming language! And bash is honestly a pretty shitty programming language. You'd wonder why anybody ever bothered with Unix in the first place! And that's because Unix isn't bash or the Bourne shell. They're an important part of it but not the bulk of it; bash outside of the context that makes it so insanely useful is a bit like a fish out of water, or maybe an elevator operator in a modern automatic elevator.I don't know what embedded Forth to recommend, though, because I've never actually used Forth on a microcontroller. The only time I've ever used Forth without another OS under it is in OpenBootPROM/OpenFirmware. So I might be all wrong about this! Hopefully more experienced people can correct me. Paging DonHopkins! Paging abecedarius!
Of course OpenFirmware has some code for paging! ;)
purpose: Set up page tables and turn on paging
https://github.com/openbios/openfirmware/blob/master/cpu/x86...
start-assembling
protected-mode
\ RAM is on and mem-info-pa tells the memory layout
label entry
\ Initialize virtual page table
\ Initialize linear=physical page table (redundant page table entries)
\ Enable paging (note that page fault handler is not in place yet)
[ifdef] notdef
\ clear page tables
ax ax xor
/ptab /l / # cx mov
pt-pa # di mov
rep ax stos
[then]For the new agey stuff I'd say start with factor if you're on x86. if you're not maybe try retro[0], or write your own.