Implement Jorth interpreter in Jorth so its task can be suspended

This commit is contained in:
Jeremy Penner 2019-02-09 21:52:12 -05:00
parent 6552c1498b
commit c8331edece
7 changed files with 150 additions and 84 deletions

42
boot.jor Executable file
View file

@ -0,0 +1,42 @@
2 const cell
: cells cell * ;
key ) const ')'
10 const '\n'
key const sp
128 const F_IMMEDIATE
: cr '\n' emit ;
: bl sp emit ;
: if ' BZ_ , here 0 , ; immediate
: else ' GOTO_ , 0 , here swap ! here cell - ; immediate
: then here swap ! ; immediate
: begin here ; immediate
: while ' BZ_ , here 0 , ; immediate
: repeat ' GOTO_ , swap , here swap ! ; immediate
: again ' GOTO_ , , ; immediate
: until ' BZ_ , , ; immediate
: ( begin key ')' = until ; immediate
: lit ' LIT_ , , ;
: interpretword F_IMMEDIATE & state not or if execute else , then ;
: interpretnumber state if lit then ;
: interpretunknown type s" ?" type cr ;
: compileword lookup dup
if interpretword
else drop number
if interpretnumber
else interpretunknown
then
then ;
: interpreter
begin word dup b@ while compileword repeat
s" ok" type cr drop ;
: load-input swap-input r> r> interpreter r< r< swap-input ;
: loadstring ' key-string load-input drop drop ;
: loadfile ' key-file load-input drop close ;

View file

@ -2,29 +2,6 @@
s" jorth.log" open const LOGFILE s" jorth.log" open const LOGFILE
: log-emit LOGFILE fputc ; : log-emit LOGFILE fputc ;
2 const cell
: cells cell * ;
key ) const ')'
10 const '\n'
key const sp
: cr '\n' emit ;
: bl sp emit ;
: if ' BZ_ , here 0 , ; immediate
: else ' GOTO_ , 0 , here swap ! here cell - ; immediate
: then here swap ! ; immediate
: begin here ; immediate
: while ' BZ_ , here 0 , ; immediate
: repeat ' GOTO_ , swap , here swap ! ; immediate
: again ' GOTO_ , , ; immediate
: until ' BZ_ , , ; immediate
: ( begin key ')' = until ; immediate
' cells @ const docolon ( get the colon execution token ) ' cells @ const docolon ( get the colon execution token )
: :noname here docolon , ] ; : :noname here docolon , ] ;
@ -39,8 +16,6 @@ key const sp
1 + ( cp i+1 ) 1 + ( cp i+1 )
repeat drop drop then drop ; repeat drop drop then drop ;
: lit ' LIT_ , , ;
( tasks ) ( tasks )
: mailbox 2 cells + ; : mailbox 2 cells + ;
: task-ip task-user-size cells + ; : task-ip task-user-size cells + ;

BIN
game.exe

Binary file not shown.

BIN
game.prj

Binary file not shown.

145
jorth.c
View file

@ -88,6 +88,11 @@ BINOP(f_uge, u, >=)
BINOP(f_ugt, u, >) BINOP(f_ugt, u, >)
BINOP(f_ult, u, <) BINOP(f_ult, u, <)
BINOP(f_ule, u, <=) BINOP(f_ule, u, <=)
BINOP(f_and, u, &&)
BINOP(f_or, u, ||)
BINOP(f_bitand, u, &)
BINOP(f_bitor, u, |)
BINOP(f_bitxor, u, ^)
void f_eq0() { void f_eq0() {
TOP().i = (TOP().i == 0); TOP().i = (TOP().i == 0);
@ -146,6 +151,15 @@ void f_rot() { // a b c -- b c a
ST2() = b; ST2() = b;
} }
void f_rput() {
RPUSH(TOP());
DROP(1);
}
void f_rtake() {
PUSHC(*RPOP());
}
void f_cexecute(); void f_cexecute();
void f_key_string() { void f_key_string() {
@ -180,8 +194,9 @@ void f_key_file() {
void f_key() { void f_key() {
cell *keyword = RUNNING + TASK_USER_KEY; cell *keyword = RUNNING + TASK_USER_KEY;
cell *echoword = RUNNING + TASK_USER_ECHO; cell *echoword = RUNNING + TASK_USER_ECHO;
if (keyword->f) { if (keyword->p) {
keyword->f(); PUSHCP(keyword->p);
f_cexecute();
} else { } else {
PUSHI(0); PUSHI(0);
} }
@ -368,11 +383,15 @@ void f_lit_() {
IP.p++; IP.p++;
} }
void f_number() { // str -- num isnum void f_number() { // str -- (num 1 | str 0)
int num = 0, result; int num = 0, result;
result = sscanf(TOP().s, "%d", &num); result = sscanf(TOP().s, "%d", &num);
if (result == 1) {
TOP().i = num; TOP().i = num;
PUSHI(result == 1); PUSHI(result == 1);
} else {
PUSHI(0);
}
} }
void f_streq() { void f_streq() {
@ -381,16 +400,30 @@ void f_streq() {
TOP().i = result == 0; TOP().i = result == 0;
} }
void f_wordname() {
TOP().p = TOP().p + 2;
}
void f_wordflags() {
TOP().u = TOP().p[1].u;
}
void f_codepointer() {
unsigned int flags = TOP().p[1].u;
TOP().p = CELL_OFFSET(TOP().p + 2, (flags & ~F_IMMEDIATE) + 1);
}
void f_lookup() { // name -- (codepointer flags) | (name 0) void f_lookup() { // name -- (codepointer flags) | (name 0)
cell *entry = LATEST; cell *entry = LATEST;
while (entry) { while (entry) {
f_dup(); f_dup();
PUSHP(entry + 2); PUSHP(entry);
f_wordname();
f_streq(); f_streq();
if (TOP().i) { if (TOP().i) {
unsigned int flags = entry[1].u; TOP().p = entry;
TOP().u = flags; f_codepointer();
ST1().p = CELL_OFFSET(entry + 2, (flags & ~F_IMMEDIATE) + 1); f_swap();
TOP().p = entry;
f_wordflags();
return; return;
} }
DROP(1); DROP(1);
@ -402,13 +435,15 @@ void f_lookup() { // name -- (codepointer flags) | (name 0)
void f_revlookup() { // codepointer -- name void f_revlookup() { // codepointer -- name
cell *entry = LATEST; cell *entry = LATEST;
while (entry) { while (entry) {
unsigned int length = entry[1].u & ~F_IMMEDIATE; PUSHCP(entry);
cell *name = entry + 2; f_codepointer();
cell *cp = CELL_OFFSET(name, length + 1); if (TOP().p == ST1().p) {
if (cp == TOP().p) { DROP(1);
TOP().p = name; TOP().p = entry;
f_wordname();
return; return;
} }
DROP(1);
entry = entry->p; entry = entry->p;
} }
TOP().p = NULL; TOP().p = NULL;
@ -477,14 +512,12 @@ void f_compileword() { // name --
f_lookup(); f_lookup();
if (!TOP().u) { // name 0 if (!TOP().u) { // name 0
DROP(1); // name DROP(1); // name
f_dup(); // name name f_number(); // n isnum
f_number(); // name n isnum
if (TOP().i) { if (TOP().i) {
f_rot(); // name n isnum -- n isnum name DROP(1);
DROP(2); // n isnum w -- n
f_interpretnumber(); f_interpretnumber();
} else { } else {
DROP(2); // name DROP(1);
f_interpretunknown(); f_interpretunknown();
} }
} else { // codepointer flags } else { // codepointer flags
@ -512,37 +545,21 @@ void f_open() {
} }
void f_close() { void f_close() {
if (TOP().fp) {
fclose(TOP().fp); fclose(TOP().fp);
DROP(1);
}
void f__loadfile() {
cell *key = RUNNING + TASK_USER_KEY;
cell *keysrc = RUNNING + TASK_USER_KEYSRC;
cell oldKey = *key;
cell oldKeysrc = *keysrc;
key->f = f_key_file;
keysrc->fp = TOP().fp;
DROP(1);
f_interpreter();
if (key->fp != NULL) {
fclose(key->fp);
} }
*key = oldKey; DROP(1);
*keysrc = oldKeysrc;
} }
void f_loadstring() { void f_swapinput() {
cell *key = RUNNING + TASK_USER_KEY; cell *key = RUNNING + TASK_USER_KEY;
cell *keysrc = RUNNING + TASK_USER_KEYSRC; cell *keysrc = RUNNING + TASK_USER_KEYSRC;
cell oldKey = *key; cell oldKey = *key;
cell oldKeysrc = *keysrc; cell oldKeysrc = *keysrc;
key->f = f_key_string; *key = TOP();
keysrc->s = TOP().s; *keysrc = ST1();
DROP(1); TOP() = oldKey;
f_interpreter(); ST1() = oldKeysrc;
*key = oldKey;
*keysrc = oldKeysrc;
} }
void f_taskemit() { void f_taskemit() {
@ -650,12 +667,18 @@ void f_quote() {
void f_loadfile(char *filename) { void f_loadfile(char *filename) {
PUSHS(filename); PUSHS(filename);
f_open(); f_open();
f__loadfile(); PUSHS("loadfile");
f_lookup();
DROP(1);
f_cexecute();
} }
void f_runstring(char *s) { void f_runstring(char *s) {
PUSHS(s); PUSHS(s);
f_loadstring(); PUSHS("loadstring");
f_lookup();
DROP(1);
f_cexecute();
} }
void f_quiet() { void f_quiet() {
@ -716,11 +739,13 @@ void f_rstacksize() {
void f_taskusersize() { void f_taskusersize() {
PUSHU(TASK_USER_SIZE); PUSHU(TASK_USER_SIZE);
} }
#define CDEF(name, def) PUSHP(def); PUSHS(name); f_cdef()
void f_init() { void f_init() {
CDEF("[", f_compileoff); f_immediate(); CDEF("[", f_compileoff); f_immediate();
CDEF("]", f_compileon); CDEF("]", f_compileon);
CDEF("key", f_key); CDEF("key", f_key);
CDEF("key-string", f_key_string);
CDEF("key-file", f_key_file);
CDEF("emit", f_emit); CDEF("emit", f_emit);
CDEF("word", f_word); CDEF("word", f_word);
CDEF("immediate", f_immediate); CDEF("immediate", f_immediate);
@ -753,6 +778,11 @@ void f_init() {
CDEF("u>", f_ugt); CDEF("u>", f_ugt);
CDEF("u<", f_ult); CDEF("u<", f_ult);
CDEF("u<=", f_ule); CDEF("u<=", f_ule);
CDEF("and", f_and);
CDEF("or", f_or);
CDEF("&", f_bitand);
CDEF("|", f_bitor);
CDEF("^", f_bitxor);
CDEF("@", f_get); CDEF("@", f_get);
CDEF("!", f_set); CDEF("!", f_set);
CDEF("b@", f_bget); CDEF("b@", f_bget);
@ -762,9 +792,12 @@ void f_init() {
CDEF("drop", f_drop); CDEF("drop", f_drop);
CDEF("swap", f_swap); CDEF("swap", f_swap);
CDEF("rot", f_rot); CDEF("rot", f_rot);
CDEF("r>", f_rput);
CDEF("r<", f_rtake);
CDEF("emit", f_emit); CDEF("emit", f_emit);
CDEF("task-emit", f_taskemit); CDEF("task-emit", f_taskemit);
CDEF("task-echo", f_taskecho); CDEF("task-echo", f_taskecho);
CDEF("swap-input", f_swapinput);
CDEF("putc", f_putc); CDEF("putc", f_putc);
CDEF("fputc", f_fputc); CDEF("fputc", f_fputc);
CDEF("number", f_number); CDEF("number", f_number);
@ -784,8 +817,6 @@ void f_init() {
CDEF("noop", f_noop); CDEF("noop", f_noop);
CDEF("open", f_open); CDEF("open", f_open);
CDEF("close", f_close); CDEF("close", f_close);
CDEF("loadfile", f__loadfile);
CDEF("loadstring", f_loadstring);
CDEF("quiet", f_quiet); CDEF("quiet", f_quiet);
CDEF("loud", f_loud); CDEF("loud", f_loud);
CDEF("task", f_task); CDEF("task", f_task);
@ -796,6 +827,16 @@ void f_init() {
CDEF("rstacksize", f_rstacksize); CDEF("rstacksize", f_rstacksize);
CDEF("task-user-size", f_taskusersize); CDEF("task-user-size", f_taskusersize);
PUSHS("boot.jor");
f_open();
PUSHS("key-file");
f_lookup();
DROP(1);
f_swapinput();
f_interpreter();
f_swapinput();
DROP(2);
f_loadfile("defs.jor"); f_loadfile("defs.jor");
} }
@ -805,17 +846,11 @@ void f_quit() {
} }
void f_repl() { void f_repl() {
char inputbuf[256]; char input[256];
CDEF("quit", f_quit);
CDEF("quit", f_quit);
f_runstring("stdout");
while (!DIE) { while (!DIE) {
int len; f_runstring(gets(input));
gets(inputbuf);
len = strlen(inputbuf);
inputbuf[len] = '\n';
inputbuf[len + 1] = 0;
PUSHS(inputbuf);
f_runstring("REPL send");
f_taskloop();
} }
} }

View file

@ -6,6 +6,7 @@
void f_init(); void f_init();
void f_cdef();
#define CDEF(name, def) PUSHP(def); PUSHS(name); f_cdef() #define CDEF(name, def) PUSHP(def); PUSHS(name); f_cdef()
void f_immediate(); void f_immediate();

13
temp.jor Executable file
View file

@ -0,0 +1,13 @@
: interpretword F_IMMEDIATE & state not or if execute else , then ;
: compileword lookup dup
if interpretword
else drop dup number
if swap drop interpretnumber
else drop interpretunknown
then
then ;
: interpreter
begin word dup b@ while compileword repeat
s" ok\n" type drop ;
: loadstring
: loadfile