1 \ @(#) numberio.fth 98/01/26 1.2
7 \ Copyright 1994 3DO, Phil Burk, Larry Polansky, David Rosenboom
9 \ Permission to use, copy, modify, and/or distribute this
10 \ software for any purpose with or without fee is hereby granted.
12 \ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 \ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 \ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
15 \ THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
16 \ CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
17 \ FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
18 \ CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 \ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 anew task-numberio.fth
24 \ ------------------------ INPUT -------------------------------
25 \ Convert a single character to a number in the given base.
26 : DIGIT ( char base -- n true | char false )
28 \ convert lower to upper
35 IF ascii A - ascii 9 + 1+
39 ( between 9 and A is bad )
40 drop 0 ( trigger error below )
53 : >NUMBER ( ud1 c-addr1 u1 -- ud2 c-addr2 u2 , convert till bad char , CORE )
56 r@ 0> \ any characters left?
59 digit ( ud1 c-addr , n true | char false )
68 WHILE ( -- ud1 c-addr n )
69 swap >r ( -- ud1lo ud1hi n )
70 swap base @ ( -- ud1lo n ud1hi base )
71 um* drop ( -- ud1lo n ud1hi*baselo )
72 rot base @ ( -- n ud1hi*baselo ud1lo base )
73 um* ( -- n ud1hi*baselo ud1lo*basello ud1lo*baselhi )
75 r> 1+ \ increment char*
76 r> 1- >r \ decrement count
82 : CONVERT ( ud1 c-addr1 -- ud2 c-addr2 , convert till bad char , CORE EXT )
86 0 constant NUM_TYPE_BAD
87 1 constant NUM_TYPE_SINGLE
88 2 constant NUM_TYPE_DOUBLE
90 \ Like >number, but temporarily switch BASE.
91 : (>number-with-base) ( ud c-addr u base -- ud' c-addr' u' )
92 base @ >r base ! >number r> base !
95 \ This is similar to the F83 NUMBER? except that it returns a number type
96 \ and then either a single or double precision number.
97 : ((NUMBER?)) ( c-addr u -- 0 | n 1 | d 2 , convert string to number )
98 dup 0= IF 2drop NUM_TYPE_BAD exit THEN \ any chars?
100 base @ -rot ( base c-addr u )
102 \ Recognize prefixes and change base if needed
103 over c@ >r ( base c-addr u ) ( r: char )
104 r@ [char] # = if rot drop 10 -rot 1 /string then
105 r@ [char] $ = if rot drop 16 -rot 1 /string then
106 r@ [char] % = if rot drop 2 -rot 1 /string then
110 over 2 chars + c@ [char] ' = if
112 char+ c@ NUM_TYPE_SINGLE exit
118 \ check for '-' at beginning, skip if present
119 over c@ ascii - = \ is it a '-'
121 IF 1 /string ( -- base c-addr+1 cnt-1 , skip past minus sign )
124 ( base c-addr cnt ) ( r: minus-flag )
126 (>number-with-base) dup 0= \ convert as much as we can
128 2drop \ drop addr cnt
129 drop \ drop hi part of num
130 r@ \ check flag to see if '-' sign used
134 ELSE ( -- d addr cnt )
135 1 = swap \ if final character is '.' then double
138 r@ \ check flag to see if '-' sign used
150 : (NUMBER?) ( $addr -- 0 | n 1 | d 2 , convert string to number )
154 ' (number?) is number?
156 \ 0sp c" xyz" (number?) .s
157 \ 0sp c" 234" (number?) .s
158 \ 0sp c" -234" (number?) .s
159 \ 0sp c" 234." (number?) .s
160 \ 0sp c" -234." (number?) .s
161 \ 0sp c" 1234567855554444." (number?) .s
164 \ ------------------------ OUTPUT ------------------------------
165 \ Number output based on F83
166 variable HLD \ points to last character added
168 : hold ( char -- , add character to text representation)
172 : <# ( -- , setup conversion )
175 : #> ( d -- addr len , finish conversion )
176 2drop hld @ pad over -
178 : sign ( n -- , add '-' if negative )
179 0< if ascii - hold then
181 : # ( d -- d , convert one digit )
182 base @ mu/mod rot 9 over <
187 : #s ( d -- d , convert remaining digits )
193 : (UD.) ( ud -- c-addr cnt )
196 : UD. ( ud -- , print unsigned double number )
200 >r (ud.) r> over - spaces type
202 : (D.) ( d -- c-addr cnt )
203 tuck dabs <# #s rot sign #>
208 : D.R ( d n -- , right justified )
209 >r (d.) r> over - spaces type
212 : (U.) ( u -- c-addr cnt )
215 : U. ( u -- , print unsigned number )
218 : U.R ( u n -- , print right justified )
219 >r (u.) r> over - spaces type
221 : (.) ( n -- c-addr cnt )
222 dup abs 0 <# #s rot sign #>
224 : . ( n -- , print signed number)
227 : .R ( n l -- , print right justified)
228 >r (.) r> over - spaces type