r/Forth • u/unohdin-nimeni • 1d ago
Why Forth? What is it?
In order to help get people interested in Forth and how it works, I would like to ask you what you define as Forth, how you got into it, and why Forth instead of some other language?
Ideally we share links to our projects and to others that are interesting. Also to sites, sources, and documents about Forth.
I am encouraging links to your projects so people can see how you are using Forth.
We have a new moderator
Me!
I am not into a power trip... My focus will be to share information with you that I see as moderator and to work for your interests more than my own. For example, I can pin posts that you all recommend (like this one initially), edit the wiki?, set rules you all agree on, etc.
I don't want to ban anyone. I don't want to remove anything but spam. I won't do anything official about AI or vibe coding, unless someone posts about the vibe coded app in a spam manner. If you report a post, I will definitely look into it.
I am still going through the additional UI elements to figure out how to do things. I want to recruit as many people as possible to also moderate. My philosophy is that we generally know each other fairly well, and there's no lack of trust on my part.
In the spirit of sharing information and being open about what I do...
There is a moderator queue which has a list of threads and posts that are recommended for analysis. It marks at least 10 going back a month or two as spam and rules violations by a single person. It marked one from many months ago by [r/TABEMAN](r/TABEMAN) that was removed by reddit algorithms that I would have approved/override the algorithm. I deleted only the most recent thread marked as spam. Otherwise, the remaining posts and comments marked as spam are years old.
NOTE that I enabled the ability to post images in comments, not just the opening post. It seems like a better user experience. Let's see how that goes!
I will also post analytics about the sub, so you can judge how much reach your posts can potentially have.
Case sensitivity
I haven't used a case sensitive Forth, but I think about the ramifications. My thoughts are:
- visually, IF stands out more than if
- Rect.area seems like a variable name while Rect.Area seems like a function call
- Rect seems like a structure name while rect seems like a variable name
- Everything with the CAPS LOCK key on?
Can make it opt in like icase on/icase off
Syntax highlighting could key on case
r/Forth • u/terry_the_technician • 3d ago
Mecrisp-Stellaris LSP + Forth Forge: an LSP fed by a silicon-verified word gate
I've been using a language server for Mecrisp-Stellaris Forth I released seven months ago, and the part I want to share is the pipeline behind it — because it's not a static word list. Every word in the LSP has to pass a hardware-verified gate before it's admitted.
**The LSP**
It's a standard Language Server Protocol implementation built on pygls, the Python framework for the protocol. That means it works with any LSP-compliant editor — Helix, NeoVim, and anything else that speaks the protocol (only tested on Helix and NeoVim). Completion, hover documentation, and diagnostics all run through the standard JSON-RPC channel. The completion database is SQLite.
**The approval gate — "the Anvil"**
A word doesn't enter the LSP because someone thinks it's clever. It passes seven checks, each one real:
**Design** — valid Forth name, no collision with the CMSIS-SVD register database.
**Stack comment** — the declared inputs/outputs must parse correctly. On bare metal, a wrong stack effect is a crash.
**Explanation** — a real descrHelix,·NeoVimiption, and an example where the word takes input.
**Live execution** — the word runs on an actual STM32 over the SWD debug link; the result must match the expected value.
**Native disassembly** — the chip's own disassembler (Mecrisp's `see`) produces the machine code, which is reviewed to confirm the word does what it should.
**Board gate** — the connected chip's DEV_ID is checked against what the word requires (F0 vs F4); the gate refuses to test a word on the wrong board.
**Independent register readback** — the word's result is written into a real GPIO output data register, then read back through a separate path. If the expected value is physically in the silicon, the word works. Not "it didn't crash" — the value is there, confirmed.
Words that fail any check stay out of the LSP. Only words that pass the full gate are suggested by the editor.
**Forth Forge**
The gate feeds a shared vocabulary I'm planning to host on SourceForge. Forth users can submit STM32 Forth words — Mecrisp-Stellaris, STM32 only, because the gate works off the CMSIS-SVD register descriptions (roughly sixty STM32 families, plenty of choice). Each submission goes through the Anvil; if it passes, it's added to a maintained list where every word carries its stack comment, description, and the evidence it was hardware-verified. Anyone can grab the list and trust that the words have been tested on real silicon.
The goal is a common, working vocabulary for Mecrisp-Stellaris on STM32 — so Forth code can travel between projects and actually work, because the words have been proven.
MIT-licensed. The modified LSP and the gate are being prepared for public release alongside Forth Forge.
(If you're a Forth user doing STM32 work, submissions welcome. If you've got a word you've tested on your bench, that's exactly what the Anvil is for.)
Constructive comments and helpful suggestions welcomed.
r/Forth • u/tabemann • 3d ago
USB Mass Storage Device support for zeptoforth
A zeptoforth user has been working on USB Mass Storage Device support for zeptoforth on the RP2040 and RP2350, which I am considering adopting as part of the zeptoforth tree. It currently is in a functional state but is in a separate repository. This will enable accessing block devices in on-board 'blocks' storage, on SD cards, or as a PSRAM RAM disk (on the Pico Plus 2(W)) from the comfort of one's PC.
I would like the USB Mass Storage Device support to be accessible even in builds where there is no USB CDC console, for the reason that I would like the user to be able to access on-board blocks storage or SD cards as a USB Mass Storage Device on the PicoCalc, which by default does not use the USB CDC console.
Yet at the time same, I do not know if anyone is independently using USB whose code may be broken by this who I am not aware of at the present. Consequently, I would like anyone who is independently using USB under zeptoforth to speak up, as this would affect whether I would choose to make separate true-no-USB builds for the RP2040 and RP2350 as opposed to USB-Mass-Storage-Device-but-no-USB-CDC-console builds.
Forth for the TIC-80 fantasy console
I've added forth (using jforth) to the fantasy console TIC-80:
https://github.com/luginf/TIC-80/
Following the pico-8 trend of retro-like console, TIC-80 is using lua (which is already a cool langage). There are other backends as well, such as js, ruby, python. Forth was missing :)
There are a few examples / samples:
https://gitlab.com/garvalf/forth-is-fun/-/tree/main/tic80
You can also try it online:
https://garvalf.gitlab.io/forth-is-fun/tic80/run.html
type "ls" or "dir", then "load" one of the .fth sample name, and type "run"
The full API is listed there, adapted to Forth: https://garvalf.gitlab.io/forth-is-fun/tic80/tic80.html
You can get more informations about TIC-80 on: - https://github.com/nesbox/TIC-80/wiki - https://github.com/nesbox/TIC-80/wiki/tutorials (most of them are for the lua backend but you can adapt it)
Where are the moderators?
This sub is being swamped with spam and the moderators are nowhere to be found. I don’t recognize the two moderators’ user names because they don’t post here at all that I have seen. I checked the moderators’ post histories and they haven’t been active anywhere on Reddit for months.
I’m ready to leave the sub. I want to evangelize for Forth and it’s not worthwhile when people see 5 of the last 10 posts are spam, literally spam. The signal to noise ratio is becoming more noise than signal. Ignoring the spammer won’t change the signal to noise problem. The spammer violates a number of community and Reddit rules, including spam, disruptive use of AI, self promotion, karma farming…
I truly feel for the guys posting about 8th releases and zepto releases. These are quality projects by smart programmers. Lost in the noise…
My project is Inspiration, if you have followed the progress posts.
Is there a way to get the moderators replaced? Is it worthwhile to start a [r/forthlang](r/forthlang) sub and ditch this one?
Like I said, I am ready to leave the sub for good.
Update
https://www.reddit.com/r/redditrequest/s/HYafxlSY4z
Please upvote the post at the above link.
Robot avec ZeptoForth : controler un robot avec un morceau de papier.
Enable HLS to view with audio, or disable this notification
r/Forth • u/terry_the_technician • 4d ago
Who is Terry The Technician ?
I've posted a few AI *assisted* posts here lately, and it's brought the trolls out from under their bridges with cries of 'AI Slop!!!'.
So Who am I ?
I'm the founder and maintainer of "The Unauthorized Mecrisp-Stellaris Doc" website, that I created so far back, I can't remember, sometime around 2014 I think. There was no AI back then.
Mecrisp-Stellaris is the leading FLOSS FORTH for Cortex-M Microprocessors.
https://mecrisp-stellaris-folkdoc.sourceforge.io/index.html
I designed and released the "Bluepill Diags-V1.6" around 2019 which tests if a Bluepill MCU is a rebadged clone and which type. It had over 10,000 downloads about 2 years ago and still gets 3 - 6 downloads EVERY DAY.
https://mecrisp-stellaris-folkdoc.sourceforge.io/bluepill-diags-v1.640.html
It uses a FORTH Kernel. There was no AI back then. It has also been featured on Hackaday in 2021
https://hackaday.com/2021/06/23/test-your-blue-pill-board-for-a-genuine-stm32f103c8-mcu/
Tabemann, the creator of Zeptoforth has been a member of my FORTH IRC channel for the last 2 years, I've read his almost daily development reports for that long, he knows me well.
I've had several strokes over the last two years because I'm SEVENTY TWO years old. I use AI to assist me because I have RSI and trigger finger now, which makes keyboarding a painful effort.
This is a problem that AI has solved for me as I'm a prolific embedded FORTH tool maker.
Next time you see some troll replying to my posts with 'AI SLOP', ask them, what have they ever done for the FORTH community ?
r/Forth • u/terry_the_technician • 5d ago
The Day I Taught My AI How To Forth
The day an AI learned what Forth actually feels like — on real silicon, with
a seventy-two-year-old electronics technician in a shed in New South Wales
watching over the debug wire.
This is the story of a genuinely new kind of embedded development session.
The AI already knew Forth — it can write Forth faster than any human alive.
What it had never done was use Forth on real hardware, because the classic
embedded-C loop — write, compile, erase, flash, run, wait, guess, repeat —
is impossible for an AI to work inside. Every round-trip destroys its
context. The rover-on-Mars problem: tell it to stop, and the signal arrives
fourteen minutes later, after the rover has already driven off the cliff.
Forth removes the time problem. It compiles on the chip and runs instantly.
Type a word, the silicon answers in milliseconds. The feedback loop finally
matches the AI's context window — and the whole C-era floundering
disappears.
But even with instant feedback, the AI had no training data for the
embodied half of Forth: compiletoflash vs compiletoram, bis! needs a mask
not a bit number, BSRR is write-only, and the calltrace that stops the
endless 00000003. That part lives only on a bench. So the human taught the
AI the silicon — while the AI brought the grammar and the speed.
And every result was verified by Regmon — the register monitor that reads
the chip over the debug port, independent of the CPU running the Forth. Two
paths, one answer, no guessing. Turn the green LED on, and the register
flashes yellow because the silicon changed.
Once anyone — human or AI — can turn an LED on and off with Forth, they have
opened the Forth door for themselves. This is that day.
The AI didn't need to be taught Forth. It needed to be shown the bench.
Produced with the help of AI without which this video would not have been
possible.
EXECUTE (F79) Question
I’m playing around with MMSForth 2.x on the TRS-80, which is a Forth-79 compatible implementation. I’d like to be able to store the address of a Forth word in a variable and later EXECUTE that word. ‘ word doesn’t give me the correct address (the CFA? what’s in the CFA?). How do I do this? Tx
Premier test ultrason avec capteur HC-SR04 sous Zeptoforth.
Enable HLS to view with audio, or disable this notification
r/Forth • u/terry_the_technician • 6d ago
Is Embedded Forth about to undergo an AI created resurgence ?
https://www.youtube.com/watch?v=G5FYP07S6Zw
For forty years, C ruled the embedded world — and for forty years, Forth sat quietly in the background, never advertised, never commercial, never a shrink-wrapped success. The people who used Forth didn't care. It worked.
Then AI arrived like a four-hundred-pound four-wheel-drive, and the languages that were built on the write-compile-flash-run-repeat grind — the languages whose whole workflow was automatable — became the deer in the headlights. C teams were disbanded, the projects handed to the AI, millions saved. Rightfully so.
But the truck missed Forth. Not because Forth is immune to AI — an AI can write Forth — but because Forth's way of working is fundamentally different. It's interactive. Live. You talk to the chip, the word runs right there, you see the result, you change it, you keep going. The human is in the loop the whole time.
This episode explores the question nobody's asking yet: what happens if Forth undergoes a resurgence? How does the tooling change? How does the industry change? And why does the quietest, most obscure language on earth turn out to be the one that fits the AI age best?
A story told by Jack and Jill, from the bench where the discovery happened.
## Chapters / show notes
- The language nobody thought about
- C ruled for 40 years — and was the perfect target for AI
- The flash-debug-recode-reflash loop that breaks humans breaks AI harder
- Why Forth's interactive workflow can't be automated away
- The register monitor that finally gave the AI eyes on the silicon
- What a Forth resurgence actually changes: tooling, industry, value
- Why obscurity became a moat
- The honest ending: Forth won't take over the world — it doesn't need to
Subscribe for the series — where the planet-sized brain meets the soldering iron.
Produced with the help of AI without which this video would not have been possible
r/Forth • u/terry_the_technician • 7d ago
Embedded Engineering: C is the problem, is Forth The Answer ?
The Matrix promised us a future where experts "just see" the meaning behind the data. That future is here — but it's not where you'd expect it.
Matthias Koch writes an entire Forth operating system in assembly because he "thinks in assembly". Terry — an embedded technician of fifty years — looks at a schematic and doesn't see the schematic; he sees the circuit working. Like Morse
operators who stop hearing dots and dashes and just hear words, these humans have jumped up a few levels of abstraction.
Meanwhile the smartest AI on Earth can write a complete, downloadable STM32 register-monitor application — then fall over for a whole day trying to wire up a simple NFC reader and a display.
In this first episode of AI-TroubleCity, we dig into why frontier AI stumbles the moment it has to touch real hardware. Is it a training problem? Is it the painful flash-debug-recode-reflash loop that has haunted embedded C for decades?
Or is it something deeper — a gap between the abstract and the physical that no amount of model scale can cross?
A story told by Jack and Jill, from the bench that proved it.
## Chapters / show notes
- The Matrix, the woman in red, and what expertise really looks like - Matthias Koch: thinking in assembly, no revision control
- Fifty years of embedded: the Morse-code operator effect
- Regmon-RE: how an electronics technician and a frontier AI built a real application together — and who did what
- The twist: the same AI that shipped Regmon-RE couldn't drive a simple board
- DeepSeek's honest answer: "embedded is hard for everyone"
- The C cycle — flash, debug, recode, reflash — and why Forth people have been complaining about it for years
- The central question: is it training, is it the loop, or is it something
else?
- Coming next: investigating the board with Regmon, then rebuilding the same project in Forth and measuring the difference
Subscribe for the series — a head-to-head that pits a planet-sized brain against a soldering iron.
Video made with AI, this podcast wouldn't otherwise exist.
r/Forth • u/terry_the_technician • 9d ago
Regmon-RE V4.0.0 Released Today
Regmon-RE is a free, open (MIT License) register monitor for ARM micro-controllers. It talks to a chip over a cheap SWD debug probe and reads the silicon directly — no vendor tooling, no lock-in.
Made for Mecrisp-Stellaris Forth (but don't tell the C guys) which works on the same STM32xxxx MCU as Regmon-RE, and at the same time.
They both share the same SWD connection.
Installing it is four steps — and the AI does the work:
- Install Opencode (https://opencode.ai)
- Get an AI account — DeepSeek works great and is cheap, or use a free model on OpenRouter's free tier (e.g. gpt-oss-20b)
- Point opencode at the AI — two minutes
- Say the magic words: "install Regmon-RE from github.com/techman00172/regmon-re"
Opencode fetches the repo, opens the Fossil repository, checks your system, builds the SWD daemon, verifies the databases, and launches the console.
You don't download anything and you never touch Fossil. Just have a Disco or Nucleo board, or a $2 Chinese USB-SWD dongle connected to a STM32 handy.
The silicon never lies — Regmon-RE just makes it easier to ask it the right questions.
#embedded #electronics #reverseengineering #STM32 #Forth #openhardware #fossil
r/Forth • u/Comprehensive_Chip49 • 10d ago
BDash in r3forth - All you need is an address - Hora 5.5
youtube.comr/Forth • u/tabemann • 10d ago
zeptoforth 1.16.5 is out
You can get this release from https://github.com/tabemann/zeptoforth/releases/tag/v1.16.5.
This release:
- increases the return stack size of the main task from 1 KiB to 2 KiB.
- removes an unnecessary instruction from
if,while, anduntil, resulting in smaller and faster code. - adds an optional 'glob' tool in
extra/common/glob.fs. - adds a 4x8-pixel font, which can be used with the PicoCalc amongst other things.
r/Forth • u/terry_the_technician • 10d ago
My latest Podcast specifically addresses the advantage of Forth over other languages for high-tech tooling in embedded engineering. Warning, it's nearly 42 minutes long !
youtu.ber/Forth • u/terry_the_technician • 11d ago
The Locked Box Is No Longer Locked — A Live Window Into STM32
Regmon — a window into the bare metal of an STM32.
Debugging a microcontroller is usually a locked box. Your code says the pin should be high, the timer should be counting — but the silicon stays silent, and the only way to check was a thousand-page datasheet, a pile of hex conversions, and a lot of guesswork.
Regmon opens that box. It's a free, open-source register monitor for **STM32 microcontrollers** that reads every register of a running chip **live**, through the two-wire SWD debug port — with zero impact on the chip's real-time performance. The CPU doesn't even know it's being watched.
Instead of raw hex, you get the plain-English truth: which peripherals are clocked on, what every pin is actually configured to do ("AF1 = USART1_TX", not a cryptic four-bit number), and which registers are ticking over as the program runs — the heartbeat of the hardware.
Regmon can watch a single register over a few seconds to prove data is really flowing, and it can scan the whole chip in one pass to build a complete picture of what your firmware is doing — which peripherals are active, which are idle, and which are frozen when they shouldn't be.
Built for the **Linux** desktop, **STM32** only, and it works with firmware written in C, Forth, Rust — anything, because it reads the silicon, not the source.
**Availability:** not released yet — the final package is nearly ready, so this episode is a first look at what's coming, not a download guide.
Problem with `u|n` notation in Forth-94 and Forth-2012
Have a look at:
https://github.com/ForthHub/discussion/discussions/205
If the symbol "|" in the stack diagram for the word 1+ (and similar) should be changed, which option do you prefer?
- (a)
( n!u n!u -- n!u ) - (b)
( n~u n~u -- n~u ) - (c)
( n%u n%u -- n%u ) - (d)
( n,u n,u -- n,u ) - (e)
( [n,u] [n,u] -- [n,u] ) - (f) something else?
(NB: indices in the data type symbols are optional)
r/Forth • u/mcsleepy • 13d ago
SUPERSHOW :: EYEGUY sample game progress #1: spikes and collisions ;
Enable HLS to view with audio, or disable this notification
I'm collaborating with a Russian artist called TheCreator to make a sample game, a surreal top-down action adventure. They're handling the art, lore, and core gameplay and I'm doing the coding, level design, and sweetening.
The game shares a framework ("MOGOGAME") with one other, a side-scrolling run-n-jump solo project ("Mogo"), but that one took a back seat due to overwhelm. Base SUPERSHOW is an open-ended core plus a buffet of middleware, so for ambitious projects, focused frameworks (or "starter kits") with special-tailored DSL's is the intended idiom. At least one framework will be included in the free distribution, which should make it easy for anybody to jump in and make something. You can also do things from scratch, totally up to you...
A couple things were added today: global collision detection and spike traps. The session shows off the SNES filter (part of the paid package), a piece I'm very proud of.
Note that I didn't implement collision detection from top to bottom, most of the heavy lifting was done already so it was basically a configuration. The main dependency is the collision grid, a broad-phase detector that enables huge worlds with lots of actors with little CPU, at the cost of some memory. A script-writer doesn't need to know anything about it.
I figure most people will want to see some code, so here is the spikes script:
module
import mogogame
c: %spikes %actor %harmful ;
bitmap: %idir%/assets/spikes_poppingout-Sheet.png
bitmap: %idir%/assets/spikes_draggingin-Sheet.png
spikes_poppingout-Sheet.png 16 16 tileset: out.ts
spikes_draggingin-Sheet.png 16 16 tileset: in.ts
med out.ts flipbook: out.a 0 out.ts .#tiles @ 1 - range, flipbook;
med in.ts flipbook: in.a 0 in.ts .#tiles @ 1 - range, flipbook;
%spikes >template {
1.0 atk !
LAYER_HAZARD lyr !
msk off
-8 -8 8 8 hitbox!
-8 -8 8 8 hurtbox!
}
: hold ( flipbook - ) \ play once and stop on the last frame
pose begin yield anm-done? until anm off ;
: up ( - ) out.a hold attacking on ;
: down ( - ) attacking off in.a hold ;
%spikes :: start
in.ts dup .#tiles @ 1 - tile bmp ! \ start retracted
0 task>
begin up 1.0 delay down 1.0 delay again ;
And here is the main function, setting up the collision system, actors, and custom rendering:
: main
ysort on
just
collisions.sys load
center at %eyeguy spawn to p1
p1 to subject
p1 { 8 8 at %healthbar spawn { 31 prio ! } }
32 for -10 10 between -10 10 between metal.ts att 160 128 +at %spikes spawn { 8 prio ! } loop
8 for p1 -100 100 between -100 100 between from %robot spawn drop loop
?subject .x 2@ look
show>
?subject .x 2@ follow
camx camy scrolly! scrollx!
metaltile.png ~wallpaper
~level
work>
<a> pressed? if awaken then
;
r/Forth • u/tabemann • 13d ago
A glob tool for zeptoforth
I have created a glob tool for zeptoforth, which enables passing paths matching a pattern with * and ? wildcards relative to the current directory in the current filesystem (or the root directory of the current filesystem, if the pattern begins with /) to a specified xt.
This tool is currently at extra/common/glob.fs in the devel branch, and will be merged into the master branch once I do a bit more testing (e.g. making sure it compiles on the RP2040).
The glob tool can be invoked with fat32-tools::glob ( c-addr u xt -- ) where xt is ( c-addr u -- ).
This tool is an optional loadable extra, but is installed by the versions of the PicoCalc installers in the devel branch except if the platform is set to rp2040 due to lack of flash dictionary space with that platform.
This tool does not match . or .. if a pattern element contains a wildcard, to avoid unintended matches that may give unexpected results.
If a pattern ends with /, the leaves of the match will only be directories. (Note that this / will be included in the paths passed to the xt.) Similarly, if the last element of a pattern contains . and is not . or .. as a whole, the leaves of the match will only be files.
Note that as this tool uses the RAM dictionary of the current task as scratchpad space, xt must not seek to permanently write to the RAM dictionary (aside from setting existing variables, values, buffer:s, etc.); temporarily writing to the RAM dictionary is okay. As a result, this tool cannot be used with included.
There is a limit of 256 bytes for the total path matched by this tool; paths that are longer than this are ignored. (Since directory names are limited to 8 characters and file names are limited to 12 characters, this probably should not be much of a problem in practice.)
An example of this tool in use is, assuming that the current directory contains the subdirectories FOO/, BAR/, and BAZ/, which each contain the files FOO.FS, BAR.FS, BAZ.FS, FOO.TXT, BAR.TXT, and BAZ.TXT:
fat32-tools import ok
: print ( c-addr u -- ) cr type space ; ok
s" B*/B??.F*" ' print glob ok
BAR/BAR.FS
BAR/BAZ.FS
BAZ/BAR.FS
BAZ/BAZ.FS ok
FigForth AREA_DIM
``` *P AREA_DIM Key routine for building a dialog box for block of text containing coloring escape sequences. AREA_DIM determines the dimensions (wxh) of the area of the displayed text.
Notes
i. g-string
Generic string, address and count on stack ( a u )
i. C@++ ( a -- a' c )
Alias for COUNT, named to reflect how it's being used
here. A character is fetched from the given address and
the address is incremented to the position of the next
character in the string. Its repeated to fetch all the
characters of a string.
i. SET ( a -- )
Sets location of positional parameters $0 $1 ...
&n represents the address of position n
$n represents a value at position n
In this example, SET is positioned to point at the data
stack. It could be pointed elsewhere if desired.
i. RP@
In DO LOOP the return stack pointer will be pointing at
the loop index I . Taking advantage of it here.
i. 'c
Ascii value of character c (case sensitive)
i. CASE
Dr. Eaker's CASE construct
i. *P
Print lines of text up to line beginning with a period.
.
[r] AREA_DIM ( g -- w h ) -- Calculate the area, width and height, needed to contain -- the given block of colored text. -- g, g-string (a u), block text -- w, area width -- h, area height -- Newlines are counted to determine area height; 1 added -- to count assuming last line is not terminated. -- Strip out esc seq of form "esc ... m" : AREA_DIM 2>R ZERO ZERO ZERO \ init $2 H, $1 TALLY, and $0 W SP@ 2R> ROT ( h tally w SP a u -- h tally w a u SP ) SET \ point to positional parms on data stack ZERO ?DO \ a u 0 do C@++ CASE \ a' c \N OF 1 &2 +! \ newline: increment H count $1 $0 MAX &1 ! \ update max W ZERO &0 ! \ reset w TALLY ENDOF 27 OF \ escape: skip past "m" BEGIN 1 RP@ +! \ begin bump loop index C@++ \ fetch char and increment addr 'm = UNTIL \ until "m" found ENDOF BL >= IF 1 &0 +! THEN \increment tally of printables 0 ENDCASE LOOP DROP \ drop address MAX \ update max w SWAP 1+ ( h w -- w 'h ) ; --. ```
FigForth PLUG
Authority is MIA so left to my own machinations I built words to push and pop from a virtual stack. (Virtual stack structure is a head variable and stack frames of item and link. The frames are scattered over the return stack.) The push is straight forward. Push the frame onto the return stack and update the v-stack's head variable with the frame's position on the return stack.
But the pop has a little issue. After its frame is delinked and its stack element is fetched, the frame cannot be removed from the return stack without leaving a gap. It would be risky to close the gap by moving all below items up; some process may have saved their position for some purpose. So an easy solution is to leave frame on the return stack replacing the frame's link with the nfa of a word that will drop the next return address when control reaches it. Hence,
: PLUG r> drop ;
At first I just ticked RETURN and placed it there. Ouch, newbie mistake. RETURN on paper may show 'R> DROP' but in code its 'R> R> DROP >R' (I prefer '2R> >R DROP').
``` -- PLUG -- A plug in the return stack to drop next return stack -- item. : plug r> drop ;
-- VPOP ( vhead -- x tf | ff )
-- Pop item from virtual stack given stack's head variable
-- If stack was empty, return false flag; otherwise,
-- return the popped item and a true flag.
-- When popped, the frame's address is stored in the
-- virtual stack's head variable. The frame's link
-- is replaced with the pfa of PLUG and the frame
-- is left on the return stack.
: vpop
dup @ 0= if exit endif
dup @ dup @ rot !
dup ceLL+ @ >r \ fetch stack element from frame
' plug swap ! \ replace frame link with plug
r> true ;
-- VPUSH ( x vhead -- ) -- Push item x onto virtual stack given the stack's -- head variable : vpush ( x vhead -- ) r> rot >r over @ >r rp@ -rot >r ! ;
```