2 @program english-numbers.muf
5 $note A simple routine to render a numeric value as english words.
13 integer variant doesn't check for integer overflow
14 doesn't do fancy shortening, like someteen-hundred
19 $author <justin.wind@gmail.com>
23 ( trim some debug fluff )
24 $def D_SAVE prog "D" flag? D_STATE !
25 $def D_UNSET prog "!D" set
26 $def D_RESTORE D_STATE @ if prog "D" set then
37 ( the numbers, up until things become predictable )
38 : low_numbers_ ( @ -- s )
40 { "" "one" "two" "three" "four" "five" "six" "seven" "eight" "nine" "ten"
41 "eleven" "twelve" "thirteen" "fourteen" "fifteen" "sixteen" "seventeen"
50 { "" "" "twenty" "thirty" "forty" "fifty" "sixty" "seventy" "eighty" "ninety"
55 ( just to keep things stylistically similar )
59 ( words for big numbers, according to wikipedia )
60 : big_numbers_ ( @ -- s )
62 { "" "thousand" "million" "billion" "trillion" "quadrillion"
63 "quintillion" "sextillion" "septillion" "octillion" "nonillion"
64 "decillion" "undecillion" "duodecillion" "tredecillion"
65 "quattuordecillion" "quindecillion" "sexdecillion" "septendecillion"
66 "octodecillion" "novemdecillion" "vigintillion" "silmarillion"
69 dup 0 = if pop "???-illion" then
73 ( outputs the words for a number under one-thousand )
74 : english_sub_thousand_ ( i -- s )
76 dup 1000 % 100 / var! HUNDREDS
77 dup 100 % 10 / var! TENS
80 ( show hundreds if they exist )
83 HUNDREDS @ low_numbers_ strcat
86 ( if there's more number to show, need a word break )
93 ( show remaining teens or under )
96 over 20 % low_numbers_ strcat
99 ( otherwise show remaining tens-ones pattern )
101 TENS @ decades_ strcat
104 ONES @ low_numbers_ strcat
113 : english-number ( i -- s )
119 dup sign 0 < var! ISNEG
130 dup 1000 % english_sub_thousand_ ( i s )
131 BIGNESS @ dup 1 >= if ( i s i )
132 big_numbers_ " " swap strcat ( i s s )
138 dup strlen if ( i s s )
144 1000 / dup 0 = ( i i )
149 "negative " swap strcat
152 public english-number
154 : strcut-end ( s i -- s s )
157 ( requested more than string has )
164 ( deal with number as string )
166 : mpi-english-number ( s -- s )
167 ( atoi english-number exit )
172 dup strlen while ( s )
179 english_sub_thousand_ ( s s )
180 BIGNESS @ dup 1 >= if ( s s i )
181 big_numbers_ ( s s s )
182 " " swap strcat ( s s s )
188 dup strlen if ( s s s )
202 "negative " swap strcat
208 @reg english-numbers.muf=lib/squeep/english-numbers
209 @set $lib/squeep/english-numbers=_docs:@list english-numbers.muf=1-10
210 @set $lib/squeep/english-numbers=L
211 @set $lib/squeep/english-numbers=V
213 @set #0=_msgmacs/english-number:{muf:$lib/squeep/english-numbers,{:1}}