Froth
A Forth-like language and cross-compiler kernel written in ANSI C, built in the late 1990s for one purpose: generating native code for the Texas Instruments TMS320C50 digital signal processor.
Created by Olivier Singla, who credits Christophe Lavarenne for Free-Forth concepts and Francis Cannard for ideas drawn from his ADSP-2105 Forth cross-compiler
Froth - written wfroth when the author means the PC-hosted kernel specifically - is a Forth-like language and compiler built by Olivier Singla in the late 1990s for a single, narrow purpose: writing interactive cross-compilers that generate native code for digital signal processors. It is not a general-purpose Forth system, and its documentation says so plainly. It exists so that a programmer sitting at a PC can drive a Texas Instruments TMS320C50 evaluation board over a serial cable, compile words straight into the DSP’s memory, and run them there.
The language belongs to a category that barely registers in language histories: the deliberately unfinished tool. Its own documents rate the project at 55% complete on the home page and C50 pages - 65% on the separately maintained overview page - the tutorial at 1%, the reference manual at 5%. Those numbers were last touched in 1999 and never moved again. What makes Froth worth a page is not what it achieved but what it captures - the moment when Forth’s oldest argument, that a stack machine is the cheapest possible bridge between a human and a piece of silicon, was applied to DSP development by one person who found the commercial toolchains too heavy.
Not to be confused with: an unrelated modern language also called Froth, a live lexical language for programmable devices created by Nikolai Kozak as a thesis project at NYU ITP and currently released only for an ESP32 target. The two share only a name.
History and Origins
Froth grew out of frustration with the direction of software tooling. The project overview makes the argument directly: modern operating systems and development environments had become so feature-heavy that debugging them cost more than the problems they solved, whereas Forth’s leanness meant there was very little between the programmer and the machine that could go wrong. Simplicity, the author writes, was the driving factor.
The dates on the surviving files sketch the chronology. The reference manual is stamped 3 January 1998; the tutorial 26 December 1998. The newest date on the code itself is 7 February 1999, on the TMS320C50 cross-compiler; the latest stamp on any document is 21 March 1999, on the overview. The web pages that published all of it went up in November 1999 - which is why 1999 is the year conventionally attached to the language, even though the work clearly began at least a year earlier.
Singla credits two people. Christophe Lavarenne contributed “Free-Forth concepts (anonymous definitions among other things), advices, directions” - and the anonymous-definition mechanism turns out to be one of the two features that most visibly separate Froth from standard Forth. Francis Cannard contributed ideas from his own Forth cross-compiler for the Analog Devices ADSP-2105, a closely parallel effort on a different DSP family.
The project moved to SourceForge on 18 May 2001, reportedly under the developer handle lo_gafet, and the GNU General Public License version 2. (The home page’s own licence notice is looser, reading “version 2.1 or later” - a version number the GPL has never had.) The migration gave it a Subversion repository and a download page, but not new development: the pages were last revised on 7 November 2003, and SourceForge records a final administrative update on 19 April 2013 before marking the project inactive.
Design Philosophy
Froth accepts almost all of Forth’s model - a parameter stack, a return stack, a dictionary of words, postfix notation, an interpreter that doubles as a compiler - and then deviates in two specific places. Both deviations exist because the target is a DSP, not a general-purpose CPU.
Everything compiles
Standard Forth has two modes: interpret and compile. Type 2 3 + at a Forth prompt and it executes immediately. Froth does not work that way. As the overview puts it, “wfroth always compile: either a named definition, or an anonymous definition.” There is no interpret state. Code typed outside a colon definition becomes an anonymous definition, and a semicolon is what causes it to be compiled and run.
This is the Free-Forth idea Lavarenne is credited for. It collapses two execution models into one, which matters enormously for a cross-compiler: when the thing you are compiling for is a chip at the other end of a serial cable, “execute this immediately” is not a simple operation, and having exactly one code path to reason about is worth more than the convenience of an interactive calculator.
An address register instead of addresses on the stack
The second deviation is more radical. In Forth, executing a variable pushes its address onto the stack, and you then fetch or store through that address with @ or !. In Froth, executing a variable sets a dedicated address register; the address never reaches the parameter stack at all.
This is a direct concession to DSP architecture. Signal processors like the TMS320C50 have hardware address registers with auto-increment and modulo-addressing modes designed precisely for walking through sample buffers. Pushing addresses onto a software stack and popping them back throws that hardware away. Froth’s model maps a language-level concept onto the register the chip already has.
Key Features
The reference manual groups the word set into four families:
| Category | Contents |
|---|---|
| Integer arithmetic and logic | 32-bit and 64-bit arithmetic, bitwise and logical operations |
| Integer numeric I/O | Reading and printing integer values |
| Stack operations | Parameter stack and return stack manipulation |
| Control structures | IF...ELSE...ENDIF, BEGIN...AGAIN, BEGIN...UNTIL, BEGIN...WHILE...REPEAT, DO...ENDDO, TIMES...ENDTIMES, and a case construct |
Two details are worth pulling out. ENDIF rather than Forth’s conventional THEN is a small readability choice with a long history of partisans in the Forth community. And TIMES...ENDTIMES is a count-only loop with no loop index - the cheapest possible iteration form, and a natural fit for fixed-length filter kernels.
Host and target
The C50 cross-compiler runs in a dual-mode arrangement: the same session can be switched between the host (the PC, where compilation happens) and the target (the DSP, where code runs). Words exist for initialising the serial port, resetting the C50, entering its monitor, and reading or writing both its program and data memory. A pseudo-decompiler lets the programmer inspect what was actually generated.
Code Generation
Froth’s C50 backend is not a bytecode interpreter, and this is the most technically interesting thing about it. Definitions compile to native DSP CALL/RTS instructions - a direct-call threading model. The primitive stack words are inlined as one- or two-instruction macros: DUP and DROP do not become subroutine calls, they become single instructions. The generator also exploits the C50’s delayed branches and delayed calls, which execute the instruction following the branch while the pipeline refills, to shave cycles off control flow.
The documented memory map for the C50 target is fixed and small:
| Region | Address | Size |
|---|---|---|
| Code space | $0A00 | 4 KB |
| Data space | $1A00 | 4 KB |
| Runtime subroutines | $2A00 | - |
| Stub code | $2BB0 | - |
| Parameter stack | $2BD0 (data) | 32 words |
Three of the processor’s registers are reserved by the compiler: AR7 holds the stack pointer, the accumulator ACC caches the top stack value, and AR6 serves as the address register described above. AR3 through AR5 are available as temporaries. Literals get special handling, with separate paths for 8-bit and 16-bit constants so that small values cost less to load.
A 32-word parameter stack is the detail that tells you what kind of programming this was for. That is not a general-purpose runtime; it is a budget, chosen because on a chip with a few kilobytes of on-board RAM every word of stack is a word not available for sample data.
A note on performance: the documentation describes these choices - inlined primitives, direct native calls, delayed-branch scheduling, an accumulator-cached stack top - as cycle-count optimisations, and the reasoning is sound for the C50’s architecture. But no published benchmark compares Froth-generated code against hand-written C50 assembly or against the TI C compiler, and no measured figures exist. The design intent is documented; the resulting speed is not.
Evolution
Froth’s evolution is mostly the absence of one. The self-assessed percentages tell the story: between the March 1999 overview and the last page revision in November 2003, the headline completion figure stayed at 55%, and the code’s last-modified stamp stayed at February 1999. The 2001 SourceForge migration and the 2013 final update were administrative rather than substantive.
The distribution never acquired version numbers. There are two archives - wfroth_exe.tgz, holding the executable and examples, and wfroth_src.tgz, holding the C sources - plus repository access. Anyone wanting to know what a given snapshot contains has to read the files, which is a fair description of the project’s overall documentation posture.
It is worth being precise about platforms, because the record is genuinely inconsistent. The project’s own documentation states that the kernel runs on Windows 95/98/NT and QNX/Photon, and that the C50 toolchain needs a PC with a serial port and TI evaluation hardware. The SourceForge project page, created later, lists BSD and Linux. Both are what their respective sources say; neither is corroborated by the other, and building the ANSI C kernel on a modern Unix has not been verified here.
Current Relevance
Froth is dormant and has been for over two decades. Its target hardware is obsolete - the TMS320C50 is a fixed-point DSP from TI’s early-1990s C5x generation, long superseded - and the host platforms named in its documentation are Windows 98 and QNX 4. There is no community, no mailing list, and no fork of consequence; as of August 2026 the SourceForge download counter reads zero for the week.
What survives is documentary. The pages are still online and still describe, in unusual detail for a hobby project, exactly how one person built a Forth cross-compiler for a DSP: the register allocation, the memory map, the choice of direct-call threading over bytecode, the reason variables set a register instead of pushing an address. For anyone attempting the same thing on modern hardware - and people do, regularly, for ARM Cortex-M and RISC-V - it remains a readable worked example.
The wider tradition Froth belongs to is very much alive. Forth cross-compilers for microcontrollers continue to be written and used; FlashForth for Microchip PIC and AVR parts, PicForth for the PIC16F family, and xForth targeting 8051, AVR, Cortex-M, MSP430, PIC and STM8 all occupy the niche Froth was aiming at. Froth’s particular contribution to that lineage was to take the Free-Forth compile-always model and the address-register idea and show what they look like when the target is a signal processor.
Why It Matters
Froth matters for three reasons, none of them about adoption.
It documents a design trade-off clearly. The address-register decision is a small, sharp example of a language bending to fit hardware rather than abstracting over it. Forth’s convention of putting addresses on the stack is not wrong, but on a chip whose whole architecture is built around address registers with auto-increment, it is wasteful. Froth chose the chip.
It shows what “Forth is small enough to port” actually costs. The claim that a Forth can be brought up on new hardware by one person is a genuine and repeatedly demonstrated strength of the language family. Froth is also evidence of the honest version of that claim: one person got a working kernel, a working cross-compiler, and a serial-link debug loop onto a DSP, and stalled at 55% with the tutorial 1% written. Both halves of that are true at once.
It is an artefact of a specific era of embedded development. A PC, a serial cable at 57,600 baud, a 4 KB code window, a 32-word stack, and an interactive prompt that compiles words straight into a chip. That workflow was once how DSP work got done, and Froth is a well-preserved specimen of it - which is the most useful thing an unfinished language can be.
Sources
- FROTH: Forth for the TMS320C50 - project home page, credits, and download links
- wfroth overview - design goals, differences from standard Forth, completion status
- Forth for the TMS320C50 DSP - code generation model, memory map, register allocation
- Forth Cross-Compiler for the TMS320C5x - host/target operation and serial protocol words
- wfroth reference manual - word categories and control structures
- wfroth tutorial - 26 December 1998 stamp, 1% completion figure
- froth on SourceForge - registration date, license, project status
- frothlang.org - the unrelated modern language of the same name
- xForth - a current cross-compiler in the same niche
Timeline
Notable Uses & Legacy
TMS320C50 evaluation card toolchain
The project's flagship deliverable: an interactive cross-compiler driving a Texas Instruments C50 DSP evaluation card over an RS-232 serial link at 57,600 baud from a PC running Windows 95/98/NT or QNX. The Forth words include serial-port setup, processor reset, monitor entry, and read/write access to the DSP's program and data memory
fcc_c50.wft
The cross-compiler itself, written in Froth rather than C - a self-hosted target description that emits TMS320C50 instructions. It provides stack words, arithmetic and logic, memory access, the IF/ELSE/ENDIF and BEGIN/UNTIL control forms, and a pseudo-decompiler for inspecting generated code
wfroth kernel
The portable half of the project: a Forth-like compiler written in ANSI C - the author is explicit that it is C and not C++ - which the SourceForge project description says requires only glib, and which runs in a plain text console window. It is the piece intended to be reused for DSPs and CPUs other than the C50
Project documentation set
Overview, tutorial, reference, glossary, internals and examples pages, each labelled with its own completion percentage. The set is unusual for its candour - the tutorial announces itself as 1% finished - and it is the primary surviving record of what the language actually did