Paste: Decimal.factor

Author: george
Mode: factor
Date: Tue, 23 Jun 2009 02:03:30
Plain Text |
USING: io kernel math math.functions math.parser parser lexer
namespaces make sequences splitting grouping combinators
continuations ;
IN: decimal

SYMBOL: currency-token
CHAR: $ \ currency-token set-global

: split/ ( dollars spliter -- dollars cents )
   10 swap ^ [ * ] [ ] bi /mod round ;

: decimal>string ( dec prec -- str )  split/ [ number>string ] bi@ "." glue ;
: money>string ( decimal -- str ) 2 decimal>string ;
: money. ( object -- ) money>string print ;

ERROR: not-an-integer x ;

: parse-decimal ( str -- atio )
    "." split1
    [ "-" ?head swap ] dip
    [ [ "0" ] when-empty ] bi@
    [
        [ dup string>number [ nip ] [ not-an-integer ] if* ] bi@
    ] keep length
    10 swap ^ / + swap [ neg ] when ;


SYNTAX: DECIMAL: scan parse-decimal parsed ;

Annotation: tests

Author: george
Mode: factor
Date: Tue, 23 Jun 2009 02:04:10
Plain Text |
USING: decimal parser tools.test eval ;
IN: decimal.tests

[ -1/10 ] [ DECIMAL: -.1 ] unit-test
[ -1/10 ] [ DECIMAL: -0.1 ] unit-test
[ -1/10 ] [ DECIMAL: -00.10 ] unit-test

[ 0 ] [ DECIMAL: .0 ] unit-test
[ 0 ] [ DECIMAL: 0.0 ] unit-test
[ 0 ] [ DECIMAL: 0. ] unit-test
[ 0 ] [ DECIMAL: 0 ] unit-test
[ 1/10 ] [ DECIMAL: .1 ] unit-test
[ 1/10 ] [ DECIMAL: 0.1 ] unit-test
[ 1/10 ] [ DECIMAL: 00.10 ] unit-test
[ 23 ] [ DECIMAL: 23 ] unit-test
[ -23 ] [ DECIMAL: -23 ] unit-test
[ -23-1/100 ] [ DECIMAL: -23.01 ] unit-test

[ "DECIMAL: ." eval ] must-fail
[ "DECIMAL: f" eval ] must-fail
[ "DECIMAL: 0.f" eval ] must-fail
[ "DECIMAL: f.0" eval ] must-fail

[ "100.0" ] [ DECIMAL: 100.0 money>string ] unit-test
[ "0.0" ] [ DECIMAL: 0.0 money>string ] unit-test

[ "100.255" ] [ DECIMAL: 100.255 3 decimal>string ] unit-test

New Annotation

Summary:
Author:
Mode:
Body: