Libforth
libforth: A small Forth interpreter that can be used as a library written in c99
Install / Use
/learn @howerj/LibforthREADME
% FORTH(1) % Richard Howe % November 2016
NAME
forth - a forth interpreter
SYNOPSIS
forth [-s file] [-e string] [-l file] [-m size] [-VthvLSnx] [-] [files]
DESCRIPTION
A Forth interpreter built around a library, libforth, that implements a complete Forth interpreter.
For a much better, albeit 16-bit only, Forth that is also very well documented and (slightly more) standards compliant, please visit the more up to date Embed virtual machine. Also of interest is the Forth CPU I wrote, in VHDL, for an FPGA.
This interpreter is available at here.
OPTIONS
Command line switches must be given before any files, unless that switch takes a file as an argument.
- -s file
This saves the working memory of the Forth interpreter to a file, which can later be loaded with the "-l" option. If a core file has been invalidated this will not be saved, invalidation occurs when an unrecoverable error has been detected that would prevent any recovery or meaningful execution with the current image.
- -e string
Evaluate a Forth string passed in as an argument.
- -t
After all the files have been read from and any core files have been loaded this will make the Forth interpreter read from [stdin][], the core file will be saved after [stdin][] has been read from and there is no more work to do, if the "-d" or "-s" flags have been specified.
- -h
Print out a short help message and exit unsuccessfully.
- -v
Turn verbose mode on, more information will be printed out, to [stderr][], about what is happening in the interpreter. Usually the interpreter is as silent as possible.
- -m size
Specify the virtual machines memory size in kilobytes, overriding the default memory size. This is mutually exclusive with "-l".
- -l file
This option loads a forth core file generated from the "-d" option of a previous run. This core file is not portable and must be generated on the same platform as it was generated. It can only be specified once per run of the interpreter.
- -L
The same as "-l", however the default core file name is used, "forth.core", so an argument does not have to be provided.
- -S
The same as "-s", however the default core file name is used, "forth.core", so an argument does not have to be provided.
- '-'
Stop processing any more command line options and treat all arguments after this as files to be executed, if there are any.
- -V
Print version and interpreter information and exit successfully.
- -f file
Process a file immediately. This allows options and file arguments to be intermingled.
- -n
If the line editing library is compiled into the executable, which is a compile time option, then when reading from [stdin][] this will use a [line editor][] to read in a line at a time. This option implies -t.
- -x
Enable signal handling, signal handling is experimental and not quite worked out yet. It is off by default as I find it annoying when programs catch signals when you really want to program to die. This cannot be enabled from within the Forth interpreter. This option should disappear once signal handling has been sorted out.
- file...
If a file, or list of files, is given, read from them one after another and execute them. The dictionary and any stored Forth blocks will persist, as will values on the stack.
If no files are given to execute [stdin][] will be read from.
EXAMPLES
./forth
Execute any commands given from [stdin][]
./forth -t file1.4th file2.4th
Execute file "file1.4th", then "file2.4th", then read from [stdin][]
./forth file1.4th
Execute file "file1.4th".
./forth -s file1.4th
Execute file "file1.4th", the produce a "forth.core" save file.
./forth -s -l forth.core
Load a "forth.core" file, read from [stdin][] and execute any commands given, then dump the new core file to "forth.core".
The interpreter returns zero on success and non zero on failure.
LICENSE
The Forth interpreter and the library that implements it are released under the [MIT][] license. Copyright (c) Richard Howe, 2016.
EXIT STATUS
This program will return a non-zero value on failure, and zero on success.
SEE ALSO
libforth(3)
BUGS
If you find a bug, or would like to request a new feature, please Email me at:
howe.r.j.89 [ at ] gmail . com
The interpreter has not been battle hardened yet so there is likely behavior that is non-standard (for no reason) or just outright incorrect.
MANUAL
This small [Forth][] interpreter is based on a de-obfuscated entrant into the [IOCCC][] by buzzard. The entry described a [Forth][] like language which this derives from. You can use this library to evaluate [Forth][] strings or as an embeddable interpreter. Work would need to be done to get useful information after doing those evaluations, but the library works quite well.
main.c is simply a wrapper around one the functions that implements a simple [REPL][].
This project implements a [Forth][] interpreter library which can be embedded in other projects, it is incredibly minimalistic, but usable. To build the project a [C][] compiler is needed, and a copy of [Make][], type:
make help
For a list of build options. By running:
make run
Will build the interpreter and run it, it will then read from [stdin][].
To build the documentation other programs may be needed, such as [pandoc][] and the [markdown script][], but these steps are optional.
[Forth][] is an odd language that has a loyal following groups, but it is admittedly not the most practical of language as it lacks nearly everything the modern programmer wants in a language; safety, garbage collection, modularity and clarity. It is however possible to implement a fully working interpreter in a one to two kilobytes of assembly, those kilobytes can make a functional and interactive programming environment, giving a high ratio of utility memory used.
From the [Wikipedia][] article we can neatly summarize the language:
"Forth is an imperative stack-based computer programming language
and programming environment.
Language features include structured programming, reflection (the
ability to modify the program structure during program execution),
concatenative programming (functions are composed with juxtaposition)
and extensibility (the programmer can create new commands).
...
A procedural programming language without type checking, Forth features
both interactive execution of commands (making it suitable as a shell
for systems that lack a more formal operating system) and the ability
to compile sequences of commands for later execution."
Given the nature of the [Forth][] language it does not make for a terribly good embeddable scripting language, but it is simple to implement and can be fun to use. This interpreter is based off a previous [IOCCC][] in a file called [buzzard.2.c][], it is a descendant of that file.
Before using and understanding this library/interpreter it is useful to checkout more literature on [Forth][] such as [Thinking Forth][] by Leo Brodie for a philosophy of the language, [Starting Forth][] (same Author), [Jonesforth][] which is a specific implementation of the language in x86 assembly and [Gforth][], a more modern and portable implementation of the language.
It is important to realize that [Forth][] is really more a philosophy and collection of ideas than a specific reference implementation or standard. It has been said that an intermediate [Forth][] user is one who has implemented a [Forth][] interpreter, something which cannot be said about other languages nor is possible given their complexity.
The saying "if you have seen one Forth implementation, you have seen one Forth implementation" applies, nearly every single [Forth][] implementation has its own idea of how to go about things despite standardization efforts - in keeping with this, this library has its own idiosyncrasies.
This implementation, written in [C][], can be thought of as a hybrid between a fairly dumb stack based virtual machine with instructions such as "pop two values off the stack, add them, and push the result" and a small interpreter/compiler for the virtual machine. This simple kernel is then used to build a more compliant and usable [Forth][] implementation by defining words that build upon those provided by the base system.
Other documentation
Apart from this file there are other sources of information about the project:
As can the code, which is small enough to be comprehensible:
- [libforth.c][] (contains the core interpreter)
- [libforth.h][] (contains the API documentation)
And the forth startup code:
- [forth.fth][]
The startup code is well commented and shows how the core interpreter is extended to a more function [Forth][] environment.
The source file [libforth.c][] can be converted to a more readable webpage by first converting the source to [markdown][] with [convert][] script, the converting that to HTML in the usual fashion
Using the interpreter
main.c simple calls the function main_forth() in libforth.c, this function initializes a [Forth][] environment and puts the user in a [REPL][] where you can issue commands and define words. See the manual pages for list of command line options and library calls. All commands are given using [Reverse Polish Notation][] (or RPN),
So:
2+(2*4)
Becomes:
4 2 * 2 +
And brackets are no longer needed. Numbers of pushed on to the variable stack automatically and commands (such as '*' and '+') take their operands off the stack and push the result. Juggling variables on the stack becomes easier over time. To pop a value from the stack and print it there
Related Skills
node-connect
349.0kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
109.4kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
349.0kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
349.0kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
