Erweiterung

Einen Assembler bietet pfe nicht. Man kann es aber leicht durch C-Funktionen erweitern, was allerdings eine neue Übersetzung des Systems mit dem C-Compiler erfordert und insofern in der täglichen Arbeit ein schwacher Trost ist.

Dem C-Programmierer bietet der Rest des Systems folgendes Programmiermodell:

Datentypen:
Mit den Objekten aus Sicht von Forth kompatible Objekte in C sind als die folgenden typedefs bekannt:
Cell
eine Einheit auf dem Stack, Integer-Typ mit Vorzeichen, zuweisungskompatibel mit Zeigertypen.
uCell
eine Einheit auf dem Stack, Integer-Typ ohne Vorzeichen.
dCell
eine doppelt genaue Zahl mit Vorzeichen, struct bestehend aus Cell hi und uCell lo.
udCell
wie dCell, vorzeichenlos.
void (*pcode) (void)
ist ein Zeiger auf eine ein Primitive realisierende C-Funktion, die also der Gestalt void primitive (void) ist. Zur Vermeidung von Namenskollisionen enden die Namen all dieser C-Funktionen in einem Tiefstrich. Zur Erleichterung der Definition gibt es das Makro code(NAME), das den Funktionskopf void NAME_(void) erzeugt. Im Kopf jedes Wortes steht ein solcher Zeiger auf die auszuführende Funktion.
pcode *CFA
ist der Typ des Execution Tokens, ein Zeiger auf die Position im Kopf eines Wortes, wo der Zeiger auf dieas Wort realisierende C-Funktion steht.

Register der virtuellen Maschine
sind global deklarierte C-Variablen:
Cell *sp
Daten-Stackpointer
CFA *ip
Instruktionszeiger. Zeigt in die Liste compilierter Worte, deren jedes jeweils genau das Execution Token, also ein Zeiger des Typs CFA ist.
CFA **rp
Der Return-Stack dient zur Sicherung des ip, der Stapelzeiger ist also ein Zeiger auf den Typ des ip.
CFA w
Das W-Register der virtuellen Maschine, hier kann ein Primitive seine eigene CFA ablesen. Zugriff auf den Body des Wortes über (typ *)&w[1].

Systemvariablen
Weil die Art der Speicherung der Systemvariablen sich ändern k÷nnte, gibt es zum Zugriff auf die in Forth definierten Systemvariablen Makros mit nahenliegenden Namen. So kann in C-Funktionen z.B. auf den DP unter dem Namen DP zugegriffen werden usw.

Funktionen
Das System enthält hunderte von C-Funktionen, wovon natürlich nicht jede in ihrer jetzigen Form garantiert – oder gar dokumentiert – werden kann. Beispiele:
void abortq (char *fmt, ...);
gibt – mit den Fähigkeiten von printf() ausgestattet – eine Fehlermeldung aus und führt -2 THROW aus.
void type (char *s, Cell n)
gibt eine Zeichenkette wie TYPE aus.
char *word (char del)
wie das Forth-Wort WORD, liest ein Wort aus dem Eingabestrom in den Speicher ab HERE und übergibt diese Stelle als Funktionsergebnis.
void run_forth (CFA xt);
führt ein beliebiges (auch High-level) Forth Wort aus. Enthält den inneren Interpreter.

Makros
erleichtern die Anpassung von C an Forth sehr, weil sich darin viele der notwendigen Type-Casts verbergen lassen. Einige Beispiele:
POP(T,P,X)
liest ein Objekt des Typs T über den Zeiger P in die Variable X, unabhängig von den tatsächlichen Typen der Operanden. Erh÷ht P entsprechend.
PUSH(T,X,P)
Umkehrung zu POP, schreibt ein Objekt X des Typs T in einen zu kleineren Adressen hin wachsenden Stapel mit Stapelzeiger P.
RPUSH(X)
legt ein Objekt der Grևe einer Cell auf den Return-Stack.
RPOP(X)
holt eine Cell vom Return-Stack.
FLAG(X)
macht aus X ein Forth-Flag, also 0 bzw. -1.
COMMA(X)
schreibt das Objekt X der Grևe 1 Cell ins Dictionary.

Will man das System zum Beispiel um einen für ein bestimmtes Betriebssystem wichtigen Satz von Worten erweitern, bietet sich die Anlage einer entsprechenden Quelltextdatei an. Sie enthält alle system- oder aufgabenspezifischen C-Funktionen, die in eine Reihe von C-Funktionen münden, die die Gestalt von Forth-Primitives haben, also mit dem Makro Code (name) deklariert sind. Diese Primitives werden in eine Wortliste zusammengefaát, die beim System registriert wird14 und so beim Start von pfe mit ins Dictionary geladen wird.

Vollständiges Beispiel:

#include "forth.h"
#include "support.h"

Code (user_added_primitive)
{
  outs ("\nThis is a sample primitive."
        " See src/yours.c "
        "for it's definition.\n");
}

LISTWORDS (your) =
{
  CO ("USER-ADDED-PRIMITIVE",
       user_added_primitive),
};
COUNTWORDS (your, "Your kernel extensions");

Das Makro LISTWORDS deklariert eine Wortlisten-Struktur, die zu Initialisieren ist mithilfe der Makros:

CO(NM,PCODE) gew÷hnliches Wort
CI(NM,PCODE) immediate Wort
CS(NM,SEM) Compiler Erweiterung
SV(NM,VAR) Systemvariable
SC(NM,VAR) Forth-Konstante, deren Wert aus einer Variablen stammt
OC(NM,VAL) normale Konstante
VO(NM,RUNTM) WORDLIST
Das Makro COUNTWORDS zählt schlicht die Anzahl Worte in der Liste und stellt sie zur Einbindung bereit.