( -*- forth -*- ) ( this is adapted from Bill Muench's x86 eForth.. original copyright notice: --- Copyright Bill Muench All rights reserved. Permission is granted for non-commercial use, provided this notice is included. Contact Bill Muench concerning commercial use. --- contains some adaptations to make it work on the purrr kernel. i converted everything to lower case. aestetics i guess.. ) ( ============================================================ ) : noop ( -- ) ( 0x7b ) ; ( system variables ) : _var ( -- a ) ( 0xb9 ) r> ; compile-only : _con ( -- n ) ( 0xba ) r> @ ; compile-only create '?key ( input device vector ) ' ?rx , create 'emit ( output device vector ) ' tx! , variable base ( numeric radix ) ( 6.1.0750 )( 0xa0 ) variable dpl ( numeric input decimal place ) variable hld ( numeric output string pointer ) variable >in ( input buffer offset ) ( 6.1.0560 ) create #in ( input buffer count ) 2 cells allot ( input buffer address ) variable csp ( save stack pointer ) create state ( interpret/compile flag ) ( 6.1.2250 )( 0xdc ) 2 cells allot ( interpret/compile vector ) create dp ( dictionary pointer ) 2 cells allot create sup ( -- tid ) =rp , ( return stack ) =sp , ( data stack ) =bl constant bl ( -- c ) ( 6.1.0770 )( 0xa9 ) ( common functions ) : hex ( -- ) ( 6.2.1660 ) 16 base ! ; : decimal ( -- ) ( 6.1.1170 ) 10 base ! ; : rot ( n1 n2 n3 -- n2 n3 n1 ) ( 6.1.2160 )( 0x4a ) >r swap r> swap ; : nip ( n1 n2 -- n2 ) ( 6.2.1930 )( 0x4d ) swap drop ; : 2drop ( n n -- ) ( 6.1.0370 )( 0x52 ) drop drop ; : 2dup ( n1 n2 -- n1 n2 n1 n2 ) ( 6.1.0380 )( 0x53 ) over over ; : ?dup ( n -- n n | 0 ) ( 6.1.0630 )( 0x50 ) dup if dup then ; : + ( n n -- n ) ( 6.1.0120 )( 0x1e ) um+ drop ; : d+ ( d d -- d ) ( 8.6.1.1040 )( 0xd8 ) >r swap >r um+ r> + r> + ; : invert ( n -- n ) ( 6.1.1720 )( 0x26 ) -1 xor ; : negate ( n -- n ) ( 6.1.1910 )( 0x2c ) invert 1 + ; : dnegate ( d -- d ) ( 8.6.1.1230 ) invert >r invert 1 um+ r> + ; : s>d ( n -- d ) ( 6.1.2170 ) dup 0< ; : abs ( n -- u ) ( 6.1.0690 )( 0x2d ) dup 0< if negate then ; : dabs ( d -- ud ) ( 8.6.1.1160 ) dup 0< if dnegate then ; : - ( n n -- n ) ( 6.1.0160 )( 0x1f ) negate + ; : pick ( n -- n ) ( 6.2.2030 )( 0x50 ) ?dup if swap >r 1 - recurse r> swap exit then dup ; ( comparison ) : 0= ( n -- f ) ( 6.1.0270 )( 0x34 ) if 0 exit then -1 ; : = ( n n -- f ) ( 6.1.0530 )( 0x3c ) xor 0= ; : u< ( u u -- f ) ( 6.1.2340 )( 0x40 ) 2dup xor 0< if nip 0< exit then - 0< ; : < ( n n -- f ) ( 6.1.0480 )( 0x3a ) 2dup xor 0< if drop 0< exit then - 0< ; : max ( n n -- n ) ( 6.1.1870 )( 0x2f ) 2dup < if swap then drop ; : min ( n n -- n ) ( 6.1.1880 )( 0x2e ) 2dup swap < if swap then drop ; : within ( u ul uh -- f ) ( 6.2.2440 )( 0x45 ) over - >r - r> u< ; ( multiply ) : lshift ( u n -- u ) ( 6.1.1805 )( 0x27 ) begin dup while >r dup + r> 1 - repeat drop ; : um* ( u u -- ud ) ( 6.1.2360 )( 0xd4 ) 0 swap [ #bits ] literal begin dup while >r dup um+ >r >r dup um+ r> + r> if >r over um+ r> + then r> 1 - repeat drop >r nip r> ; : * ( n n -- n ) ( 6.1.0090 )( 0x20 ) um* drop ; ( divide ) : rshift ( u n -- u ) ( 6.1.2162 )( 0x28 ) 0 swap [ #bits ] literal swap - begin dup while >r 2dup d+ r> 1 - repeat drop nip ; : um/mod ( ud u -- ur uq ) ( 6.1.2370 )( 0xd5 ) 2dup u< if negate [ #bits ] literal begin dup while >r >r dup um+ >r >r dup um+ r> + dup r> r@ swap >r um+ r> or if >r drop 1 + r> else drop then r> r> 1 - repeat 2drop swap exit then drop 2drop -1 dup ; : sm/rem ( d n -- r q ) ( 6.1.2214 ) ( symmetric ) over >r >r dabs r@ abs um/mod r> r@ xor 0< if negate then r> 0< if >r negate r> then ; : fm/mod ( d n -- r q ) ( 6.1.1561 ) ( floored ) dup 0< dup >r if negate >r dnegate r> then >r dup 0< if r@ + then r> um/mod r> if >r negate r> then ; : /mod ( n n -- r q ) ( 6.1.0240 )( 0x2a ) over 0< swap fm/mod ; ( or sm/rem ) : mod ( n n -- r ) ( 6.1.1890 )( 0x22 ) /mod drop ; : / ( n n -- q ) ( 6.1.0230 )( 0x21 ) /mod nip ; ( memory access ) : +! ( n a -- ) ( 6.1.0130 )( 0x6c ) dup >r @ + r> ! ; : count ( a -- a c ) ( 6.1.0980 )( 0x84 ) dup char+ swap c@ ; : bounds ( a n -- a+n a ) ( 0xac ) over + swap ; : /string ( a u n -- a+n u-n ) ( 17.6.1.0245 ) dup >r - swap r> chars + swap ; : aligned ( a -- a ) ( 6.1.0706 )( 0xae ) ( depends on 2's comp and 2^n cell si ze ) [ 1 cells 1 - dup ] literal + [ invert ] literal and ; : 2! ( u u a -- ) ( 6.1.0310 )( 0x77 ) swap over ! cell+ ! ; : 2@ ( a -- u u ) ( 6.1.0350 )( 0x76 ) dup cell+ @ swap @ ; : move ( a a u -- ) ( 6.1.1900 )( 0x78 ) >r 2dup u< if begin r> dup while char- >r over r@ + c@ over r@ + c! repeat drop 2drop exit then r> over + >r begin dup r@ xor while >r dup c@ r@ c! char+ r> char+ repeat r> drop 2drop ; : fill ( a u c -- ) ( 6.1.1540 )( 0x79 ) >r chars bounds begin 2dup xor while r@ over c! char+ repeat r> drop 2drop ; : -trailing ( a u -- a u ) ( 17.6.1.0170 ) begin dup while 1 - 2dup chars + c@ bl swap u< until 1 + then ; : >adr ( xt -- a ) ; \ itc : >body ( xt -- a ) ( 6.1.0550 )( 0x86 ) >adr cell+ cell+ ; \ itc ( multitask ) variable up ( current task pointer ) : _usr ( -- a ) up @ r> @ + ; compile-only ( u1\tf\tid\tos\status\follower\r>-- @ >r ; compile-only ' _pass constant pass : _wake ( -- ) ( restore follower ) r> up ! tos @ sp! rp! ; compile-only ' _wake constant wake : pause ( -- ) ( allow another task to execute ) rp@ sp@ tos ! follower @ >r ; : stop ( -- ) ( sleep current task ) pass status ! pause ; compile-only : get ( semaphore -- ) pause ( remember your manners ) dup @ status xor ( owner ? ) if begin dup @ while pause repeat ( no, wait for release ) status swap ! ( lock ) exit then drop ; : release ( semaphore -- ) dup @ status xor if drop exit then 0 swap ! ( unlock ) ; : sleep ( tid -- ) ( sleep another task ) pass swap status 's ! ; : awake ( tid -- ) ( wake another task ) wake swap status 's ! ; : activate ( tid -- ) dup 2@ ( tid sp rp ) r> over ! ( save entry at rp ) over ! ( save rp at sp ) over tos 's ! ( save sp in tos ) awake ; compile-only : build ( tid -- ) dup sleep ( sleep new task ) follower @ over follower 's ! ( link new task ) dup status 's follower ! ( link old task ) dup tid 's ! ; ( link to tid ) ( numeric input ) : digit? ( c base -- u f ) ( 0xa3 ) >r [char] 0 - 9 over < if 7 - dup 10 < or then dup r> u< ; : >number ( ud a u -- ud a u ) ( 6.1.0570 ) begin dup while >r dup >r c@ base @ digit? while swap base @ um* drop rot base @ um* d+ r> char+ r> 1 - repeat drop r> r> then ; : number? ( a u -- d -1 | a u 0 ) over c@ [char] - = dup >r if 1 /string then >r >r 0 dup r> r> -1 dpl ! begin >number dup while over c@ [char] . xor if rot drop rot r> 2drop 0 exit then 1 - dpl ! char+ dpl @ repeat 2drop r> if dnegate then -1 ; ( numeric output ) : here ( -- a ) ( 6.1.1650 )( 0xad ) dp @ ; : pad ( -- a ) ( 6.2.2000 ) here [ #pad chars ] literal + ; : <# ( -- ) ( 6.1.0490 )( 0x96 ) pad hld ! ; : digit ( u -- c ) 9 over < 7 and + [char] 0 + ; : hold ( c -- ) ( 6.1.1670 )( 0x95 ) hld @ char- dup hld ! c! ; : # ( d -- d ) ( 6.1.0030 )( 0xc7 ) 0 base @ um/mod >r base @ um/mod swap digit hold r> ; : #s ( d -- d ) ( 6.1.0050 )( 0xc8 ) begin # 2dup or 0= until ; : #> ( d -- a u ) ( 6.1.0040 )( 0xc9 ) 2drop hld @ pad over - ; : sign ( n -- ) ( 6.1.2210 )( 0x98 ) 0< if [char] - hold then ; ( error handling ) : catch ( xt -- 0 | err ) ( 9.6.1.0875 )( 0x217 ) sp@ >r tf @ >r rp@ tf ! execute r> tf ! r> drop 0 ; : throw ( 0 | err -- | err ) ( r: i*x i*y -- i*x i*y | i*x ) ( 9.6.1.2275 )( 0x 218 ) ?dup if tf @ rp! r> tf ! r> swap >r sp! drop r> then ; : abort ( i*n -- ) ( r: i*x i*y -- i*x ) ( 9.6.2.0670 )( 0x216 ) -1 throw ; ( basic i/o ) : ?key ( -- c -1 | 0 ) pause '?key @ execute ; : key ( -- c ) ( 6.1.1750 )( 0x8e ) begin ?key until ; : nuf? ( -- f ) ?key dup if 2drop key [ =cr ] literal = then ; : emit ( c -- ) ( 6.1.1320 )( 0x8f ) 'emit @ execute ; : space ( -- ) ( 6.1.2220 ) bl emit ; ,c" coyote" : emits ( n c -- ) swap 0 max begin dup while over emit 1 - repeat 2drop ; : spaces ( n -- ) ( 6.1.2230 ) bl emits ; : type ( a u -- ) ( 6.1.2310 )( 0x90 ) chars bounds begin 2dup xor while count emit repeat 2drop ; : cr ( -- ) ( 6.1.0990 )( 0x92 ) [ =cr ] literal emit [ =lf ] literal emit ; : _" ( -- a ) r> r> dup count chars + aligned >r swap >r ; compile-only : _s" ( -- a u ) _" count ; compile-only : _." ( -- ) ( 0x12 ) _" count type ; compile-only : _abort" ( i*n f -- i*n | ) ( r: i*x i*y -- i*x i*y | i*x ) if _" csp ! -2 throw then _" drop ; compile-only : s.r ( a u n -- ) over - spaces type ; : d.r ( d n -- ) ( 8.6.1.1070 ) >r dup >r dabs <# #s r> sign #> r> s.r ; : u.r ( u n -- ) ( 6.2.2330 )( 0x9c ) 0 swap d.r ; : .r ( n n -- ) ( 6.2.0210 )( 0x9e ) >r s>d r> d.r ; : d. ( d -- ) ( 8.6.1.1060 ) 0 d.r space ; : u. ( u -- ) ( 6.1.2320 )( 0x9b ) 0 d. ; : . ( n -- ) ( 6.1.0180 )( 0x9d ) base @ 10 xor if u. exit then s>d d. ; : ? ( a -- ) ( 15.6.1.0600 ) @ . ; ( bits & bytes ) : pack ( a1 u a2 -- a2 ) ( 0x83 ) over 256 u< if dup >r over >r char+ swap chars move r> r@ c! r> exit then -18 throw ; : depth ( -- n ) ( 6.1.1200 )( 0x51 ) sp@ tid @ cell+ @ swap - [ 1 cells ] literal / ; : ?stack ( -- ) depth 0< abort" depth?" ; ( terminal ) : accept ( a u -- u ) ( 6.1.0695 ) over + over ( bot eot cur ) begin key dup [ =cr ] literal xor ( carrage return ? ) while dup [ =bs ] literal = ( backspace ? ) if ( destructive backspace ) drop >r over r@ < dup ( any chars ? ) if [ =bs ] literal dup emit bl emit emit then r> + else ( printable ) >r 2dup xor ( more ? ) if r@ over c! char+ r@ emit then r> drop then repeat drop nip swap - ; ( interpreter ) : same? ( a a u -- f ) \ ???faster chars swap >r begin dup while char- 2dup + c@ over r@ + c@ xor until r> drop 2drop 0 exit ( no match ) then r> drop 2drop -1 ; ( found ) : _delimit ( a u -- a u delta ) \ ???chars bounds dup >r char- begin char+ 2dup xor ( skip leading bl ) while bl over c@ < until swap over ( save first non blank addr ) begin char+ 2dup xor ( scan trailing bl ) while dup c@ bl 1 + < until nip dup char+ ( found ) else drop dup ( not found ) then >r over - r> else drop 0 over ( all bl ) then r> - ; : _parse ( a1 u1 c -- a1 u2 delta ) \ ???chars >r over + over char- ( save char, adjust addr ) begin char+ 2dup xor ( inc addr ? ) while dup c@ r@ = ( match ? ) until swap r> 2drop over - dup 1 + exit ( found ) then swap r> 2drop over - dup ; ( not found ) : name> ( a -- xt ) count chars + char+ aligned ; : wid? ( a u wid -- xt lex -1 | a u 0 ) \ ???chars swap >r @ ( address of last word ) begin dup ( last word ? ) while count r@ = ( count ? ) if 2dup r@ same? ( match ) if swap r> 2drop char- dup name> swap count chars + c@ -1 exit ( found ) then then char- cell- @ ( link ) repeat drop r> 0 ; ( no match ) create context ( search order ) #vocs 1 + cells allot ( wids ) : sfind ( a u -- xt lex -1 | a u 0 ) context cell- >r ( setup ) begin r> cell+ dup >r @ dup ( wid | 0 ) while wid? ( found ? ) until -1 then r> drop ; : _[ ( a u -- ) ( the forth interpreter ) sfind ( search dictionary ) if [ =comp ] literal and abort" compile?" execute ?stack exit then number? ( unknown symbol, try to convert a number ) if dpl @ 0< ( single? ) if drop then exit then -13 throw ; compile-only : [ ( -- ) ( 6.1.2500 ) ['] _[ 0 state 2! ; immediate : source ( -- a u ) ( 6.1.2216 ) #in 2@ ; : parse-word ( "ccc" -- a u ) source >in @ /string _delimit >in +! ; : evaluate ( a u -- ) ( 6.1.1360 )( 0xcd ) >in @ >r 0 >in ! source >r >r #in 2! begin parse-word dup while state cell+ @ execute repeat 2drop r> r> #in 2! r> >in ! ; ( redirect input ms-dos only =============================== ) : asciiz ( a u a -- a ) dup >r swap chars 2dup + 0 swap c! move r> ; : stdin ( a u -- ) here asciiz redirect abort" file?" ; compile-only : from ( "ccc" -- ) ( chain not nest ) parse-word stdin source >in ! drop ; ( ========================================================== ) create 'ok ( prompt options ) ' noop , ( typically .s ) : quit ( -- ) ( r: i*x -- ) ( 6.1.2050 ) sup @ rp! ( reset return stack ) [ ' [ compile, ] ( reset interpret state ) s" con" stdin ( reset console i/o, ms-dos only ) begin begin [ =tib ] literal ( input buffer ) dup [ #tib ] literal accept space ( user input ) ['] evaluate catch dup ( error ? ) if dup -1 xor ( abort = -1 ) if cr dup -2 xor ( abort" = -2 ) if source drop ( undefined error ) >in @ -trailing type ." ?(" 0 .r ." )" else csp @ count type then space then sup cell+ @ sp! ( reset data stack ) recurse ( restart ) then cr state @ = ( 0 from catch ) until 'ok @ execute ." ok " ( prompt ) again ; ( compiler ) : align ( -- ) ( 6.1.0705 ) here aligned dp ! ; : allot ( n -- ) ( 6.1.0710 ) dp +! ; : s, ( a u -- ) here over chars char+ allot pack drop ; : c, ( n -- ) ( 6.1.0860 )( 0xd0 ) here [ 1 chars ] literal allot c! ; : , ( n -- ) ( 6.1.0150 )( 0xd3 ) here [ 1 cells ] literal allot ! ; : compile, ( xt -- ) ( 6.2.0945 )( 0xdd ) , ; : literal ( n -- ) ( 6.1.1780 ) ['] _lit compile, , ; immediate : char ( "ccc" -- c ) ( 6.1.0895 ) parse-word drop c@ ; : [char] ( "ccc" -- ) ( 6.1.2520 ) char [ ' literal compile, ] ; immediate : ' ( "name" -- xt ) ( 6.1.0070 ) parse-word sfind if drop exit then -13 thr ow ; : ['] ( "name" -- ) ( 6.1.2510 ) ' [ ' literal compile, ] ; immediate : parse ( c "ccc" -- a u ) ( 6.2.2008 ) \ ???move >r source >in @ /string r> _parse >in +! ; : ( ( "comment" -- ) ( 6.2.0200 ) [char] ) parse type ; immediate : ( ( "comment" -- ) ( 6.1.0080 ) [char] ) parse 2drop ; immediate : \ ( "comment" -- ) ( 6.2.2535 ) source >in ! drop ; immediate : sliteral ( a u -- ) ( -- a u ) ( 17.6.1.2212 ) ['] _s" compile, s, align ; immediate compile-only : ,c" ( "ccc" -- ) [char] " parse s, align ; : s" ( "ccc" -- ) ( 6.1.2165 ) ['] _s" compile, ,c" ; immediate compile-only : ." ( "ccc" -- ) ( 6.1.0190 ) ['] _." compile, ,c" ; immediate compile-only : abort" ( "ccc" -- ) ( 6.1.0680 ) ['] _abort" compile, ,c" ; immediate compile-only : _] ( a u -- ) ( the forth compiler ) sfind ( search dictionary ) if [ =imed ] literal and if execute ?stack exit ( immediate ) then compile, exit then number? ( unknown symbol, try to convert a number ) if dpl @ 0< if drop ( single ) else swap [ ' literal compile, ] ( double ) then [ ' literal compile, ] exit then -13 throw ; compile-only : ] ( -- ) ( 6.1.2540 ) align ['] _] -1 state 2! ; create forth-wordlist ( -- wid ) ( 16.6.1.1595 ) 0 , ( na, of last definition, linked ) 0 , ( wid|0, next or last wordlist in chain ) 0 , ( na, wordlist name pointer ) create last ( -- a ) 1 cells allot ( na, of last definition, unlinked ) 1 cells allot ( wid, current wordlist for linking ) label =token 1 cells allot ( xt, of last definition ) create current ( -- a ) forth-wordlist , ( wid, new definitions ) forth-wordlist , ( wid, head of chain ) : get-current ( -- wid ) ( 16.6.1.1643 ) current @ ; : set-current ( wid -- ) ( 16.6.1.2195 ) current ! ; : definitions ( -- ) ( 16.6.1.1180 ) context @ set-current ; : ?unique ( a u -- a u ) 2dup get-current wid? if 2drop cr ." redef " 2dup type exit then 2drop ; : head, ( "name" -- ) \ ???fix ( xt "name" -- ) parse-word dup if ?unique ( warn if redefined ) align get-current dup @ , here last 2! ( link ) dup c, ( save count ) here swap dup allot move ( build name ) 0 c, ( build attribute byte ) exit then -16 throw ; ( attempt to use zero-length string ) | : lex! ( u -- ) last @ count chars + dup >r c@ or r> c! ; : immediate ( -- ) ( 6.1.1710 ) [ =imed ] literal lex! ; : compile-only ( -- ) [ =comp ] literal lex! ; : reveal ( -- ) last 2@ swap ! [ ' [ compile, ] ; : recurse ( -- ) ( 6.1.2120 ) [ =token ] literal @ compile, ; immediate : postpone ( "name" -- ) ( 6.1.2033 ) parse-word sfind if [ =imed ] literal and if compile, exit then [ ' literal compile, ] ['] compile, compile, exit then -13 throw ; immediate ( defining words ) : code ( "name" -- ) ( 15.6.2.0930 ) \ itc head, align here cell+ , reveal ; : next, ( -- ) \ itc 80x86 only [ next1 ] literal h# e9 c, here 2 + - , ; : :noname ( -- xt ) ( 6.2.0455 ) \ itc align here dup [ =token ] literal ! [ list1 ] literal , ] ; : : ( "name" -- ) ( 6.1.0450 ) head, :noname drop ; : ; ( -- ) ( 6.1.0460 ) ['] exit compile, reveal ; immediate compile-only : _does> ( -- ) ( link child ) \ align ( child ) \ ???why r> [ =token ] literal @ cell+ ( itc ) ! ; compile-only : does> ( -- ) ( 6.1.1250 ) ( build parent ) ['] _does> compile, ( link child ) :noname drop ['] r> compile, ( begin child ) ; immediate compile-only : create ( "name" -- ) ( 6.1.1000 ) ['] _var : reveal compile, ; : variable ( "name" -- ) ( 6.1.2410 ) create 0 , ; : constant ( n "name" -- ) ( 6.1.0950 ) ['] _con : reveal compile, , ; : user ( n "name" -- ) ['] _usr : reveal compile, , ; : hat ( u s r "name" -- ) ( -- tid ) create + swap [ 7 cells ] literal + ( tf\tid\tos\status\follower\r>--r cell+ recurse r> swap 1 + exit then nip ; : get-order ( -- u*wid u ) ( 16.6.1.1647 ) context order@ ; : set-order ( u*wid n -- ) ( 16.6.1.2197 ) dup -1 = if drop forth-wordlist 1 then ( default ? ) [ #vocs ] literal over u< if -46 throw then ( range ? ) context swap begin dup while >r swap over ! cell+ r> 1 - repeat ( 0 ) swap ! ; \ ============================================================ : _marker ( -- ) ( r: dfa -- ) \ ??? r> 2@ ( * ) dup @ follower ! dup context begin >r cell+ dup @ dup r@ ! while r> cell+ repeat ( search order ) cell+ dup 2@ current 2! cell+ dup @ ( cur wid & head ) begin >r cell+ dup @ r@ ! r> cell+ @ ?dup 0= until ( wid last na's ) r> 2drop ( * ) dp 2! ; compile-only : marker ( "name" -- ) \ ??? align dp 2@ ( * ) follower @ , context begin dup @ dup , while cell+ repeat drop ( search order ) current 2@ , dup , ( cur wid & head ) begin dup @ , cell+ @ ?dup 0= until ( wid last na's ) ['] _marker : reveal compile, ( * ) , , ; \ ============================================================ ( control flow ) : begin ( -- a ) ( 6.1.0760 ) here ; immediate : then ( a -- ) ( 6.1.2270 ) [ ' begin compile, ] ( over - ) swap ! ; immediate : resolve ( a -- ) ( [ ' begin compile, ] - ) , ; : mark ( -- a ) here [ ' begin compile, ] resolve ; : if ( -- a ) ( 6.1.1700 ) ['] _if compile, mark ; immediate : ahead ( -- a ) ( 15.6.2.0702 ) ['] _else compile, mark ; immediate : else ( a -- a ) ( 6.1.1310 ) [ ' ahead compile, ] swap [ ' then compile, ] ; immediate : while ( a -- a a ) ( 6.1.2430 ) [ ' if compile, ] swap ; immediate : until ( a -- ) ( 6.1.2390 ) ['] _if compile, resolve ; immediate : again ( a -- ) ( 6.2.0700 ) ['] _else compile, resolve ; immediate : repeat ( a a -- ) ( 6.1.2140 ) [ ' again compile, ' then compile, ] ; immedia te ( tools ) : .s ( -- ) ( 15.6.1.0220 )( 0x9f ) ?stack depth begin ?dup while dup pick . 1 - repeat ; : !csp ( -- ) sp@ csp ! ; : ?csp ( -- ) sp@ csp @ xor abort" csp?" ; : >char ( c -- c ) h# 7f and dup 127 bl within if drop [char] _ then ; : _type ( a u -- ) ( alpha dump ) chars bounds begin 2dup xor while count >char emit repeat 2drop ; : _dump ( a u -- ) ( numeric dump ) chars bounds begin 2dup xor while count 3 u.r repeat 2drop ; : dump ( a u -- ) ( 15.6.1.1280 ) base @ >r hex chars bounds begin 2dup swap u< while ( range? ) cr dup 0 <# # # # # #> type ( address ) space [ #dump ] literal 2dup _dump ( numeric ) space space 2dup _type ( alpha ) chars + nuf? ( user? ) until then 2drop r> base ! ; : .id ( a -- ) count _type ; : widwords ( a u wid -- a u ) swap >r dup if cr dup ." wid=" u. cr begin @ dup ( last name ? ) while 2dup char+ r@ same? ( match ? ) if dup .id space then cell- nuf? until then then drop r> ; : words ( "ccc" -- ) bl parse dup if current begin cell+ @ ?dup while dup >r widwords r> repeat ( all wid ) else context @ widwords then 2drop ; : named? ( aa -- na | 0 ) current ( all wid ) begin cell+ @ dup ( last link ? ) while dup >r begin @ ?dup ( zero link ? ) while 2dup name> >adr = ( match ? ) if swap r> 2drop exit ( found ) then cell- repeat r> repeat nip ( not found ) ; : ssee ( a u -- ) ( simple decompiler ) cells bounds begin 2dup xor ( done? ) while dup named? ?dup if cr .id cr then space dup @ >adr named? ?dup if .id ( display named token ) else dup @ 0 u.r ( unnamed token ) then cell+ nuf? until then 2drop ; : see ( "name" -- ) ( 15.6.1.2194 ) ' >adr -1 ssee ; ( software reset ) : cold ( -- ) sup 2@ rp! sp! ( init stacks ) sup @ cell- ( follower ) up ! ( init user pointer ) status follower ! sup tid ! sup awake ( init tasks ) 0 !io ( init i/o device ) hex -1 set-order definitions cr [ =version ] literal count type cr [ =(c) ] literal count type cr quit ; code bye ( -- ) ( 15.6.2.0830 ) h# 20 int ( terminate process ) end-code proc vcold ( cold start entry ) cli ( disable interrupt for old 808x cpu bug ) cs ax mov ax ds mov ( ds=cs ) ax ss mov ( ss=cs ) sup ## bp mov ( system user pointer ) 1 cells bp [] sp mov ( init sp ) 0 cells bp [] bp mov ( init rp ) sti ( enable interrrupts ) \ ===================== reset ## dx mov ( ^c on output ms-dos only ) h# 2523 ## ax mov ( set ^c interrupt int23 ) h# 21 int \ ===================== cld ( direction flag, increment ) ' cold ## di mov ( first word to execute ) \ itc 0 di [] jmp ( start eforth ) end-code cr ( metacompile end ) ]meta references 1. mailto:bill muench?subject=eforth license