dictionary words, limited "target" compiler
This commit is contained in:
parent
8d5fbe0143
commit
74171670b2
5
boot.jor
5
boot.jor
|
@ -7,8 +7,7 @@
|
||||||
13 const '\r'
|
13 const '\r'
|
||||||
key const sp
|
key const sp
|
||||||
|
|
||||||
128 const F_IMMEDIATE
|
0x100 const F_IMMEDIATE
|
||||||
0x100 const F_USERWORD
|
|
||||||
|
|
||||||
: cr '\n' emit ;
|
: cr '\n' emit ;
|
||||||
: bl sp emit ;
|
: bl sp emit ;
|
||||||
|
@ -60,7 +59,7 @@ key const sp
|
||||||
( image loading )
|
( image loading )
|
||||||
: noop ;
|
: noop ;
|
||||||
|
|
||||||
: defer word new-word $DODEFERRED , ' noop , ;
|
: defer new-word $DODEFERRED , ' noop , ;
|
||||||
: redefine ( cp cpdeferred ) cell + ! ;
|
: redefine ( cp cpdeferred ) cell + ! ;
|
||||||
: definition ( cpdeferred ) cell + @ ;
|
: definition ( cpdeferred ) cell + @ ;
|
||||||
|
|
||||||
|
|
4
defs.jrt
4
defs.jrt
|
@ -27,8 +27,8 @@
|
||||||
|
|
||||||
: :noname here $DOCOLON , ] ;
|
: :noname here $DOCOLON , ] ;
|
||||||
|
|
||||||
: array word new-word $DOVAR , ;
|
: array new-word $DOVAR , ;
|
||||||
: create word new-word $DOCREATE , 0 , ;
|
: create new-word $DOCREATE , 0 , ;
|
||||||
|
|
||||||
: finishcreate ( ipfirst -- )
|
: finishcreate ( ipfirst -- )
|
||||||
( set cell after codepointer to first instruction of does> )
|
( set cell after codepointer to first instruction of does> )
|
||||||
|
|
14
lookup.jrt
Executable file
14
lookup.jrt
Executable file
|
@ -0,0 +1,14 @@
|
||||||
|
:t entry= ( name len entry -- f )
|
||||||
|
dup wordname swap wordlen <rot = BZ_ [ ( p1 - fail ) patchpt ]
|
||||||
|
[ ( l1 ) target @ ] over b@ dup BZ_ [ ( p2 - success ) patchpt ]
|
||||||
|
over b@ = BZ_ [ ( p3 - fail ) patchpt ]
|
||||||
|
2inc GOTO_ [ ( l1 ) <rot w>t ]
|
||||||
|
( fail ) [ patch!t swap patch!t ] drop drop 0 return
|
||||||
|
( success ) [ patch!t ] drop drop 1 ;
|
||||||
|
|
||||||
|
:t lookup ( name -- cp meta | name 0 )
|
||||||
|
dup strlen over dictbucket
|
||||||
|
[ target @ ] @ dup . dup BZ_ [ patchpt ]
|
||||||
|
3dup entry= BZ_ [ swap w>t ]
|
||||||
|
( entry found ) >rot drop drop dup codepointer swap wordflags @ return
|
||||||
|
( end of list ) [ patch!t ] drop drop 0 ;
|
|
@ -345,7 +345,7 @@ void f_bcomma() {
|
||||||
DROP(1);
|
DROP(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void f_create() { // name --
|
void f_create() { // word --
|
||||||
int namelen;
|
int namelen;
|
||||||
HERE->p = LATEST;
|
HERE->p = LATEST;
|
||||||
LATEST = HERE;
|
LATEST = HERE;
|
||||||
|
@ -357,6 +357,10 @@ void f_create() { // name --
|
||||||
DROP(1);
|
DROP(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void f_newword() {
|
||||||
|
f_word();
|
||||||
|
f_create();
|
||||||
|
}
|
||||||
void f_cdef() { // func name --
|
void f_cdef() { // func name --
|
||||||
f_create();
|
f_create();
|
||||||
f_comma();
|
f_comma();
|
||||||
|
@ -765,7 +769,7 @@ void f_init() {
|
||||||
CDEF("word", f_word);
|
CDEF("word", f_word);
|
||||||
CDEF("immediate", f_immediate);
|
CDEF("immediate", f_immediate);
|
||||||
CDEF("execute", f_execute);
|
CDEF("execute", f_execute);
|
||||||
CDEF("new-word", f_create);
|
CDEF("new-word", f_newword);
|
||||||
CDEF("here", f_here);
|
CDEF("here", f_here);
|
||||||
CDEF("here!", f_here_set);
|
CDEF("here!", f_here_set);
|
||||||
CDEF("there", f_there);
|
CDEF("there", f_there);
|
||||||
|
|
BIN
minijort.exe
BIN
minijort.exe
Binary file not shown.
|
@ -34,8 +34,8 @@ extern cell *rstack;
|
||||||
extern cell *stack;
|
extern cell *stack;
|
||||||
extern FILE *IN_FILE;
|
extern FILE *IN_FILE;
|
||||||
extern FILE *OUT_FILE;
|
extern FILE *OUT_FILE;
|
||||||
#define F_NAMELEN_MASK 0x7f
|
#define F_NAMELEN_MASK 0xff
|
||||||
#define F_IMMEDIATE 0x80
|
#define F_IMMEDIATE 0x100
|
||||||
|
|
||||||
#define CELL_OFFSET(cp, b) ((cell*)(((char *)(cp)) + b))
|
#define CELL_OFFSET(cp, b) ((cell*)(((char *)(cp)) + b))
|
||||||
#define TOP() (*(stack - 1))
|
#define TOP() (*(stack - 1))
|
||||||
|
|
BIN
minijort.prj
BIN
minijort.prj
Binary file not shown.
BIN
tinyjort.com
BIN
tinyjort.com
Binary file not shown.
316
tinyjort.jrt
316
tinyjort.jrt
|
@ -28,8 +28,9 @@ JMP 9 @>
|
||||||
bits.
|
bits.
|
||||||
Entry:
|
Entry:
|
||||||
LINK - pointer to next word in the dictionary
|
LINK - pointer to next word in the dictionary
|
||||||
FLAGS - byte
|
META - word, made up of:
|
||||||
LENGTH - byte
|
LENGTH - byte
|
||||||
|
FLAGS - byte
|
||||||
NAME - bytes ending in \0
|
NAME - bytes ending in \0
|
||||||
CODE POINTER - pointer to machine code routine )
|
CODE POINTER - pointer to machine code routine )
|
||||||
|
|
||||||
|
@ -38,26 +39,30 @@ L: DICTIONARY
|
||||||
0 w>t 0 w>t 0 w>t 0 w>t 0 w>t 0 w>t 0 w>t 0 w>t
|
0 w>t 0 w>t 0 w>t 0 w>t 0 w>t 0 w>t 0 w>t 0 w>t
|
||||||
L: LATEST 0 w>t
|
L: LATEST 0 w>t
|
||||||
|
|
||||||
|
0x0f const BUCKETMASK
|
||||||
|
|
||||||
: savelabel ( word -- )
|
: savelabel ( word -- )
|
||||||
dup type s" : " type
|
dup type s" : " type
|
||||||
here swap begin dup b@ dup while b, 1 + repeat b, drop lastlabel ! ;
|
here swap begin dup b@ dup while b, 1 + repeat b, drop lastlabel ! ;
|
||||||
: DICTLIST ( word -- tptr ) b@ 0x0f & cells [ L@ DICTIONARY lit ] + ;
|
: DICTLIST ( word -- tptr ) b@ BUCKETMASK & cells [ L@ DICTIONARY lit ] + ;
|
||||||
: strlen ( word -- len ) 0 swap begin dup b@ while swap 1 + swap 1 + repeat drop ;
|
: strlen ( word -- len ) 0 swap begin dup b@ while swap 1 + swap 1 + repeat drop ;
|
||||||
: str>t ( word -- ) begin dup b@ dup while >t 1 + repeat >t drop ;
|
: str>t ( word -- ) begin dup b@ dup while >t 1 + repeat >t drop ;
|
||||||
: link>t ( tptr-head -- ) dup @t swap target @ swap !t w>t ;
|
: patch!t ( tptr -- ) target @ swap !t ;
|
||||||
: DEF word dup savelabel dup DICTLIST link>t 0 >t dup strlen >t str>t
|
: link>t ( tptr-head -- ) dup @t swap patch!t w>t ;
|
||||||
|
: DEF word dup savelabel dup DICTLIST link>t dup strlen w>t str>t
|
||||||
target @ cell + .hex cr ;
|
target @ cell + .hex cr ;
|
||||||
|
|
||||||
: WORD= ( word len tptr -- f )
|
: WORD= ( word len tptr -- f )
|
||||||
3 + dup b@t <rot != if 2drop 0 return then 1 + ( word tword )
|
cell + dup b@t <rot != if 2drop 0 return then cell + ( word tword )
|
||||||
begin over b@ over b@t = while
|
begin over b@ over b@t = while
|
||||||
over b@ not if 2drop 1 return then ( 0 byte, matched )
|
over b@ not if 2drop 1 return then ( 0 byte, matched )
|
||||||
1 + swap 1 + swap
|
1 + swap 1 + swap
|
||||||
repeat 2drop 0 ;
|
repeat 2drop 0 ;
|
||||||
|
: tlookup ( word -- tcp )
|
||||||
: t' word dup strlen over DICTLIST ( word len tptr-next-entry )
|
dup strlen over DICTLIST ( word len tptr-next-entry )
|
||||||
begin dup while 3dup WORD= if 5 + + swap drop return then @t repeat
|
begin dup while 3dup WORD= if 5 + + swap drop return then @t repeat
|
||||||
drop drop drop 0 ;
|
drop drop drop 0 ;
|
||||||
|
: t' word tlookup ;
|
||||||
: t& t' cell + ;
|
: t& t' cell + ;
|
||||||
|
|
||||||
: :ASM DEF target @ 2 + w>t ;
|
: :ASM DEF target @ 2 + w>t ;
|
||||||
|
@ -71,6 +76,7 @@ L: $$CONST
|
||||||
|
|
||||||
: CONST DEF [ L@ $$CONST lit ] w>t w>t ;
|
: CONST DEF [ L@ $$CONST lit ] w>t w>t ;
|
||||||
|
|
||||||
|
L@ $$CONST CONST $DOCONST
|
||||||
L@ DICTIONARY CONST dictionary
|
L@ DICTIONARY CONST dictionary
|
||||||
L@ LATEST CONST &latest
|
L@ LATEST CONST &latest
|
||||||
|
|
||||||
|
@ -99,22 +105,35 @@ L@ $$VAR CONST $DOVAR
|
||||||
MOV SI @[ BP]
|
MOV SI @[ BP]
|
||||||
NEXT
|
NEXT
|
||||||
|
|
||||||
( some helpers for making manually defining colon words slightly less ugly )
|
|
||||||
: '>t t' w>t ;
|
|
||||||
: :t DEF [ t& $DOCOLON lit ] w>t ;
|
|
||||||
|
|
||||||
:CP $DODEFERRED
|
:CP $DODEFERRED
|
||||||
INC BX INC BX
|
INC BX INC BX
|
||||||
MOV BX @[ BX]
|
MOV BX @[ BX]
|
||||||
JMP @[ BX]
|
JMP @[ BX]
|
||||||
|
|
||||||
: DEFERRED DEF [ t& $DODEFERRED lit ] w>t '>t ;
|
|
||||||
|
|
||||||
:ASM LIT_
|
:ASM LIT_
|
||||||
LODSW
|
LODSW
|
||||||
PUSH AX
|
PUSH AX
|
||||||
NEXT
|
NEXT
|
||||||
|
|
||||||
|
( some helpers for making manually defining colon words less ugly )
|
||||||
|
: '>t t' w>t ;
|
||||||
|
|
||||||
|
: stch? ( str -- f ) ' @ , key lit ' = , ; immediate
|
||||||
|
( DOES NOT SUPPORT ARBITRARY IMMEDIATE WORDS.
|
||||||
|
Supports [], comments, ; and numeric literals ONLY.
|
||||||
|
You must use [ for anything fancy. )
|
||||||
|
: :t DEF [ t& $DOCOLON lit ] w>t ]
|
||||||
|
begin word dup stch? ; not while
|
||||||
|
state if dup stch? [ if drop [ ' [ , ] else
|
||||||
|
dup stch? ( if drop [ ' ( , ] else
|
||||||
|
dup tlookup dup if w>t drop else drop
|
||||||
|
number if [ t' LIT_ lit ] w>t w>t else
|
||||||
|
type s" ?" type cr then then then then else
|
||||||
|
compileword then
|
||||||
|
repeat drop [ t' return lit ] w>t [ ' [ , ] ;
|
||||||
|
|
||||||
|
: DEFERRED DEF [ t& $DODEFERRED lit ] w>t '>t ;
|
||||||
|
|
||||||
:ASM INLINEDATA_
|
:ASM INLINEDATA_
|
||||||
LODSW
|
LODSW
|
||||||
PUSH SI
|
PUSH SI
|
||||||
|
@ -143,6 +162,27 @@ DEF GOTO_ L@ GOTO_IMPL w>t
|
||||||
PUSH AX
|
PUSH AX
|
||||||
NEXT
|
NEXT
|
||||||
|
|
||||||
|
:ASM 2dup
|
||||||
|
POP AX
|
||||||
|
POP BX
|
||||||
|
PUSH BX
|
||||||
|
PUSH AX
|
||||||
|
PUSH BX
|
||||||
|
PUSH AX
|
||||||
|
NEXT
|
||||||
|
|
||||||
|
:ASM 3dup
|
||||||
|
POP AX
|
||||||
|
POP BX
|
||||||
|
POP CX
|
||||||
|
PUSH CX
|
||||||
|
PUSH BX
|
||||||
|
PUSH AX
|
||||||
|
PUSH CX
|
||||||
|
PUSH BX
|
||||||
|
PUSH AX
|
||||||
|
NEXT
|
||||||
|
|
||||||
:ASM swap
|
:ASM swap
|
||||||
POP AX
|
POP AX
|
||||||
POP BX
|
POP BX
|
||||||
|
@ -151,11 +191,14 @@ DEF GOTO_ L@ GOTO_IMPL w>t
|
||||||
NEXT
|
NEXT
|
||||||
|
|
||||||
:ASM over
|
:ASM over
|
||||||
POP AX
|
( this costs 1 extra byte but should save 20 clock cycles )
|
||||||
POP BX
|
MOV BX SP
|
||||||
POP BX
|
PUSH @[ 4 @+ SS: BX]
|
||||||
POP AX
|
( POP AX
|
||||||
POP BX
|
POP BX
|
||||||
|
PUSH BX
|
||||||
|
PUSH AX
|
||||||
|
PUSH BX )
|
||||||
NEXT
|
NEXT
|
||||||
|
|
||||||
:ASM <rot
|
:ASM <rot
|
||||||
|
@ -167,9 +210,18 @@ DEF GOTO_ L@ GOTO_IMPL w>t
|
||||||
PUSH CX
|
PUSH CX
|
||||||
NEXT
|
NEXT
|
||||||
|
|
||||||
|
:ASM >rot
|
||||||
|
POP AX
|
||||||
|
POP BX
|
||||||
|
POP CX
|
||||||
|
PUSH AX
|
||||||
|
PUSH CX
|
||||||
|
PUSH BX
|
||||||
|
NEXT
|
||||||
|
|
||||||
:ASM terminate
|
:ASM terminate
|
||||||
MOV AH 0x4c #
|
MOV AH 0x4c #
|
||||||
MOV AL 0 # ( todo: pop )
|
MOV AL 0 # ( todo: pop? )
|
||||||
INT 0x21 #
|
INT 0x21 #
|
||||||
|
|
||||||
:ASM execute
|
:ASM execute
|
||||||
|
@ -248,9 +300,9 @@ L: RETFALSE
|
||||||
JZ RETFALSE
|
JZ RETFALSE
|
||||||
JMP RETTRUE
|
JMP RETTRUE
|
||||||
|
|
||||||
:t != '>t = '>t not '>t return
|
:t != = not ;
|
||||||
:t <= '>t > '>t not '>t return
|
:t <= > not ;
|
||||||
:t >= '>t < '>t not '>t return
|
:t >= < not ;
|
||||||
|
|
||||||
dbg" bitwise"
|
dbg" bitwise"
|
||||||
:ASM &
|
:ASM &
|
||||||
|
@ -281,7 +333,7 @@ dbg" bitwise"
|
||||||
PUSH AX
|
PUSH AX
|
||||||
NEXT
|
NEXT
|
||||||
|
|
||||||
:ASM >>
|
:ASM >> ( val count )
|
||||||
POP CX
|
POP CX
|
||||||
POP AX
|
POP AX
|
||||||
SHR AX CL
|
SHR AX CL
|
||||||
|
@ -291,8 +343,7 @@ dbg" bitwise"
|
||||||
dbg" mem"
|
dbg" mem"
|
||||||
:ASM @
|
:ASM @
|
||||||
POP BX
|
POP BX
|
||||||
MOV AX @[ BX]
|
PUSH @[ BX]
|
||||||
PUSH AX
|
|
||||||
NEXT
|
NEXT
|
||||||
|
|
||||||
:ASM b@
|
:ASM b@
|
||||||
|
@ -311,8 +362,7 @@ dbg" mem"
|
||||||
|
|
||||||
:ASM @far
|
:ASM @far
|
||||||
POP ES POP BX
|
POP ES POP BX
|
||||||
MOV AX @[ ES: BX]
|
PUSH @[ ES: BX]
|
||||||
PUSH AX
|
|
||||||
NEXT
|
NEXT
|
||||||
|
|
||||||
:ASM b@far
|
:ASM b@far
|
||||||
|
@ -323,8 +373,8 @@ dbg" mem"
|
||||||
NEXT
|
NEXT
|
||||||
|
|
||||||
:ASM !
|
:ASM !
|
||||||
POP BX POP AX
|
POP BX
|
||||||
MOV @[ BX] AX
|
POP @[ BX]
|
||||||
NEXT
|
NEXT
|
||||||
|
|
||||||
:ASM b!
|
:ASM b!
|
||||||
|
@ -333,8 +383,8 @@ dbg" mem"
|
||||||
NEXT
|
NEXT
|
||||||
|
|
||||||
:ASM !far
|
:ASM !far
|
||||||
POP ES POP BX POP AX
|
POP ES POP BX
|
||||||
MOV @[ ES: BX] AX
|
POP @[ ES: BX]
|
||||||
NEXT
|
NEXT
|
||||||
|
|
||||||
:ASM b!far
|
:ASM b!far
|
||||||
|
@ -344,20 +394,17 @@ dbg" mem"
|
||||||
|
|
||||||
dbg" return stack"
|
dbg" return stack"
|
||||||
:ASM >r
|
:ASM >r
|
||||||
POP AX
|
POP @[ BP]
|
||||||
MOV @[ BP] AX
|
|
||||||
INC BP INC BP
|
INC BP INC BP
|
||||||
NEXT
|
NEXT
|
||||||
|
|
||||||
:ASM <r
|
:ASM <r
|
||||||
DEC BP DEC BP
|
DEC BP DEC BP
|
||||||
MOV AX @[ BP]
|
PUSH @[ BP]
|
||||||
PUSH AX
|
|
||||||
NEXT
|
NEXT
|
||||||
|
|
||||||
:ASM r@
|
:ASM r@
|
||||||
MOV AX @[ -2 @+ BP]
|
PUSH @[ -2 @+ BP]
|
||||||
PUSH AX
|
|
||||||
NEXT
|
NEXT
|
||||||
|
|
||||||
:ASM rdrop
|
:ASM rdrop
|
||||||
|
@ -390,21 +437,21 @@ dbg" patched"
|
||||||
)
|
)
|
||||||
dbg" allocation"
|
dbg" allocation"
|
||||||
0 VAR, &here
|
0 VAR, &here
|
||||||
:t here '>t &here '>t @ '>t return
|
:t here &here @ ;
|
||||||
:t here! '>t &here '>t ! '>t return
|
:t here! &here ! ;
|
||||||
0xffff CONST there
|
0xffff CONST there
|
||||||
|
|
||||||
:t latest '>t &latest '>t @ '>t return
|
:t latest &latest @ ;
|
||||||
:t latest! '>t &latest '>t ! '>t return
|
:t latest! &latest ! ;
|
||||||
|
|
||||||
0 VAR, lastseg
|
0 VAR, lastseg
|
||||||
:t segalloc '>t lastseg '>t @ '>t LIT_ 4096 w>t '>t +
|
:t segalloc lastseg @ 4096 + dup lastseg ! ;
|
||||||
'>t dup '>t lastseg '>t ! '>t return
|
|
||||||
|
|
||||||
2 CONST cell
|
2 CONST cell
|
||||||
:t allot '>t here '>t + '>t here! '>t return
|
:t cells cell * ;
|
||||||
:t , '>t here '>t ! '>t cell '>t allot '>t return
|
:t allot here + here! ;
|
||||||
:t b, '>t here '>t b! '>t LIT_ 1 w>t '>t allot '>t return
|
:t , here ! cell allot ;
|
||||||
|
:t b, here b! 1 allot ;
|
||||||
|
|
||||||
dbg" i/o"
|
dbg" i/o"
|
||||||
:ASM overwrite
|
:ASM overwrite
|
||||||
|
@ -450,12 +497,11 @@ dbg" i/o"
|
||||||
|
|
||||||
-1 CONST EOF
|
-1 CONST EOF
|
||||||
0 VAR, fbuffer
|
0 VAR, fbuffer
|
||||||
:t fgetc '>t LIT_ 1 w>t '>t fbuffer '>t <rot '>t fread
|
: skip>t 1 + cells target @ + w>t ;
|
||||||
'>t fbuffer '>t ub@
|
:t fgetc ( fp -- c )
|
||||||
'>t fcount '>t @ '>t not '>t BZ_ target @ 3 cells + w>t
|
1 fbuffer <rot fread fbuffer ub@
|
||||||
'>t drop '>t EOF '>t return
|
fcount @ not BZ_ [ 2 skip>t ] drop EOF ;
|
||||||
:t fputc '>t swap '>t fbuffer '>t b!
|
:t fputc ( c fp -- ) swap fbuffer b! 1 fbuffer <rot fwrite ;
|
||||||
'>t LIT_ 1 w>t '>t fbuffer '>t <rot '>t fwrite '>t return
|
|
||||||
|
|
||||||
:ASM console-emit
|
:ASM console-emit
|
||||||
MOV AH 2 #
|
MOV AH 2 #
|
||||||
|
@ -472,12 +518,10 @@ DEFERRED emit console-emit
|
||||||
NEXT
|
NEXT
|
||||||
|
|
||||||
0 VAR, infile ( 0 is a predefined file handle meaning stdin )
|
0 VAR, infile ( 0 is a predefined file handle meaning stdin )
|
||||||
:t in-key '>t infile '>t @ '>t dup '>t BZ_ target @ 4 cells + w>t
|
:t in-key infile @ dup BZ_ [ 3 skip>t ] drop console-key return fgetc ;
|
||||||
'>t drop '>t console-key '>t return
|
|
||||||
'>t fgetc '>t return
|
|
||||||
DEFERRED key in-key
|
DEFERRED key in-key
|
||||||
|
|
||||||
dbg" number"
|
dbg" parsing"
|
||||||
L: BASE 10 w>t L: ISNEG? 0 >t
|
L: BASE 10 w>t L: ISNEG? 0 >t
|
||||||
:ASM number ( str -- num 1 | str 0 )
|
:ASM number ( str -- num 1 | str 0 )
|
||||||
( AX - current number
|
( AX - current number
|
||||||
|
@ -595,17 +639,163 @@ L: write-next-digit
|
||||||
PUSH t& &here @+
|
PUSH t& &here @+
|
||||||
NEXT
|
NEXT
|
||||||
|
|
||||||
:t type target @ '>t dup '>t b@ '>t dup '>t BZ_ target @ 7 cells + w>t
|
:t type [ target @ ]
|
||||||
'>t emit '>t LIT_ 1 w>t '>t + '>t GOTO_ w>t '>t drop '>t drop '>t return
|
dup b@ dup BZ_ [ 6 skip>t ]
|
||||||
:t . '>t num>str '>t type '>t LIT_ key w>t '>t emit '>t return
|
emit 1 + GOTO_ [ w>t ]
|
||||||
|
drop drop ;
|
||||||
|
:t . num>str type LIT_ [ key w>t ] emit ;
|
||||||
|
|
||||||
dbg" test"
|
:ASM whitespace?
|
||||||
( test program )
|
POP AX
|
||||||
ARRAY hex65 key - >t key 6 >t key 5 >t 0 >t
|
CMP AX key #
|
||||||
L: test-word '>t hex65 '>t number '>t . '>t . '>t terminate
|
JZ 0 @>
|
||||||
|
CMP AX 13 # ( newline )
|
||||||
|
JZ 1 @>
|
||||||
|
CMP AX 10 # ( linefeed )
|
||||||
|
JZ 2 @>
|
||||||
|
CMP AX 9 # ( tab )
|
||||||
|
JNZ 3 @>
|
||||||
|
0 <: 1 <: 2 <:
|
||||||
|
PUSH TRUE
|
||||||
|
NEXT
|
||||||
|
3 <:
|
||||||
|
PUSH FALSE
|
||||||
|
NEXT
|
||||||
|
|
||||||
|
:ASM eoi? ( end of input )
|
||||||
|
POP AX
|
||||||
|
CMP AX 0 # ( null )
|
||||||
|
JZ 0 @>
|
||||||
|
CMP AX -1 # ( EOF )
|
||||||
|
JNZ 1 @>
|
||||||
|
0 <:
|
||||||
|
PUSH TRUE
|
||||||
|
NEXT
|
||||||
|
1 <:
|
||||||
|
PUSH FALSE
|
||||||
|
NEXT
|
||||||
|
|
||||||
|
:t word,
|
||||||
|
( consume leading whitespace )
|
||||||
|
0 [ target @ ] drop key dup whitespace? not BZ_ [ w>t ]
|
||||||
|
( consume non-whitespace / eoi characters )
|
||||||
|
[ target @ ] dup whitespace? over eoi? or
|
||||||
|
( if whitespace or eoi, end ) BZ_ [ 5 skip>t ] drop 0 b, return
|
||||||
|
( otherwise, write byte and continue ) b, key GOTO_ [ w>t ] ;
|
||||||
|
|
||||||
|
:t word here word, dup here! ;
|
||||||
|
|
||||||
|
dbg" compiler"
|
||||||
|
:t wordflags cell + ;
|
||||||
|
:t wordname 2 cells + ;
|
||||||
|
:t wordlen wordflags ub@ ;
|
||||||
|
:t codepointer dup wordname swap wordlen + ( trailing null ) 1 + ;
|
||||||
|
:t dictbucket ( word -- p ) ub@ LIT_ [ BUCKETMASK w>t ] & cells dictionary + ;
|
||||||
|
:t new-word
|
||||||
|
( set latest ) here latest!
|
||||||
|
( create entry ) 0 dup , ,
|
||||||
|
( save word + calc length ) here word, here swap -
|
||||||
|
( save length ) latest wordflags !
|
||||||
|
( find bucket ) latest wordname dictbucket
|
||||||
|
( link to prev ) dup @ latest !
|
||||||
|
( link bucket to new ) latest swap ! ;
|
||||||
|
:t 2inc ( x y -- x+1 y+1 ) 1 + swap 1 + swap ;
|
||||||
|
:t strlen ( name -- len )
|
||||||
|
0 swap [ target @ ] dup b@ BZ_ [ 3 skip>t ]
|
||||||
|
2inc GOTO_ [ w>t ] drop ;
|
||||||
|
|
||||||
|
: patchpt target @ 0 w>t ;
|
||||||
|
|
||||||
|
:ASM dict-lookup ( name dict -- cp meta | name 0 )
|
||||||
|
POP BX ( dictionary )
|
||||||
|
POP DI ( name )
|
||||||
|
( strlen - in DI: str, out CX: len, clobbers AX )
|
||||||
|
XOR CX CX DEC CX ( start CX at -1 so we search until we find the 0 )
|
||||||
|
XOR AX AX ( search for 0 )
|
||||||
|
REPNZ SCASB
|
||||||
|
NEG CX DEC CX
|
||||||
|
SUB DI CX ( restore DI )
|
||||||
|
DEC CX ( ignore trailing zero )
|
||||||
|
|
||||||
|
( keeping CX + DI, find the next entry pointer and store in BX )
|
||||||
|
MOV AL @[ DI]
|
||||||
|
AND AL BUCKETMASK #
|
||||||
|
SHL AX 1 #
|
||||||
|
ADD BX AX
|
||||||
|
|
||||||
|
( save SI )
|
||||||
|
MOV DX SI
|
||||||
|
|
||||||
|
L: check-next-entry
|
||||||
|
MOV BX @[ BX]
|
||||||
|
CMP BX 0 #
|
||||||
|
JZ 0 @>
|
||||||
|
CMP CL @[ 2 @+ BX]
|
||||||
|
JNZ check-next-entry
|
||||||
|
|
||||||
|
( we have a matching length; compare the string )
|
||||||
|
PUSH CX
|
||||||
|
PUSH DI
|
||||||
|
MOV SI BX
|
||||||
|
ADD SI 4 #
|
||||||
|
REPZ CMPSB
|
||||||
|
POP DI
|
||||||
|
POP CX
|
||||||
|
JNZ check-next-entry
|
||||||
|
|
||||||
|
( we have a matching word! return success )
|
||||||
|
MOV AX @[ 2 @+ BX] ( read flag word )
|
||||||
|
ADD BX CX ( strlen )
|
||||||
|
ADD BX 5 # ( header + null byte )
|
||||||
|
PUSH BX
|
||||||
|
PUSH AX
|
||||||
|
MOV SI DX ( restore SI )
|
||||||
|
NEXT
|
||||||
|
|
||||||
|
0 <: ( failure; we've hit a null pointer in our linked list )
|
||||||
|
PUSH DI ( push word pointer back onto the stack )
|
||||||
|
PUSH FALSE
|
||||||
|
MOV SI DX ( restore SI )
|
||||||
|
NEXT
|
||||||
|
|
||||||
|
:t lookup dictionary dict-lookup ;
|
||||||
|
|
||||||
|
0x100 CONST F_IMMEDIATE
|
||||||
|
:t immediate latest wordflags dup @ F_IMMEDIATE | swap ! ;
|
||||||
|
: IMMEDIATE [ L@ LATEST lit ] @t cell + dup @t 0x100 | swap !t ;
|
||||||
|
|
||||||
|
0 VAR, &state
|
||||||
|
:t state &state @ ;
|
||||||
|
:t ] 1 &state ! ;
|
||||||
|
:t [ 0 &state ! ; IMMEDIATE
|
||||||
|
:t : new-word $DOCOLON , ] ;
|
||||||
|
:t ; LIT_ return , [ '>t [ ] ; IMMEDIATE
|
||||||
|
:t const new-word $DOCONST , , ;
|
||||||
|
:t var new-word $DOVAR , 0 , ;
|
||||||
|
:t interpretword ( cp meta -- ) F_IMMEDIATE & state not or
|
||||||
|
BZ_ [ patchpt ] execute return [ patch!t ] , ;
|
||||||
|
:t interpretnumber ( n -- n? ) state BZ_ [ patchpt ] LIT_ , , [ patch!t ] ;
|
||||||
|
:t ?err ( word -- ) type LIT_ [ key ? w>t ] emit 13 emit ;
|
||||||
|
DEFERRED err ?err
|
||||||
|
:t compileword ( word -- )
|
||||||
|
lookup dup BZ_ [ patchpt ] interpretword return [ patch!t ]
|
||||||
|
drop number BZ_ [ patchpt ] interpretnumber return [ patch!t ]
|
||||||
|
err ;
|
||||||
|
:t interpreter
|
||||||
|
[ target @ ] word dup b@ BZ_ [ patchpt ] compileword GOTO_ [ swap w>t ]
|
||||||
|
[ patch!t ] drop ;
|
||||||
|
|
||||||
|
dbg" boot stub"
|
||||||
|
:ASM debug NEXT
|
||||||
|
: t" begin key dup [ key " lit ] != while >t repeat drop 0 >t ;
|
||||||
|
ARRAY input t" +"
|
||||||
|
t& input VAR, inptr
|
||||||
|
:t keyinput inptr @ b@ dup BZ_ [ patchpt ] inptr @ 1 + inptr ! [ patch!t ] ;
|
||||||
|
t' keyinput t& key !t
|
||||||
|
:t tinyjort 1 2 word lookup drop execute . terminate ;
|
||||||
|
|
||||||
9 <: ( actual entry point )
|
9 <: ( actual entry point )
|
||||||
LEA SI test-word
|
MOV SI t& tinyjort #
|
||||||
PUSH CS
|
PUSH CS
|
||||||
POP AX
|
POP AX
|
||||||
ADD AX 4096 #
|
ADD AX 4096 #
|
||||||
|
|
Loading…
Reference in a new issue