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 <stdio.h>
#include <sys/stat.h> #include <sys/stat.h>
@ -440,25 +440,8 @@ void f_cdef() { // func name --
f_comma(); f_comma();
} }
void f_docolon();
void f_revlookup(); 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 #ifdef TRACE
void f_traceon() { void f_traceon() {
TRACING = 1; TRACING = 1;
@ -466,11 +449,8 @@ void f_traceon() {
void f_traceoff() { void f_traceoff() {
TRACING = 0; TRACING = 0;
} }
#endif
void f_colondispatch() { void f_colondispatch() {
cell codeptr;
#ifdef TRACE
static int printing = 0; static int printing = 0;
if (TRACING && !printing) { if (TRACING && !printing) {
@ -487,15 +467,11 @@ void f_colondispatch() {
} }
printing = 0; printing = 0;
} }
#endif W.p->f();
codeptr = *W.p;
if (codeptr.f == f_docolon) {
RPUSH(IP);
IP.p = W.p + 1;
} else {
codeptr.f();
}
} }
#else
#define f_colondispatch() W.p->f()
#endif
void f_colonloop() { void f_colonloop() {
while (IP.p) { 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 // this version of f_execute can be run from a colon word
void f_execute() { void f_execute() {
W = TOP(); W = TOP();
@ -522,6 +488,27 @@ void f_execute() {
f_colondispatch(); 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_() { void f_lit_() {
PUSHC(*IP.p); PUSHC(*IP.p);
IP.p++; IP.p++;

View file

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