Hash :
1a08f436
Author :
Date :
2010-08-25T09:23:17
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
\ @(#)io.fth 2.22 05/02/14
\ Copyright 1985-1994 Bradley Forthware
\ Copyright 2005 Sun Microsystems, Inc. All Rights Reserved
\ Copyright Use is subject to license terms.
decimal
\ Emit is a two-level vector.
\ The low level is (emit and the high level is emit.
\ The low-level vector just selects the output device.
\ The high-level vector performs other processing such as keeping
\ track of the current position on the line, pausing, etc.
\ Terminal control with escape sequences should use the low-level vector
\ to prevent a pause from garbling the escape sequence.
\ Key is a two-level vector.
\ The low level is (key and the high level is key.
\ The low-level vector just selects the output device.
\ The high-level vector performs other processing such as switching
\ the input stream between different windows.
defer (type ( adr len -- ) \ Low-level type; just outputs characters
defer type ( adr len -- ) \ High-level type
defer (emit ( c -- ) \ Low level emit; just puts out the character
defer emit ( c -- ) \ Higher level; keeps track of position on the line, etc
defer (key ( -- c ) \ Low level key; just gets key
defer key ( -- c ) \ Higher level; may do other nonsense
defer key? ( -- f ) \ Is a character waiting?
defer bye ( -- ) \ Exit to the operating system, if any
defer (interactive? ( -- f ) \ Is input coming from the keyboard?
defer interactive? ( -- f ) \ Is input coming from the keyboard?
' (interactive? is interactive?
defer prompt ( -- )
defer quit
defer accept ( adr len -- ) \ Read up to len characters from keyboard
defer alloc-mem ( #bytes -- address )
defer free-mem ( adr #bytes -- )
defer lock[ ( -- ) ' noop is lock[
defer ]unlock ( -- ) ' noop is ]unlock
defer sync-cache ( adr len -- ) ' 2drop is sync-cache
defer #out ( -- adr )
defer #line ( -- adr )
defer cr ( -- )
\ Default actions
: key1 ( -- char ) begin pause key? until (key ;
: emit1 ( char -- ) pause (emit 1 #out +! ;
: type1 ( adr len -- ) pause dup #out +! (type ;
: default-type ( adr len -- )
0 max bounds ?do pause i c@ (emit loop
;
\ headerless \ from campus version
nuser (#out \ number of characters emitted
\ headers \ from campus version
nuser (#line \ the number of lines sent so far
\ Install defaults
' emit1 is emit
' type1 is type
' key1 is key
' (#out is #out
' (#line is #line
decimal
7 constant bell
8 constant bs
10 constant linefeed
13 constant carret
\ Obsolescent, but required by the IEEE 1275 device interface
nuser span \ number of characters received by expect
\ A place to put the last word returned by blword
0 value 'word
: expect ( adr len -- ) accept span ! ;
defer newline-pstring
: newline-string ( -- adr len ) newline-pstring count ;
: newline ( -- char ) newline-string + 1- c@ ; \ Last character
: space (s -- ) bl emit ;
: spaces (s n -- ) 0 max 0 ?do space loop ;
: backspaces (s n -- ) dup negate #out +! 0 ?do bs (emit loop ;
: beep (s -- ) bell (emit ;
: (lf (s -- ) 1 #line +! linefeed (emit ;
: (cr (s -- ) carret (emit ;
: lf (s -- ) #out off (lf ;
: crlf (s -- ) (cr lf ;
0 value tib
headerless
0 value #-buf
chain: init ( -- )
40 dup alloc-mem + is #-buf
/tib alloc-mem is tib
;
headers
nuser base \ for numeric input and output
nuser hld \ points to last character held in #-buf
: hold (s char -- ) -1 hld +! hld @ c! ;
: hold$ ( adr len -- )
dup if
1- bounds swap do i c@ hold -1 +loop
else
2drop
then
;
: <# (s -- ) #-buf hld ! ;
: sign (s n -- ) 0< if ascii - hold then ;
\ for upper case hex output, change 39 to 7
: >digit (s n -- char ) dup 9 > if 39 + then 48 + ;
: u# (s u1 -- u2 )
base @ u/mod ( nrem u2 ) swap >digit hold ( u2 )
;
: u#s (s u -- 0 ) begin u# dup 0= until ;
: u#> (s u -- addr len ) drop hld @ #-buf over - ;
: mu/mod (s d n1 -- rem d.quot )
>r 0 r@ um/mod r> swap >r um/mod r>
;
: # (s ud1 -- ud2 )
base @ mu/mod ( nrem ud2 ) rot >digit hold ( ud2 )
;
: #s (s ud -- 0 0 ) begin # 2dup or 0= until ;
: #> (s ud -- addr len ) drop u#> ;
: (u.) (s u -- a len ) <# u#s u#> ;
: u. (s u -- ) (u.) type space ;
: u.r (s u len -- ) >r (u.) r> over - spaces type ;
: (.) (s n -- a len ) dup abs <# u#s swap sign u#> ;
: (.d) ( n -- adr len ) base @ >r decimal (.) r> base ! ;
: (.h) ( n -- adr len ) base @ >r hex (.) r> base ! ;
: s. (s n -- ) (.) type space ;
: .r (s n l -- ) >r (.) r> over - spaces type ;
[ifndef] run-time
headerless
: (ul.) (s ul -- a l ) n->l <# u#s u#> ;
headers
: ul. (s ul -- ) (ul.) type space ;
headerless
: ul.r (s ul l -- ) >r (ul.) r> over - spaces type ;
: (l.) (s l -- a l ) dup l->n swap abs <# u#s swap sign u#> ;
headers
: l. (s l -- ) base @ d# 10 = if (l.) else (ul.) then type space ;
headerless
: l.r (s l l -- ) >r (l.) r> over - spaces type ;
headers
[then]
\ smart print that knows that signed hex numbers are uninteresting
: n. (s n -- ) base @ 10 = if s. else u. then ;
: . (s n -- ) (.) type space ;
: ? (s addr -- ) @ n. ;
: (.s (s -- )
depth 0 ?do depth i - 1- pick n. loop
;
: .s (s -- )
depth 0<
if ." Stack Underflow " sp0 @ sp!
else depth
if (.s else ." Empty " then
then
;
: ". (s pstr -- ) count type ;