#lang planet zwizwa/staapl/pic18 \ -*- forth -*-
provide-all
staapl pic18/double-math
staapl pic18/double-pred
staapl pic18/double-dict
staapl pic18/execute
\ A direct threaded Forth using native code primitives. NEXT is
\ procedure return to an explicit interpreter loop.
: _IP!
fh ! fl ! : _exit
r> fh !
r> fl ! : _dolit
@f+ @f+ : _jump
@f+ fl !
@f+ fh ! : _0jump
or z? if drop _jump drop @f+ drop @f+ drop
: enter
fl @ >r
fh @ >r
TOSL fl @! \ TOS cannot be movff dst, but src is ok
TOSH fh @!
pop
: continue
begin @f+ @f+ execute/b again
: _bye
_exit \ remove DTC continuation
pop
\ Bootstrap compiler words.
macro
: compile address ,, : literal >m ' _dolit compile m> ,, : _forth
\ On-target compiler words.
macro
: >xt address lohi forth
: _compile _, : _literal ' _dolit >xt _, _,
\ Trampoline entry from native code. The 'interpret' word will run a
\ dtc primitive or primitive wrapped program.
: bye>r
enter
' _bye compile : interpret \ ( lo hi -- )
bye>r \ install continuation into dtc code "bye ;"
execute/b \ invoke the primitive (might be enter = wrapped program)
continue
\ Return stack
: _>r >r >r : _r> r> r> : _rdrop rdrop rdrop : _r rl @ rh @
\ Immediate words
: _0 0 dup : _0jump, ' _0jump >xt _, : _jump, ' _jump >xt _, : _hole, _here@ _0 _,
: _begin _here@ : _again _jump, _, : _until _0jump, _,
: _if _0jump, _hole, : _then _>r _here@ _r> _cbuf _! : _else _>r _jump, _r> _hole,
\ Dictionary meta data.
\ For now we compile the dictionary meta data inline with the code so
\ we can reuse compilation primitives. Later the dictionary could be
\ separated.
\ Compile a pstring to the dictionary.
: compile-name \ lo hi --
_dup _@ drop \ lo hi nb.bytes
>> 1+ \ nb.words
for _dup _@ _, _cell+ next
_drop
\ Create a new dictionary entry. Format: [ next XT CT name code ]
: word \ lo hi --
_here@ _>r \ Save location of new head pointer.
_head _@ _, \ Compile link to old head.
_r> _head _! \ Store new head pointer.
_here@ _>r _0 _, \ Save XT hole + Compile stub.
' _compile >xt _, \ Compile CT
compile-name \ Compile the name string.
_here@ _r> _cbuf _! \ Patch XT hole.
\ String comparison. Since one of them is in RAM and the other in
\ FLASH both pointers can be used to iterate over the strings.
: flash/ram-compare \ FH FL AH AL -- ?
a!! f!! a/f-compare @a @f+ = if @a+ n-a/f-compare : n-a/f-compare \ len --
1 - c? if drop -1 @a+ @f+ = if n-a/f-compare drop 0
\ untested
\ Lookup a pstring in the flash dictionary. Returns 0 if not found,
\ or a link to the dictionary record if found.
: find \ lo hi --
_>r
_last _@
: find-loop
_dup or 0 = if _drop _rdrop _0 _dup _r _@ flash/ram-compare if _rdrop _@ find-loop
: init-dtc
#x1000 lohi _here ! _0 _last !