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:
parent
8ce9ab33b5
commit
640471a59e
65
jorth.c
65
jorth.c
|
@ -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++;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue