2008-11-05 22:59:06 -05:00
|
|
|
! Copyright (c) 2007, 2008 Aaron Schaefer.
|
2007-12-24 00:06:53 -05:00
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
2009-01-23 09:22:03 -05:00
|
|
|
USING: combinators.short-circuit grouping kernel math math.parser
|
|
|
|
math.text.utils namespaces sequences ;
|
2008-01-06 22:21:58 -05:00
|
|
|
IN: math.text.english
|
2007-12-24 00:06:53 -05:00
|
|
|
|
|
|
|
<PRIVATE
|
|
|
|
|
|
|
|
: small-numbers ( n -- str )
|
|
|
|
{ "Zero" "One" "Two" "Three" "Four" "Five" "Six" "Seven" "Eight" "Nine"
|
|
|
|
"Ten" "Eleven" "Twelve" "Thirteen" "Fourteen" "Fifteen" "Sixteen"
|
|
|
|
"Seventeen" "Eighteen" "Nineteen" } nth ;
|
|
|
|
|
|
|
|
: tens ( n -- str )
|
2008-01-21 22:36:20 -05:00
|
|
|
{ f f "Twenty" "Thirty" "Forty" "Fifty" "Sixty" "Seventy" "Eighty" "Ninety" } nth ;
|
2007-12-24 00:06:53 -05:00
|
|
|
|
|
|
|
: scale-numbers ( n -- str ) ! up to 10^99
|
2008-01-21 22:36:20 -05:00
|
|
|
{ f "Thousand" "Million" "Billion" "Trillion" "Quadrillion" "Quintillion"
|
2007-12-24 00:06:53 -05:00
|
|
|
"Sextillion" "Septillion" "Octillion" "Nonillion" "Decillion" "Undecillion"
|
|
|
|
"Duodecillion" "Tredecillion" "Quattuordecillion" "Quindecillion"
|
|
|
|
"Sexdecillion" "Septendecillion" "Octodecillion" "Novemdecillion"
|
|
|
|
"Vigintillion" "Unvigintillion" "Duovigintillion" "Trevigintillion"
|
|
|
|
"Quattuorvigintillion" "Quinvigintillion" "Sexvigintillion"
|
|
|
|
"Septvigintillion" "Octovigintillion" "Novemvigintillion" "Trigintillion"
|
|
|
|
"Untrigintillion" "Duotrigintillion" } nth ;
|
|
|
|
|
|
|
|
SYMBOL: and-needed?
|
|
|
|
: set-conjunction ( seq -- )
|
2008-11-09 17:23:24 -05:00
|
|
|
first { [ 100 < ] [ 0 > ] } 1&& and-needed? set ;
|
2007-12-24 00:06:53 -05:00
|
|
|
|
|
|
|
: negative-text ( n -- str )
|
|
|
|
0 < "Negative " "" ? ;
|
|
|
|
|
|
|
|
: hundreds-place ( n -- str )
|
2008-12-15 21:49:31 -05:00
|
|
|
100 /mod over 0 = [
|
2007-12-24 00:06:53 -05:00
|
|
|
2drop ""
|
|
|
|
] [
|
2008-12-15 21:49:31 -05:00
|
|
|
[ small-numbers " Hundred" append ] dip
|
|
|
|
0 = [ " and " append ] unless
|
2007-12-24 00:06:53 -05:00
|
|
|
] if ;
|
|
|
|
|
|
|
|
: tens-place ( n -- str )
|
|
|
|
100 mod dup 20 >= [
|
2008-01-21 22:36:20 -05:00
|
|
|
10 /mod [ tens ] dip
|
2008-12-15 21:49:31 -05:00
|
|
|
dup 0 = [ drop ] [ small-numbers "-" glue ] if
|
2007-12-24 00:06:53 -05:00
|
|
|
] [
|
2008-12-15 21:49:31 -05:00
|
|
|
dup 0 = [ drop "" ] [ small-numbers ] if
|
2007-12-24 00:06:53 -05:00
|
|
|
] if ;
|
|
|
|
|
|
|
|
: 3digits>text ( n -- str )
|
2008-11-05 22:59:06 -05:00
|
|
|
[ hundreds-place ] [ tens-place ] bi append ;
|
2007-12-24 00:06:53 -05:00
|
|
|
|
|
|
|
: text-with-scale ( index seq -- str )
|
2008-11-05 22:59:06 -05:00
|
|
|
[ nth 3digits>text ] [ drop scale-numbers ] 2bi
|
2008-12-03 20:11:55 -05:00
|
|
|
[ " " glue ] unless-empty ;
|
2007-12-24 00:06:53 -05:00
|
|
|
|
|
|
|
: append-with-conjunction ( str1 str2 -- newstr )
|
2008-12-15 21:49:31 -05:00
|
|
|
over length 0 = [
|
2007-12-24 00:06:53 -05:00
|
|
|
nip
|
|
|
|
] [
|
2008-12-15 21:49:31 -05:00
|
|
|
swap and-needed? get " and " ", " ?
|
|
|
|
glue and-needed? off
|
2007-12-24 00:06:53 -05:00
|
|
|
] if ;
|
|
|
|
|
2008-11-05 22:59:06 -05:00
|
|
|
: (recombine) ( str index seq -- newstr )
|
2008-12-15 21:49:31 -05:00
|
|
|
2dup nth 0 = [
|
2008-11-05 22:59:06 -05:00
|
|
|
2drop
|
2007-12-24 00:06:53 -05:00
|
|
|
] [
|
2008-11-05 22:59:06 -05:00
|
|
|
text-with-scale append-with-conjunction
|
2007-12-24 00:06:53 -05:00
|
|
|
] if ;
|
|
|
|
|
|
|
|
: recombine ( seq -- str )
|
2008-04-01 18:06:36 -04:00
|
|
|
dup length 1 = [
|
2007-12-24 00:06:53 -05:00
|
|
|
first 3digits>text
|
|
|
|
] [
|
2008-11-05 22:59:06 -05:00
|
|
|
[ set-conjunction "" ] [ length ] [ ] tri
|
|
|
|
[ (recombine) ] curry each
|
2007-12-24 00:06:53 -05:00
|
|
|
] if ;
|
|
|
|
|
|
|
|
: (number>text) ( n -- str )
|
2008-10-03 03:19:03 -04:00
|
|
|
[ negative-text ] [ abs 3digit-groups recombine ] bi append ;
|
2007-12-24 00:06:53 -05:00
|
|
|
|
|
|
|
PRIVATE>
|
|
|
|
|
|
|
|
: number>text ( n -- str )
|
2008-10-03 03:19:03 -04:00
|
|
|
dup zero? [ small-numbers ] [ [ (number>text) ] with-scope ] if ;
|
2008-01-21 22:36:20 -05:00
|
|
|
|