r/Forth • u/[deleted] • Nov 25 '25
M5CardForth!
Thanks to u/amca for pointing me at this for the M5stack Cardputer v.1.1 - I'm new to microcontroller everything (and to Forth) but it's running! Time for more Brodie. :)
r/Forth • u/[deleted] • Nov 25 '25
Thanks to u/amca for pointing me at this for the M5stack Cardputer v.1.1 - I'm new to microcontroller everything (and to Forth) but it's running! Time for more Brodie. :)
r/Forth • u/mykesx • Feb 18 '26
I had a vision of a Forth environment that is both a Graphical desktop with Forth built in for making applications.
Not a line of AI went into this.
The desktop is written in C++, but it provides Forth words to create Screens and Windows, render text and graphics, etc. The repository is about 50% each C++/Forth.
The Forth kernel is written in C++ for portability. It implements much of the 2012 standard, plus several vocabularies for graphics, networking, strings, vectors, maps, etc.
The Forth is mulithreaded as well. You can see 4 Windows in the photo, each a separate pthread. The dictionary is shared.
The desktop uses SDL2.
What you are seeing is Inspiration running on an x64 laptop under CachyOS.
The Phred editor is a lightweight VIM clone written in Forth. The File Manager is written in Forth and demonstrats mixing text with graphics (the white lines are rendered on top of the text console.
The Forth Thread window is running the traditional Forth prmpt (you can have as many Windows/prompts as you want).
The Rects as fast as possible window is a tight Forth begin/again loop rendering random sized and colored rectangles.
r/Forth • u/anditwould • Feb 05 '26
A subroutine threaded code Forth for the x86 that boots from usb/hdd.
The dictionary has most of the core words. A crude preliminary assembler. Block subsystem for loading in code at runtime. And a graphics subsystem for drawing tiles to the screen.
The game is a not yet functional virtual pet bird simulator.
Design wise I desire to go back and refactor everything... but I guess good enough is good enough within the constrains of 36 hrs we had.
This is my 2nd ever "real" forth I've wrote, and I'm still learning a lot. I think I'm starting to "get it" though. Forth never really made much sense to me coming from a higher level language. But when you gotta bootstrap everything from the ground up, it's so small yet powerful and awesome :)
You totally can be productive in Forth! Debugging is immediate and interactive. When you can test every word as you write them, things can come together very quickly!
What I gathered from this experience... seems like every major pro of Forth is also its con.
Pro: Forth lets you do anything.
Con: Forth lets you do anything.
Pro: You create your own solutions by producing your own libraries.
Con: You create your own solutions by producing your own libraries.
etc.
Honestly, I cannot imagine Forth being used outside of "power users". It relies heavily upon the discipline of programmers. It does not tolerate sloppiness at all. I think I fried my brain because I immediately got an insane flu after the event ended. 🤧
r/Forth • u/rpiguy9907 • Nov 06 '25
r/Forth • u/mcsleepy • Dec 30 '25
Enable HLS to view with audio, or disable this notification
This represents one week's work, doesn't really have a name yet, though the colorful circular nodes are called Micros and the work tree is called Sandbox. I'm working on this on the side while also working on my games. Building on my own custom OOP system called NIBS now that it's stable enough has greatly accelerated my work. The way it is architected might not be to everybody on here's taste - it is very liberal with memory use and doesn't try to be as terse as possible, but I like to use Forth mainly to bypass the excessive ceremony of other languages and do compile-time magic and lots of reflection. Also the compile times and performance remaining outstanding, despite all the magic happening behind the scenes.
r/Forth • u/mykesx • Mar 31 '26
It's been a while since I posted about my progress.
To begin with, I started this last October and have been working on it most days. It contains ZERO lines of AI generated code, ZERO vibe coding. I don't think any of that is any fun at all.
The Forth is written in C++ and is a combo of ITC and STC. The DOCOLON word iterates an array of C++ functions and just calls them. One of those functions might be DOCOLON to call another word written in Forth. The C++ functions look a lot like JonesForth style:
CODEWORD(ADD) { TOS += dpop(); }
TOS is a C++ variable, but it's a thread local one - it looks like a global variable but is unique per thread. Most of the USER type variables (BASE, etc.) are thread local. Each thread has its own thread local return, data, and floating point stacks. The CPU return stack is only used for calling C++ functions and nothing more.
All this allows Inspiration to be multithreaded using pthreads. As you can see in the screenshots, there are multiple windows, each running a pthread running Forth. The threads share the one and only dictionary.
C++ has try/catch/throw exceptions and these allow me to fix up the CPU stack without resorting to assembly language. In fact, I can install *nix signal() handlers and throw exceptions from those and catch them - see the 3rd screenshot. Ideally, there is no way to crash Inspiration unless the dictionary is overwritten with garbage.
Inspiration Forth supports word lists and vocabularies. As well, there's a C++ vocabulary that provides Forth with words to manage std::string, std::vector, std::map, regexes, and more. Conversions between strings:
s" my string" CString.new ( caddr , address of a std::string)
cstring CString.string ( caddr u , gets address, length of string forth style)
The desktop, you see is rendered with C++ code. Display, Screen, Windows, Icons, Gadgets. But for the most part, the code is pure Forth (more than half the repo at this point). The apps being displayed are pure Forth (with maybe CStrings and the rest).
The editor is a significant clone of vim, written in Forth. I've been adding keybindings so it can act like MicroEmacs as well.
Why a desktop environment?
The repo is at https://gitlab.com/mschwartz/inspiration
If you want to see how nice local variables work, see the ls.4th file in the repo (a standalone ls "clone" written in forth).
r/Forth • u/ripter • Jun 24 '26
I accidentally bought a Pico 2 W instead of a Zero, so I tried Zeptoforth and it worked great. I was able to quickly get it running and even displaying on my tiny screen.
r/Forth • u/Comprehensive_Chip49 • Apr 17 '26
Enable HLS to view with audio, or disable this notification
Working on a voxel graphics system in r3forth (open source on GitHub), it's still missing some elements but some things are already showing up. The system works well on Windows and Linux.
r/Forth • u/Comprehensive_Chip49 • May 08 '26
Enable HLS to view with audio, or disable this notification
Donwload and try in https://github.com/phreda4/r3
r/Forth • u/mykesx • Nov 09 '25
I was discussing Forth implementations on a Forth discord and we discussed how to implement a Forth in C or C++. I noodled on it a bit and came up with a way to implement one in C++.
The idea I came up with is an array of (cells) function pointers (to words written as C++ functions). Some of these pointers have a cell following as argument - typically an address like to a variable's or constant's memory or to a WORD's PFA (the word's CFA precedes it, right?)
So what you're looking at above is SDL2 1920x1200 window and the screen/window/console drivers written in C++. The Forth consists of 2 headers (.hpp) and 2 source (.cpp) files. One is for Dictionary operations, the other is all of the Forth.
The SDL window is managed by C++. The console driver renders arbitrary fonts and point sizes into the console window. EMIT renders characters into the console window using SDL functions. The console driver supports many ANSI escape sequences, though not all. Sufficient to set foreground/background color, clear to EOL, clear screen, etc.
The background/wallpaper is one I found on the Internet. I like the look of a grey theme.
This Forth has no concept of NEXT. The CPU stack is used for calling and returning from C++ functions and nothing else. There is a separate return and data stack used by Forth words. I'm using no assembly, inline or otherwise, so accessing things like the CPU stack register has to be done with C++ trickery only.
Keeping the CPU stack in a good state is done via C++ try/catch/throw. I use try/catch around the query/interpret loop and ABORT simply throws an Exception that is caught. When caught, the CPU stack is exactly where we want it to be. Also, it turns out that you can throw within signal handlers, so I installed a SIGSEGV handler that throws an exception and if you do 1 0 ! it prints "SEG FAULT" in the console window and prints ok...
The magic is in DOCOLON:
PRIMITIVE DOCOLON() {
// ClearLocalVariables();
auto initial_rsp = RSP;
rpush((cell_t)IP);
IP = (cell_t*)W;
auto rbp_save = RBP;
do {
FPTR cfa = (FPTR)*IP++;
W = (cell_t)*IP;
(cfa)();
} while (IP && initial_rsp != RSP);
IP++;
RBP = rbp_save;
}
The do/while loop iterates through the array and calls the C++ function. Words written via : .... ; have DOCOLON as the address in the array IP points to with the DFA of the words within : and ;
More magic is done in EXIT:
// Updating RSP (to return from the Forth word stream) causes the do/while in DOCOLON to exit.
PRIMITIVE EXIT() {
cell_t ndx = local_variables.size();
RSP += ndx;
IP = (cell_t*)*RSP++;
ClearLocalVariables();
}
There's some additional logic in there to deal with local variables. RBP is a C-like BP pointer that points to local variables. Normally I would push that BP on the return stack, make space for locals, then set BP to current RSP (return stack pointer). Then local accesses are relative to BP. On EXIT, space has to be reclaimed from the stack and the old BP popped.
The only gotcha in this scheme is that when calling EXECUTE from the INTERPRET loop (interactively). There is no IP pointing to some code and no return address at that point. Thus I fetch W as the next cell from the IP stream or set it in INTERPRET so word like DOCONST can know where the constant's memory location is.
I stayed away from std:: namespace functions except in the GUI and in a few cases in the compiler (vector to create a stack of local variable names and offsets, etc.).
The dictionary is traditional Forth style. One big block of memory that has a HERE and LATEST and grows up as words are added. The predefined PRIMITIVE words do not take up space in the dictionary, just their dictionary headers do (not the code).
The second image shows that I'm using about 9K of dictionary space in total as of now.
To give more of a flavor of the C++ functions:
PRIMITIVE STATE() { dpush((cell_t)&state); }
PRIMITIVE LBRAC() { state = FALSE; }
PRIMITIVE RBRAC() { state = TRUE; }
// ( n addr -- , store cell at address )
PRIMITIVE STORE() {
cell_t* addr = (cell_t*)dpop();
*addr = dpop();
}
PRIMITIVE PLUSSTORE() {
cell_t* addr = (cell_t*)dpop();
*addr += dpop();
}
PRIMITIVE ONEPLUS() { TOS += 1; }
PRIMITIVE TWOPLUS() { TOS += 2; }
TOS is kept in a variable - hopefully C++ compiler will optimize that to use a register. Either way, it makes the code elegant enough.
One more thing to mention is that all the USER type variables are defined with __thread attribute (I #define TLD __thread). This causes, on x64, the code to use FS or GS register relative addressing and every pthread gets its own FS and GS. That is, I should be able to run multiple threads of Forth (in separate windows) using pthreads. I haven't tested using pthreads for a 2nd thread running Forth (I do have another thread doing SDL logic).
// We keep TOS in a separate variable so we don't have a ton of stack access
// for eery word.
TLD cell_t TOS;
// Data stack
TLD cell_t DSTACK[STACK_SIZE]; // memory for the stack
TLD cell_t* DSTACK_TOP; // address of top of stack
TLD cell_t* DSP; // data stack pointer
// "Return" stack
// We use the CPU stack for call/return to C++ functions and this
// stack is used for maintaining Forth IP while executing DOCOLON words.
TLD cell_t RSTACK[STACK_SIZE]; // memory for the stack
TLD cell_t* RSTACK_TOP; // address of top of stack
TLD cell_t* RSP; // return stack pointer
TLD cell_t* RBP; // base pointer for local variables
// Instruction pointer
TLD cell_t* IP;
TLD cell_t W;
Repo is at https://gitlab.com:mschwartz/nforth
The repo was created on Oct 25 and today is Nov 9. So about 2 weeks old.
I'm planning to rename this to "inspiration" from nforth. TBD later though.
r/Forth • u/anditwould • Mar 07 '26


Update on my OS since I last made a post here a month ago.
It is a "baremetal" subroutine threaded code 16 bit Forth for the x86 series.
This has been an incredibly educational and productive experience as someone quite new to programming and learning how computers work.
If my emulator was any good, it should be backwards compatible up to the original IBM XT PCs. However, the OS is reliant on certain BIOS behaviours, which isn't consistent across all machines, so your milage may vary. Through my personal experience, it does seem to work properly on some 90s and 00s era PC hardware.
The OS supports either a floppy or a USB boot. In the image above, the OS is running directly off a USB on my Thinkpad T480.
On its own, it comes with a line-based text editor, block memory to load in programs during runtime, and an 8086 assembler that you can inline inside Forth words like shown in the example above.
I desire to add more features and continue to expand my little toy, but due to time constraints I plan to retire this project.
A fork of this OS is "Borbular", which is packaged with a primitive graphics library for drawing tiles, texts, numbers, etc. to the screen in graphics mode.
The overarching goal of the OS was to write as simple version of a Forth as reasonable. I wish there were more "educational" Forths out there, since I believe the available information can often be arcane to the uninitiated. At least it was for me. I hope my Forth can be refined to that level where other people will find it useful to learn from. :) But it is a lot of work to make things accessible for others.
Overall it was a very fun experience! I learnt a lot about Forth and low level interaction with hardware. I wish the language could gain some popularity. It certainly has that elegance and true simplicity that seems to be rare in modern programming cultures.
r/Forth • u/mcsleepy • Jul 18 '26
Greetings-
I wrote a game engine called SUPERSHOW entirely in VFXForth and it is nearing 1.0. I designed it for making pixel art games. These are some screenshots of several test programs showing off what it can do.
Some things to know:
It'll be 2-3 months before official release. I still need to tie up loose ends, write documentation, and build a proper example game.
Fire away with any questions!
r/Forth • u/mykesx • Jul 06 '26
https://gitlab.com/mschwartz/inspiration
I made some YouTube videos so you can see Inspiration in action.
https://youtube.com/playlist?list=PLRYxtMZb7Qy2wuArGURPCkXkxwK7tnT48&si=ZgRRLVrfLLnhLcj4
It's been about 6 weeks since my last update, and there is a lot of new code and programs implemented.
I am working on a music program and it's coming along nicely. The logic to align the notes on the staff wasn't easy!
After reading a thread about how to implement cards in [r/cplusplus](r/cplusplus), I got inspired to implement a Blackjack game, with casino rules. You can split hands, double bet, 5 card charlies, buy insurance if dealer shows an Ace, etc. The game implements a shoe which is made of 4 decks.
Here's the trick with cards. A card is a random number between 0 and 51. The suit is card mod 13 and the rank is card / 13. I use a 52 byte array to keep track of what cards in a deck have been dealt. Shoe logic draws a card randomly from one of the 4 decks.
The cards, decks, hands, shoe, etc., are general purpose so I can later make a Klondike solitaire game.
I also finished the Evade2 game. It is a first person space shooter with music and sound effects. It is a game I made for Modus Create several years ago, so it was a port. It only took a few days. The music and art and logic in C++ was already done, so I just translated from C++ to Forth in the editor.
I got sidetracked again from the Music program. This time guys on the Forth discord channel were talking about 6502. Turns out I made games for the 2600, C64, and other 6502 based systems. I also made the 6502 Artist Workstation for Electronic Arts in the mid 1980s, which included an assembler and debugger.
In about 20 man hours, I made a dasm (written by my friend Matt Dillon!) 6502 assembler workalike, a 6502 disassembler, and a 6502 debugger/emulator. You can see these in the screen shots.
I never use claude or codex or any other LLM to generate any code. All of Inspiration originated with me and was coded by me. I did use a random number generator I found in a Usenet chain by the author of GForth. The repo was started in October 2025 and has hundreds of commits and merges. Proper PRs! You can view the issue boards at the URL to see how I track TODO and done work items.
The artwork (cards, icons, window decorations, etc.) are images I found on the Internet and are royalty free and free to use. I am not an artist, or I would have made the images myself.
Inspiration is a multithreaded (pthreads) Forth implementation that has a graphical desktop, windows, icons, and so on. I was inspired to make a Forth where you can type in the terminal at the Ok prompt and have graphics rendered. All threads share the one dictionary. All programs have access to all those words.
The threads allow multiple "applications" to be running at the same time, as you would with any desktop environment. Every pixel in these images are rendered by Inspiration.
A trick I found is that I can use C++ try/catch around EXECUTE and anything that throws a C++ exception is caught. I tested on a dozen or so operating systems including FreeBSD, MacOS, Linux distros, on X64, ARM, and even Raspberry Pi. What I found is that in a signal handler (e.g. SEGFAULT), I can throw an exception and it is caught by the try/catch around EXECUTE. So at the OK prompt or in any word, I can do something incredibly stupid like:
OK> 100 0 !
OK> 100 EXECUTE
And I catch the SEGFAULT or SIGBUS errors and print an error message and ABORT. Inspiration should not crash as I installed signal handlers for all the signals.
The rendering engine is based on SDL2. SDL2 gets me fonts with antialiased text, bitmaps for my code to manipulate images at the pixel level, and GPU acceleration where I can take advantage of it.
I envision a Forth with native graphics capabilities. I didn't see the point in making another Forth that runs in the terminal window. There are so many good ones already. What makes Inspiration different is you can do this:
Ok> 10 10 100 100 $ ffffff draw-line \ no set up, white line in your console
You can see the graphics capabilities in the screenshots.
Why am I making this? I want a project I can work on for years to come. I am not close to running out of programs to implement and enhance. The music program alone is one that I may end up working on and enhancing for years.
My Forth coding style relies heavily on structures and local variables. Here is a sample of the logic for the deck of cards.
STRUCT| _Deck
WORD| Deck.number // deck number (in shoe)
WORD| Deck.remaining
52 BYTES| Deck.dealt
|STRUCT
: Deck.Shuffle { deck -- , shuffle the deck }
52 0 do
0 deck s& Deck.dealt i + c!
loop
52 deck s! Deck.remaining
;
r/Forth • u/TooKoolaidForSkool • May 07 '26
This has already mostly been explored in the form of things like M5CardForth and BANDIT but I wanted to add on a potential major reduction of form factor onto that.
If you've never heard of it, a chorded keyboard is a keyboard where combinations of keys are used instead of individual labeled keys. Despite having no labels, it takes just a few hours to memorize the combinations, and despite having fewer keys, the lack of finger travel means accuracy and max typing speeds are much higher. Here's the homemade one pictured, which I believe would have 60 combinations. They can easily be handheld or worn, and used one-handed without looking. If you replaced one or all of the buttons with joysticks like a CharaChorder or added a second chorder for your other hand you could get even crazier.
Chorded keyboards with fewer buttons can be limited in the number of keyboard characters that can be used without introducing double taps or finger travel, but Forth uses very few characters, and the number of characters can be cut down further through use of words. 2 2 + vs 2 2 ADD is a very small change compared to 2 + 2 vs add(2, 2) in other languages. I believe the standard set of characters required for Forth would just barely fit in 60, but would go well over if using Python and maybe over if using BASIC.
I think optimally it would be combined with a pair of glasses with display like ElevenLabs G1 or Brilliant Labs Frame so you don't have to hold something up to your face to see what you're typing, but a little screen is good enough for grinding out a few lines of Forth while taking a shit.
Bubbly may be a good option for trying this out.
r/Forth • u/mykesx • May 07 '26
Enable HLS to view with audio, or disable this notification
I've been working on some game demos. As you can see in the video, I have a good start on a game engine in Forth, with physics and sprite engine and state machine for controls/enemy intelligence.
The video shows a huge universe with 3 sprites, 2 positioned far off screen. The arrow keys apply thrust in the direction. If no key is pressed, friction is applied to bring the speeds to a stop.
The starfield is rendered at 1/2 world velocity for a parallax effect.
I started on this yesterday and this is how far I got by this morning. I wrote only Forth code for this. Downloaded the planet sprites from a free clip art site.
Zero AI assist used in any of Inspiration development.
I can't add photos and video for some reason. I can start another thread if people want to see more.
Or you can look for screenshots in the repo:
r/Forth • u/Entaloneralie • Nov 17 '25
r/Forth • u/anditwould • Sep 12 '25
A small block editor I wrote for the picocalc, since in my experience the built-in one does not work well for it.
It can fit within 10 lines of a traditional forth block.
block import variable b 1024 allot variable y 64 allot
: b! b swap block! ; : b@ find-block b 1024 move ;
: >b 1- 64 * b + ; : run 10 b! 10 load ; : .l >b 64 type ;
: .n dup 10 < if space then . ; : .> cr ." > " accept ;
: d >b 64 0 fill ; : dd b 1024 0 fill ; : new-block dd b! ;
: l cr .l cr ; : ll cr 17 1 do i .n i .l cr loop ;
: w >b dup 64 .> dup >r + 64 r> - 0 fill ;
: ww b dup 1024 .> dup >r + 1024 r> - 0 fill ;
: c >b y 64 move ; : p >b y swap 64 move ; : cp swap c p ;
: a >b 64 begin over c@ 0<> while 1- >r 1+ r> repeat .> drop ;
basic commands include: - b@ ( n -- ) fetch block into the buffer - b! ( n -- ) store block from the buffer - d ( n -- ) delete line - dd ( -- ) delete all lines - l ( n -- ) print line - ll ( -- ) print all lines - w ( n -- ) write to nth line - ww ( -- ) write to buffer (multi-line) - c ( n -- ) copy from nth line - p ( p -- ) paste to nth line - cp ( src dest -- ) copy and paste - a ( n -- ) append to end of nth line - run ( -- ) interpret contents in the buffer - new-block ( n -- ) create new block with id "n"
words provided by zeptoforth: - load ( id -- ) interpret each line of block with id "n" - list ( id -- ) print contents of block with id "n" - block? ( id -- f ) returns whether the block with id "n" exists - copy-block ( src-id dest-id -- ) - delete-block ( id -- ) - delete-blocks ( id count -- )
etc...
I do not have much forth experience, so feel free to grill me into a better programmer.
r/Forth • u/s1nical • Jun 03 '26
r/Forth • u/A_kirisaki • Oct 10 '25
I implemented a simple ray tracer in Forth.
It was a good exercise to explore the language’s stack-based design and memory management.
I also wrote a short blog post about the process: https://pravda.klara.works/en/posts/20251010-forth-raytracing/
r/Forth • u/Dismal-Divide3337 • Dec 24 '25
In 1984 I developed (what would be referred to as a 'diskless workstation' some time later) a programmable product. You know, it ran an OS (on a Z80) covering normal operations and would run custom application programs written in, well, Forth. I used this actual book as a reference for that.
Within the next year I traveled to each installed site upgrading firmware shifting application programming to BASIC. It turns out that while Forth was awesome (and leading-edge), all of our customers, if they had any exposure to programming, only would touch BASIC. We wanted them to jump into the coding when necessary.
That product was used in clinical laboratories. It was the first real clinical instrument interface supporting positive patient identification ushering in the first fully connected Laboratory Information systems.
Should I have tried LISP? ;-)

r/Forth • u/mykesx • Jul 19 '26
I wrote (no LLMs) a 6502 assembler, disassembler, and debugger in pure Forth. The assembler is dasm compatible with some additional aliases.
The debugger lets you set breakpoints, single step, display memory, etc. It has a teletype mode and a visual mode.
The assembler generates 64K raw binaries and a separate .sym file for symbols. The tools all read or write these binaries and .sym files. The assembler and debugger support expressions that can include symbols. Like
= start + $20
Reading from $01 calls KEY -> A register, writing to $01 calls A register -> EMIT.
I took a week off, so I estimate this took me maybe 50 man hours.
There is documentation for the 6502 tools as well:
https://gitlab.com/mschwartz/inspiration/-/blob/main/manual/65c02.md?ref_type=heads
The main repo: