Simplify colon loop / dispatch; avoid word lookup for tick/draw

Substantial speed gains _and_ f_cexecute() now works for deferred words.
This is the first version of Jorth where I feel like I've gotten the VM
right enough that it can reasonably be called a proper Forth implementation.
This commit is contained in:
Jeremy Penner 2019-04-07 22:13:32 -04:00
parent 8ce9ab33b5
commit 640471a59e
4 changed files with 31 additions and 41 deletions

BIN
game.exe

Binary file not shown.

BIN
game.prj

Binary file not shown.

65
jorth.c
View file

@ -1,4 +1,4 @@
#define TRACE
//#define TRACE
#include <stdio.h>
#include <sys/stat.h>
@ -440,25 +440,8 @@ void f_cdef() { // func name --
f_comma();
}
void f_docolon();
void f_revlookup();
// C code must always call a colon word through f_cexecute()
void f_cexecute() {
cell oldW = W;
cell oldIP = IP;
cell retIP;
retIP.p = NULL;
W = TOP();
DROP(1);
if (W.p->f == f_docolon) {
RPUSH(retIP);
}
W.p->f();
W = oldW;
IP = oldIP;
}
#ifdef TRACE
void f_traceon() {
TRACING = 1;
@ -466,11 +449,8 @@ void f_traceon() {
void f_traceoff() {
TRACING = 0;
}
#endif
void f_colondispatch() {
cell codeptr;
#ifdef TRACE
static int printing = 0;
if (TRACING && !printing) {
@ -487,15 +467,11 @@ void f_colondispatch() {
}
printing = 0;
}
#endif
codeptr = *W.p;
if (codeptr.f == f_docolon) {
RPUSH(IP);
IP.p = W.p + 1;
} else {
codeptr.f();
}
W.p->f();
}
#else
#define f_colondispatch() W.p->f()
#endif
void f_colonloop() {
while (IP.p) {
@ -505,16 +481,6 @@ void f_colonloop() {
}
}
void f_docolon() {
IP.p = W.p + 1;
f_colonloop();
}
void f_dodeferred() {
W = *(W.p + 1);
f_colondispatch();
}
// this version of f_execute can be run from a colon word
void f_execute() {
W = TOP();
@ -522,6 +488,27 @@ void f_execute() {
f_colondispatch();
}
// C code must always call a colon word through f_cexecute()
void f_cexecute() {
cell oldW = W;
cell oldIP = IP;
IP.p = NULL;
f_execute();
f_colonloop();
W = oldW;
IP = oldIP;
}
void f_docolon() {
RPUSH(IP);
IP.p = W.p + 1;
}
void f_dodeferred() {
W = *(W.p + 1);
f_colondispatch();
}
void f_lit_() {
PUSHC(*IP.p);
IP.p++;

View file

@ -271,6 +271,7 @@ void do_repl() {
}
int main(int argc) {
cell tick, draw;
if (argc > 1) {
do_repl();
return 0;
@ -278,14 +279,16 @@ int main(int argc) {
ser_init(SER_COM2, BAUD_19200, SER_8N1);
game_init();
game_f_init();
tick = f_lookupcp("tick");
draw = f_lookupcp("draw");
while (!keyIsDown(K_ESC)) {
kbd_debounce();
f_poll();
f_taskloop();
f_runstring("tick");
f_execcp(tick);
f_taskloop();
f_runstring("draw");
f_execcp(draw);
}
return 0;