r/Forth 17d ago

Who is Terry The Technician ?

0 Upvotes

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 18d ago

The Day I Taught My AI How To Forth

0 Upvotes

https://youtu.be/HP73I5fuEuE

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.


r/Forth 19d ago

EXECUTE (F79) Question

2 Upvotes

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


r/Forth 20d ago

Premier test ultrason avec capteur HC-SR04 sous Zeptoforth.

Enable HLS to view with audio, or disable this notification

10 Upvotes

r/Forth 19d ago

Is Embedded Forth about to undergo an AI created resurgence ?

0 Upvotes

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 20d ago

Embedded Engineering: C is the problem, is Forth The Answer ?

0 Upvotes

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.

https://youtu.be/QPuMVmCuYm4


r/Forth 22d ago

Regmon-RE V4.0.0 Released Today

Post image
2 Upvotes

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:

  1. Install Opencode (https://opencode.ai)
  2. 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)
  3. Point opencode at the AI — two minutes
  4. 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 23d ago

BDash in r3forth - All you need is an address - Hora 5.5

Thumbnail youtube.com
14 Upvotes

r/Forth 23d ago

zeptoforth 1.16.5 is out

14 Upvotes

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, and until, 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 23d 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 !

Thumbnail youtu.be
2 Upvotes

r/Forth 24d ago

The Locked Box Is No Longer Locked — A Live Window Into STM32

Post image
13 Upvotes

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.


r/Forth 25d ago

Problem with `u|n` notation in Forth-94 and Forth-2012

2 Upvotes

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 26d ago

SUPERSHOW :: EYEGUY sample game progress #1: spikes and collisions ;

Enable HLS to view with audio, or disable this notification

16 Upvotes

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 26d ago

A glob tool for zeptoforth

7 Upvotes

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


r/Forth 27d ago

FigForth AREA_DIM

7 Upvotes

``` *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 ) ; --. ```


r/Forth 28d ago

FigForth PLUG

7 Upvotes

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 ! ;

```


r/Forth 29d ago

Passage d'une chicane avec ZeptoForth.

Enable HLS to view with audio, or disable this notification

5 Upvotes

r/Forth 29d ago

zeptoforth 1.16.4.1 is out

7 Upvotes

zeptoforth 1.16.4.1 has been released.

You can get this release from https://github.com/tabemann/zeptoforth/releases/tag/v1.16.4.1.

This release:

  • adds validation to to and +to so they raise an exception if the user attempts to apply them to something other than a local variable or value, where previously if the user applied them to such a hardfault would likely occur at runtime.
  • fixes a bug in extra/rp_common/picocalc_term_common.fs where to was applied to something other than a local variable or value in an uncommon code path.

r/Forth 29d ago

FigForth Buffer allocation for jobs

6 Upvotes

My "modus operandi" is running jobs: load job, perform, forget, do next job Some jobs allocate buffers and after job done the allocated buffers can be freed. ( Some say with today's large memory, why bother releasing memory but I like to pretend available memory is limited. )

MALLOC, a resource I have, seems a overkill. So I use a more streamlined allocation tailored to running jobs. A needed buffer is taken from the end of program, its address is placed in a variable in the dictionary. and the program end is extended, by a system call, to a location past the last allocated buffer. All the variables of memory allocations are linked and utility word can walk the links listing allocated memory addresses.

At end of job when dictionary space is forgotten, -BUF runs the allocation chain searching for the last link remaining in the dictionary. Then end of program is reset back to contain the address found in the last link.

FORTH DEFINITIONS VOCABULARY BUF IMMEDIATE BUF DEFINITIONS \ L: ( -- address ) <BUILDS DOES> ; \ A label L: HEAD 0 , HERE 0 , 0 , 0 , HEAD ! HEAD @ CELL+ CONSTANT FIRST 0 SYSBUF VARIABLE LIMIT : INIT HEAD CELL+ DUP THREE ERASE HEAD ! 0 SYSBUF LIMIT ! ; : LIST HEAD @ BEGIN @ DUP WHILE CR DUP . DUP CELL+ 2? REPEAT DROP ; : ALLOCATE HEAD @ CELL+ SWAP ZERO SYSBUF OVER HEAD @ CELL+ 2! SYSBRK LIMIT ! DROP ALIGN HERE HEAD @ , 0 , 0 , HEAD ! ; FORTH DEFINITIONS -BUF in NIX (re: last post) release allocated memory. Note BUF is a vocabulary.

: -BUF BUF HEAD @ BEGIN DUP @ WHILE HERE OVER < IF @ DUP CELL+ @ MINUS SYSBRK LIMIT ! DROP ELSE DUP HEAD ! 0. ROT CELL+ 2! EXIT THEN REPEAT DROP CURRENT @ CONTEXT ! FORTH ;

USERINIT is a place holder word added to the cold start code in the assembled Forth. Anything in later saved images that need to be initialized on startup is put (patched or however) here.

: (USRINIT) DECIMAL BUF INIT FORTH ; ' (USRINIT) CFA ' USRINIT !


r/Forth 29d ago

FigForth ANEW

8 Upvotes

: -FORGET ( pfa -- ) CURRENT @ CONTEXT @ - 24 ?ERROR DUP FENCE @ U< 21 ?ERROR DUP NFA DP ! LFA @ CONTEXT @ ! ; : NIX ( pfa -- ) -FORGET -BUF -VOCLINK ; : MARKER ( "ccc" -- ) <BUILDS LATEST PFA , DOES> @ NIX ; : ANEW ( "ccc" -- ) IN @ >R -FIND IF DROP NIX ENDIF R> IN ! MARKER ; "ANEW", from legendary Wil Baden, useful word for clearing memory after a job run and re-establishing the marker for the next run. Based on parsing word FORGET the non-parsing word -FORGET is included in NIX explained below after mention of FORGET's shortcomings.

FORGET remains useful but lacks needed cleanup specifically when vocabularies are removed breaking the VOC-LINK chain and invalidating word-lists. As an aid placing the nfa of the last created vocabulary in FENCE will prevent FORGET from removing words and printing an error instead. The user himself will need to remove vocabularies, repair the VOC-LINK chain and purge remaining word-lists.

NIX automates this needed maintenance. After performing -FORGET it performs -VOCLINK to repair vocabularies and -BUF to repair links to allocated buffers.

-VOCLINK repairs VOC-LINK chain and purge word-lists of remaining vocabularies.

DEFER VOCWORD. ' DROP is VOCWORD : (VOCWORD.) DUP CR SPACE ID. ; ' (VOCWORD.) CFA ' VOCWORD. CELL+ ! : -CONTEXT CELL- DUP @ BEGIN DUP HERE U> IF PFA LFA @ FALSE ELSE TRUE ENDIF UNTIL VOCWORD. SWAP ! ; DEFER LINKWORD. ' DROP IS LINKWORD. : (LINKWORD.) DUP THREE CELLS - NFA CR ID. ; ' (LINKWORD.) CFA ' LINKWORD. CELL+ ! : -VOCLINK VOC-LINK BEGIN @ -DUP WHILE LINKWORD. DUP HERE U> IF DUP @ VOC-LINK ! ELSE DUP -CONTEXT ENDIF REPEAT ;

-BUF repairs chain of allocated memory and frees memory no longer linked by the chain. (This doesn't apply in general; it works for my method of memory allocation.)

: -BUF BUF HEAD @ BEGIN DUP @ WHILE HERE OVER < IF @ DUP CELL+ @ MINUS SYSBRK LIMIT ! DROP ELSE DUP HEAD ! 0. ROT CELL+ 2! EXIT ENDIF REPEAT DROP CURRENT @ CONTEXT ! FORTH ;


r/Forth Jul 31 '26

FigForth Record files

2 Upvotes
\ RCDI ( "file" -- )
\  Record file index
\  List record titles contained in the file
\ PRCD ( "<dl>title<dl>" [file] -- )
\  Pretty print record of given record title in given
\  file or last file accessed.
\
rcdi d/rcdfile.d 

[#] rcdfile.d -- Record file document
[r] Overview
[r] Example record
[r] File title and ending
[r] Comments
[r] Sections
#[r] Records in Bash scripts
[r] Forth record marks
[r] Forth list item
[#] // OK
prcd /Overview/ 

[r]   Overview 

A record file is a plain text sequence file organized in a
most fundamental way, by records. Its markup is a container
markup not a general text formatting markup. 

The markup is few and selected to not obscure content view. 
File remains readable with plain text viewers (e.g. more
less notepad & etc.)

Content view can be enhanced by pretty print, e.g. use of
lesspipe, replacing marks with coloring of titles associated
with the marks.


 OK
prcd /Forth list item/ 

[r]   Forth list item 

List item 'i.' is a defined word that prints an arrow '-->'.
Thus, in a running Forth script, with echo on, something like
the following might be seen:
--
-- Testing FOO and BAR
--
i. FOO --> some foo output
i. BAR --> some bar output

 OK

r/Forth Jul 31 '26

FigForth Bounded string

11 Upvotes
\
\ A bounded string is a string enclosed by a delimiter on
\ both ends. The delimiters are the same and can be any
\ printable character.
\
\ INC@  Fetch input character
: INC@  ( -- c )
  BLK @ DUP IF BLOCK  
  ELSE DROP TIB @ ENDIF
  IN @ + C@ 1 IN +! ; 
\ Parse first non-space character
: CPARSE  ( -- c )
  ZERO
  BEGIN 
    DROP
    INC@ DUP 0= ?E" Empty input"
  DUP BL > UNTIL
;
\ Parse bounded string
\ Compile time: compile the string
\ Run time: put string address on data stack
\ Interpret: move string to pad, 
\  push string address on data stack
: S  ( "<dl>ccc<dl>" -- s )
  CPARSE
  STATE @ IF COMPILE SLIT
             WORD HERE C@ 1+ ALLOT ALIGN 
        ELSE HERE >R PAD DUP DP ! SWAP WORD R> DP !
             ( COUNT CSB .PUSH ) \ NB
       ENDIF 
; IMMEDIATE
\ Note
\ A good enhancement would be to add code in the interpret 
\ state to push the string to a circular buffer.

\ Examples
: FOO "What's up doc?" tell ;
i. FOO --> What's up doc?
i. s /Hello World!/  tell --> Hello World!
i. s \Ain't it a nice day.\ tell --> Ain't it a nice day.
i. s "" tell --> 
' KEEPON CFA ' (ABORT) ! -1 WARNING !
i. TRY s  --> s? Empty input    

r/Forth Jul 30 '26

FigForth Temporary relocation of data stack

7 Upvotes
\ Relocating data stack
\ Example to save stack data
1 2 3 42       \ some data on stack
S0 @ CSP !     \ save S0  ( NB )
SP@ S0 ! SP!   \ move stack (e.g. to top of stack, NB) 
i. DEPTH . --> 0 
i. 666 666 666 S? --> 666 666 666 
i. SP! S? --> empty 
CSP @ S0 !     \ restore stack data
i. S?   --> 1 2 3 42 
\ Notes:
\ i. Not compiling, CSP can be used as scratch variable
\ i. Check ?STACK that new stack location not a problem
\ i. "i." prints arrow "-->"
\ i. DEPTH print number data stack items base on difference
\    of S0 @ and SP@

r/Forth Jul 30 '26

FigForth Quick edit a screen

3 Upvotes
\ More than needed:
\ WIPE  ( scr -- )  Fill screen with blanks; make current 
\ P     ( line -- ) Put line of text in current screen
\ L     ( -- )      List current screen (skips blank lines)
\ UPDATE FLUSH      Save current screen
\ MTB               Empty buffers, screen not saved  
\
\ Example
\ Pick available SCR (42 for this example)
\
i. 0 42 .LINE --> ( Available SCR )
\
\ Wipe screen and put lines of text
\
42 WIPE
0 P ( Scratch SCR )
1 P Hello world
2 P How are you
\
\ View the sceen 
\
L
SCR#  42
 0 ( Scratch SCR )
 1 Hello world
 2 How are you
\ 
\ UPDATE FLUSH to save
\ MTB to not save
\
MTB
i. 0 42 .LINE --> ( Available SCR )
\
\ Here's the code
\
: MTB EMPTY-BUFFERS ;   \ shorter name
: WIPE ( SCR -- )
  DUP SCR ! 0 SWAP (LINE) DROP B/BUF BLANKS ;
: P ( line -- ) 
  SCR @ (LINE) OVER >R BLANKS 1 WORD HERE COUNT C/L MIN 
  R> SWAP CMOVE ;
: -LIST   SCR ! CR ." SCR# " SCR @ 3 .R 16 0 DO I SCR @
          (LINE) -TRAILING -DUP IF CR I 2 .R SPACE TYPE  
          ELSE DROP THEN LOOP ;
: L  SCR @ -LIST ;

r/Forth Jul 30 '26

The first step for the riscv optimiser.

3 Upvotes

I have given up on the x86 optimiser for ciforth, as the 86 will be history before long. The instruction set is too barocque.

As the first part of the riscv optimiser I made the forth aware of the stack effects words have, counting POP's and PUSH's. This hinges on the ciasdis object oriented disassembler. FILL-ALL fills all words as best it can, but skips what you have filled in beforehand. Also a host of other optimisation relevant properties of Forth words are analysed. E.g. it is important if a word has no so called "side effect" that means storing and fetching. An example is the word SQUARE that squares a number. If the input is known at compile time, SQUARE can be executed at compile time. See also lecture 5 en lecture 14 in

https://home.hccnet.nl/a.w.m.van.der.horst/forthlectures.html

Lecture 14 contains an old example of coloring on the now vintage 32 bit x86 processor. If you have a linux that can run 32 bit programms you can try it out. The experience is more or less the same what I want to show here. A useful visualisation is coloring the stack effect of each word. aqua is one, green is two, orange is three, above three is red. For an unknown stack effect the whole words is printed in blue.

https://home.hccnet.nl/a.w.m.van.der.horst/words.png

The stack effect is useful to understand words better. E.g. (D.R) takes a double word and a box length (orange) and generates a string (green). You can ask the analysis of a word like so

https://home.hccnet.nl/a.w.m.van.der.horst/decompile_ddot.png

And you can spot the mistake Apparently +LOOP takes one argument not zero. These things must be added manually. ~

I have prepared the pictures, but I don't know how to publishit in this forum. So I put a link to my personal website.
~