\ ** ficl/softwords/softcore.fr \ ** FICL soft extensions \ ** John Sadler (john_sadler@alum.mit.edu) \ ** September, 1998 \ ** ficl extras \ EMPTY cleans the parameter stack : empty ( xn..x1 -- ) depth 0 ?do drop loop ; \ CELL- undoes CELL+ : cell- ( addr -- addr ) [ 1 cells ] literal - ; : -rot ( a b c -- c a b ) 2 -roll ; \ ** CORE : abs ( x -- x ) dup 0< if negate endif ; decimal 32 constant bl : space ( -- ) bl emit ; : spaces ( n -- ) 0 ?do space loop ; : abort" state @ if postpone if postpone ." postpone cr -2 postpone literal postpone throw postpone endif else [char] " parse rot if type cr -2 throw else 2drop endif endif ; immediate \ ** CORE EXT .( loading CORE EXT words ) cr 0 constant false false invert constant true : <> = 0= ; : 0<> 0= 0= ; : compile, , ; : convert char+ 65535 >number drop ; \ cribbed from DPANS A.6.2.0970 : erase ( addr u -- ) 0 fill ; variable span : expect ( c-addr u1 -- ) accept span ! ; \ see marker.fr for MARKER implementation : nip ( y x -- x ) swap drop ; : tuck ( y x -- x y x) swap over ; : within ( test low high -- flag ) over - >r - r> u< ; : dnegate ( d -- -d ) invert swap negate tuck 0= - ; : dabs ( d -- ud ) dup 0< if dnegate endif ; : .r ( n +n -- ) swap dup abs 0 <# #s rot sign #> rot over - dup 0< if drop else spaces then type space ; : u.r ( n +n -- ) swap 0 <# #s #> rot over - dup 0< if drop else spaces then type space ; : d. ( d -- ) swap over dabs <# #s rot sign #> type space ; : d.r ( d +n -- ) -rot swap over dabs <# #s rot sign #> rot over - dup 0< if drop else spaces then type space ; : du. ( d -- ) <# #s #> type space ; : du.r ( d +n -- ) -rot <# #s #> rot over - dup 0< if drop else spaces then type space ; : d>s ( d -- n ) drop ; : d0= ( d -- flag ) or 0= ; : d= ( d1 d2 -- flag ) rot = -rot = and ; : d0< ( d -- f ) nip 0< ; : d< ( d1 d2 -- flag ) 2 pick over = if rot 2drop < else swap drop < swap drop then ; : du< d< ; : dmax ( d1 d2 -- d3 ) 2over 2over d< if 2swap then 2drop ; : dmin ( d1 d2 -- d3 ) 2over 2over d< if 2drop else 2swap 2drop then ; : d+ ( d1 d2 -- d3 ) rot + >r tuck + tuck swap u< r> swap - ; : d- ( d1 d2 -- d3 ) dnegate d+ ; : d2* ( d1 -- d2 ) 2dup d+ ; : d2/ ( d1 -- d2 ) dup 1 and >r 2/ swap 2/ [ 1 8 cells 1- lshift 1- ] literal and r> if [ 1 8 cells 1- lshift ] literal + then swap ; : m+ ( d1 +n -- d2 ) s>d d+ ; \ ** TOOLS word set... : ? ( addr -- ) @ . ; Variable /dump : i' ( R:w R:w2 -- R:w R:w2 w ) r> r> r> dup >r swap >r swap >r ; : .4 ( addr -- addr' ) 4 0 DO -1 /dump +! /dump @ 0< IF 3 spaces ELSE dup c@ 0 <# # # #> type space THEN char+ LOOP ; : .chars ( addr -- ) /dump @ over + swap ?DO I c@ dup 127 bl within IF drop [char] . THEN emit LOOP ; : .line ( addr -- ) dup .4 space .4 ." - " .4 space .4 drop 16 /dump +! space .chars ; : dump ( addr u -- ) \ tools dump cr base @ >r hex \ save base on return stack 0 ?DO I' I - 16 min /dump ! dup 8 u.r ." : " dup .line cr 16 + 16 +LOOP drop r> base ! ; \ ** SEARCH+EXT words and ficl helpers .( loading SEARCH & SEARCH-EXT words ) cr \ BRAND-WORDLIST is a helper for ficl-named-wordlist. Usage idiom: \ wordlist dup create , brand-wordlist \ gets the name of the word made by create and applies it to the wordlist... : brand-wordlist ( wid -- ) last-word >name drop wid-set-name ; : ficl-named-wordlist \ ( hash-size name -- ) run: ( -- wid ) ficl-wordlist dup create , brand-wordlist does> @ ; : wordlist ( -- ) 1 ficl-wordlist ; \ FICL-SET-CURRENT sets the compile wordlist and pushes the previous value : ficl-set-current ( wid -- old-wid ) get-current swap set-current ; \ DO_VOCABULARY handles the DOES> part of a VOCABULARY \ When executed, new voc replaces top of search stack : do-vocabulary ( -- ) does> @ search> drop >search ; : ficl-vocabulary ( nBuckets name -- ) ficl-named-wordlist do-vocabulary ; : vocabulary ( name -- ) 1 ficl-vocabulary ; \ PREVIOUS drops the search order stack : previous ( -- ) search> drop ; \ HIDDEN vocabulary is a place to keep helper words from cluttering the namespace \ USAGE: \ hide \ \ set-current \