Language Support

It may be nearly unthinkable that a small system in such an atypical environment should support a high level programming language. In fact, the amount of support required for any common high level language would be a tremendous burden. In addition to the resources and codespace a high level language needs, there would also have to be a custom compiler and/or an assembler written for this design.

However, there is an uncommon "high level language" that was designed specifically for resource restricted devices. It is often called a programmer's tool, rather than a language because it's actually much more than what is understood as a programming language. This tool is the Forth language.

A complete description of Forth will not be included here, but its highlights and applicability to this design are discussed below. The design also included other resources not needed to support Forth but which are generally assumed for other languages. These are included for completeness and to provide a familiarity to assembler/machine level programming.

=Forth Description= Forth is an interpreted/compiled, extensible, interactive language which is quite unlike any other popular language. It has its roots in small, fast embedded systems and enjoys great success in those types of applications to this day.

Programs written in Forth are written in small routines called 'words'. New words are either a sequence of machine code commands or a series of previously defined words. As soon as a new word is written, it may be tested since most Forth systems include a built-in interpreter. This interactivity makes testing both the hardware and software very easy and allows errors to be caught asap.

A new word's definition may simply be typed out into the console and immediately executed. This way it can be tested without even a re-compile step. That is the great benefit to an interpreted language. Once the code is complete, it may be completely compiled and loaded into the system. Forth uses two interpreters - the 'outer interpreter' takes the new word's definition and looks for each word included in that definition. Assuming it is found, the definition of the found word is then passed to the 'inner interpreter' to be executed. The outer interpreter is what gives Forth its interactivity since it can accept input directly from the console. The inner interpreter continues through the indirection of defined words until it reaches the level of 'primitives' - that is, words that are defined in machine code. These are allowed to execute on the CPU core and the definition tree is followed again until the end of the word being executed is reached.

Each new 'word' becomes a new language command, or what other languages may call a 'reserved word'. These new words may be used in other parts of the code, effectively extending the language's commands. Hence, Forth is 'infinitely' extensible.

Threaded Languages
A threaded language is quite different than the more commonly known types (which can trace their roots back to Algol). In a threaded language each command or word, is defined by a sequence of previously defined commands. A program or function or command is initiated just by 'calling' its name. The most basic of these words are written in machine code rather than by using other words. These are called the primitives. A command is executed by simply executing each word in its definition, in the defined order. As each word in this definition is executed, it also may be a sequence of other words. Each of those words is executed in the proper order as well before continuing on with the following word in the primary command. Thus the term 'threading' is used to describe this means of execution. It is this threading that allows the language itself to grow with each newly defined word (or command).

The mechanism that keeps track of and controls this threading (and thus the program's execution) is called the inner interpreter. Several types of threaded execution models have been developed, usually because of limitations of the underlying hardware. These are usually called direct, indirect, subroutine and token threaded models. This design uses a subroutine threaded execution model. Other models will not be detailed here.

In a subroutine threaded execution model, the definition of each (non-primitive) word is a subroutine call. If the hardware supports nested subroutines, this is a very efficient model. Furthermore, even each primitive is a simple subroutine. Rather than a sequence of calls to other words, it is just machine code. This model allows for features not available in the other threading models. Since the definition is machine executables (calls), mcahine code itself may be inserted into the definition, interspersed within the predefined words. Peephole optimization may be done by replacing one or more word 'calls' with the actual machine code they represent. The interpreter won't care.

=Supporting Forth=

Forth has several requirements to run smoothly. The most critical of these is the mechanism needed to provide the threading, called the inner interpreter.

The Inner Interpreter
Forth normally runs on a virtual machine called the inner interpreter, which is implemented by a few machine code routines. That forms the basis for the threading mechanism. As explained above, this design implements a subroutine threaded execution mechanism. In a subroutine threaded Forth, the inner interpreter is the subroutine call/return function. This design provides a fast call/return response in hardware and inner interpreter is directly implemented by this hardware.

Other primitives needed to run the Forth virtual machine are performed by hardware as much as possible. In particular, various basic and essential stack and data manipulation functions are implemented in hardware to give the best speed possible. This is evidenced by the Instruction Set.

=Support for other languages=

Algol-descended languages such as 'C' use a stack frame to save parameters left in registers, when entering a sub-routine (or switching processes). Since Forth keeps its parameters on the stack already, there is no need for such stack frames.