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 <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++;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue