Forth
Sectorforth
This is the model of sectorforth: https://github.com/cesarblum/sectorforth/tree/master
@ // Read
! // Write
key // getc
emit // putc
sp@ // get data stack pointer
rp@ // get return stack pointer
+ // add
nand // ~(a&b)
0= // -(a==0)
exit // "return"
[ // clear the compile flag
] // set the compile flag
immediate // set the immediate flag on the last word
: // define a new word
; // finish the definition of the new word
here // pointer to the last free space
latest // pointer to the last defined word
sp - data stack pointer
rp - return stack pointer
ip - instruction pointer
w - work register
word {
link
flags
name
code
thread...
}
Direct Threading
// Executed at the start of a compiled word to enter a new frame
nest:
*--rp = ip
ip = w + sizeof(jmp)
jmp next
// Executed at the end of a compiled word to return to the caller
unnest:
ip = *rp++
jmp next
// Executed when we reach the end of a primitive word
// Advance the state of the interpreter to the next word
next:
w = *ip++
jmp %w
Indirect Threading
This actually might be better since I can use W^X code.
struct word {
word *link;
int flags;
char *name;
void (*code)();
word *thread[_];
};
word **ip;
word **rp;
word *w;
nest() {
*--rp = ip;
ip = w->thread;
next();
}
unnest() {
w = *rp++;
next();
}
next() {
w = *ip++;
w->code();
}
Interpreter design
- Add a few arbitrary conditions for a “well-behaved” program
- Use these to make analysis easier
- And to make porting the language easier
- These conditions can be fully checked on an advanced interpreter
- But the ideal bootstrap interpreter should be VERY small
- It’s nice to have
- The precise layout of the word struct and the size of a cell should be hidden
{ body } define fn
Bootstrap Language
[ code to evaluate now ]
name { word body to evaluate later }
# comment