A simple, indirect-threaded Forth, written in C; for target compiling; runs on Linux, BSD, OSX, and Cygwin
Forth Assembly C Lua Roff Shell Other
Switch branches/tags
Nothing to show
Latest commit a75257f May 12, 2017 @nimblemachines [REBUILD] core: Moving catch/throw closer to usefulness...
catch  and  throw  are now "native" Klaus Schleisiek style (KS-style)
return stack words. If you don't know what that means, you can try to
find the 1984 FORML proceedings and read his article that starts on
p361. It certainly blew *my* mind...

The basic idea (of KS-style words) is to "misuse" the return stack to
store local variables, or the original value of a global variable (which
has been temporarily set to a different value for the duration of the
execution of a single word), or to register "fixup" actions - like
closing of file descriptors - that should happen when a word exits.

The neat thing is that these frames are unbuilt, and the cleanup actions
executed, *either* when the word that has built them exits normally *or*
when some kind of exception unwinds the R stack.

Currently,  throw  is the only thing that ever unwinds the R stack, and
it is called by abort (which is, in turn, called whenever C code returns
an error).

As part of this commit I reverted an "optimization" to the word  unlink
. My version of  unlink  is now identical to KS's.

I am still throw'ing a string value (a zero-terminated C string), and so
it is difficult, in muforth code, to tell what kind of error has
occurred. One thing that *has* changed in this commit is that the error
(and the context in which it occurred) is no longer printed by abort.
Instead, the code catch'ing the error string (look in the word  warm  in
startup.mu4 for how this works in the muforth text interpreter) prints
it. You can certainly retry a piece of code on *any* error, but what I'd
ideally like is for muforth code to be able to tell the *class* of error
that has occurred, and handle it or not as it sees fit. (And if it
chooses *not* to handle it, it can re-throw it, and the innermost
enclosing  catch  will catch it.)

I'm not exactly sure how to do this - somehow *map* all the errno values
to a small number of "muforth error" equivalence classes? - but this
commit gets us closer to that ideal.


What is muforth?

muforth is a small, simple, fast, indirect-threaded code (ITC) Forth intended for use as a cross-compiler for microcontrollers and other embedded devices. It is written in C and its core is very portable. Because of its Forth nature, it is naturally extensible, scriptable, and customizable.

It is very well-suited to interactive coding, debugging, and exploration, and is a great tool for bringing up new hardware.

It has support - in varying degrees of completeness - for the following architectures:

Why yet another Forth?

I initially wrote muforth because I wanted to try out some implementation ideas. Today there is very little that distinguishes muforth from fig-FORTH - but the differences go rather deep.

Its implementation is no longer the point. Its sole reason for existing is to be a cross/meta/target-compiler for other Forths, and their implementations are in no way tied to muforth's.

Starting points

BUILDING will tell you how to build muforth. It's stupid simple.

Sadly, there isn't a lot of documentation right now. A good place to start is to read the source. It's generally well-commented, and is intended to be read and understood. mu/startup.mu4 - which is read and executed every time muforth starts - is the heart of the system.

Look in mu/target/ to find a target that interests you. There is generally a mu/target//build.mu4 that loads the cross-build environment. Use it as an "index" to find the assembler, disassembler, meta-compiler, kernel, and other key pieces of code.

muforth.nimblemachines.com is also, finally, spreading its wings.

Above all, enjoy!