2008-07-22 05:45:03 -04:00
|
|
|
! Copyright (C) 2008 Slava Pestov.
|
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
|
|
|
USING: accessors kernel kernel.private math math.private words
|
2008-09-10 21:07:00 -04:00
|
|
|
sequences parser namespaces make assocs quotations arrays locals
|
2008-09-12 09:18:44 -04:00
|
|
|
generic generic.math hashtables effects compiler.units
|
|
|
|
classes.algebra ;
|
2008-07-22 05:45:03 -04:00
|
|
|
IN: math.partial-dispatch
|
|
|
|
|
|
|
|
PREDICATE: math-partial < word
|
|
|
|
"derived-from" word-prop >boolean ;
|
|
|
|
|
2008-09-12 19:08:38 -04:00
|
|
|
GENERIC: integer-op-input-classes ( word -- classes )
|
|
|
|
|
|
|
|
M: math-partial integer-op-input-classes
|
|
|
|
"derived-from" word-prop rest ;
|
|
|
|
|
|
|
|
M: word integer-op-input-classes
|
|
|
|
"input-classes" word-prop
|
|
|
|
[ "Bug: integer-op-input-classes" throw ] unless* ;
|
|
|
|
|
|
|
|
: generic-variant ( op -- generic-op/f )
|
|
|
|
dup "derived-from" word-prop [ first ] [ ] ?if ;
|
|
|
|
|
|
|
|
: no-overflow-variant ( op -- fast-op )
|
|
|
|
H{
|
|
|
|
{ fixnum+ fixnum+fast }
|
|
|
|
{ fixnum- fixnum-fast }
|
|
|
|
{ fixnum* fixnum*fast }
|
|
|
|
{ fixnum-shift fixnum-shift-fast }
|
|
|
|
} at ;
|
|
|
|
|
|
|
|
: modular-variant ( op -- fast-op )
|
|
|
|
generic-variant dup H{
|
|
|
|
{ + fixnum+fast }
|
|
|
|
{ - fixnum-fast }
|
|
|
|
{ * fixnum*fast }
|
|
|
|
{ shift fixnum-shift-fast }
|
|
|
|
{ bitand fixnum-bitand }
|
|
|
|
{ bitor fixnum-bitor }
|
|
|
|
{ bitxor fixnum-bitxor }
|
|
|
|
{ bitnot fixnum-bitnot }
|
|
|
|
} at swap or ;
|
|
|
|
|
2008-08-18 21:49:03 -04:00
|
|
|
:: fixnum-integer-op ( a b fix-word big-word -- c )
|
|
|
|
b tag 0 eq? [
|
|
|
|
a b fix-word execute
|
2008-07-22 05:45:03 -04:00
|
|
|
] [
|
2008-08-18 21:49:03 -04:00
|
|
|
a fixnum>bignum b big-word execute
|
2008-07-22 05:45:03 -04:00
|
|
|
] if ; inline
|
|
|
|
|
2008-08-18 21:49:03 -04:00
|
|
|
:: integer-fixnum-op ( a b fix-word big-word -- c )
|
|
|
|
a tag 0 eq? [
|
|
|
|
a b fix-word execute
|
2008-07-22 05:45:03 -04:00
|
|
|
] [
|
2008-08-18 21:49:03 -04:00
|
|
|
a b fixnum>bignum big-word execute
|
2008-07-22 05:45:03 -04:00
|
|
|
] if ; inline
|
|
|
|
|
2008-08-18 21:49:03 -04:00
|
|
|
:: integer-integer-op ( a b fix-word big-word -- c )
|
|
|
|
b tag 0 eq? [
|
|
|
|
a b fix-word big-word integer-fixnum-op
|
2008-07-22 05:45:03 -04:00
|
|
|
] [
|
2008-08-18 21:49:03 -04:00
|
|
|
a dup tag 0 eq? [ fixnum>bignum ] when
|
|
|
|
b big-word execute
|
2008-07-22 05:45:03 -04:00
|
|
|
] if ; inline
|
|
|
|
|
|
|
|
: integer-op-combinator ( triple -- word )
|
|
|
|
[
|
|
|
|
[ second name>> % "-" % ]
|
|
|
|
[ third name>> % "-op" % ]
|
|
|
|
bi
|
|
|
|
] "" make "math.partial-dispatch" lookup ;
|
|
|
|
|
2008-07-30 16:37:40 -04:00
|
|
|
: integer-op-word ( triple -- word )
|
|
|
|
[ name>> ] map "-" join "math.partial-dispatch" create ;
|
2008-07-22 05:45:03 -04:00
|
|
|
|
2008-07-30 16:37:40 -04:00
|
|
|
: integer-op-quot ( triple fix-word big-word -- quot )
|
2008-07-22 05:45:03 -04:00
|
|
|
rot integer-op-combinator 1quotation 2curry ;
|
|
|
|
|
2008-07-30 16:37:40 -04:00
|
|
|
: define-integer-op-word ( triple fix-word big-word -- )
|
2008-07-22 05:45:03 -04:00
|
|
|
[
|
2008-07-30 16:37:40 -04:00
|
|
|
[ 2drop integer-op-word ] [ integer-op-quot ] 3bi
|
2008-07-22 05:45:03 -04:00
|
|
|
(( x y -- z )) define-declared
|
2008-07-30 16:37:40 -04:00
|
|
|
] [
|
|
|
|
2drop
|
|
|
|
[ integer-op-word ] keep
|
2008-07-22 05:45:03 -04:00
|
|
|
"derived-from" set-word-prop
|
|
|
|
] 3bi ;
|
|
|
|
|
2008-07-30 16:37:40 -04:00
|
|
|
: define-integer-op-words ( triples fix-word big-word -- )
|
2008-07-22 05:45:03 -04:00
|
|
|
[ define-integer-op-word ] 2curry each ;
|
|
|
|
|
|
|
|
: integer-op-triples ( word -- triples )
|
|
|
|
{
|
|
|
|
{ fixnum integer }
|
|
|
|
{ integer fixnum }
|
|
|
|
{ integer integer }
|
|
|
|
} swap [ prefix ] curry map ;
|
|
|
|
|
|
|
|
: define-integer-ops ( word fix-word big-word -- )
|
2008-09-12 19:08:38 -04:00
|
|
|
[
|
|
|
|
rot tuck
|
|
|
|
[ fixnum fixnum 3array "derived-from" set-word-prop ]
|
|
|
|
[ bignum bignum 3array "derived-from" set-word-prop ]
|
|
|
|
2bi*
|
|
|
|
] [
|
|
|
|
[ integer-op-triples ] 2dip
|
|
|
|
[ define-integer-op-words ]
|
|
|
|
[ 2drop [ dup integer-op-word ] { } map>assoc % ]
|
|
|
|
3bi
|
|
|
|
] 3bi ;
|
2008-07-22 05:45:03 -04:00
|
|
|
|
|
|
|
: define-math-ops ( op -- )
|
|
|
|
{ fixnum bignum float }
|
|
|
|
[ [ dup 3array ] [ swap method ] 2bi ] with { } map>assoc
|
|
|
|
[ nip ] assoc-filter
|
|
|
|
[ def>> peek ] assoc-map % ;
|
|
|
|
|
|
|
|
SYMBOL: math-ops
|
|
|
|
|
|
|
|
SYMBOL: fast-math-ops
|
|
|
|
|
|
|
|
: math-op ( word left right -- word' ? )
|
|
|
|
3array math-ops get at* ;
|
|
|
|
|
|
|
|
: math-method* ( word left right -- quot )
|
|
|
|
3dup math-op
|
|
|
|
[ >r 3drop r> 1quotation ] [ drop math-method ] if ;
|
|
|
|
|
|
|
|
: math-both-known? ( word left right -- ? )
|
|
|
|
3dup math-op
|
|
|
|
[ 2drop 2drop t ]
|
|
|
|
[ drop math-class-max swap specific-method >boolean ] if ;
|
|
|
|
|
|
|
|
: (derived-ops) ( word assoc -- words )
|
2008-09-12 09:18:44 -04:00
|
|
|
swap [ rot first eq? nip ] curry assoc-filter ;
|
2008-07-22 05:45:03 -04:00
|
|
|
|
|
|
|
: derived-ops ( word -- words )
|
2008-09-12 09:18:44 -04:00
|
|
|
[ 1array ] [ math-ops get (derived-ops) values ] bi append ;
|
2008-07-22 05:45:03 -04:00
|
|
|
|
|
|
|
: fast-derived-ops ( word -- words )
|
2008-09-12 09:18:44 -04:00
|
|
|
fast-math-ops get (derived-ops) values ;
|
2008-07-22 05:45:03 -04:00
|
|
|
|
|
|
|
: all-derived-ops ( word -- words )
|
|
|
|
[ derived-ops ] [ fast-derived-ops ] bi append ;
|
|
|
|
|
2008-09-12 09:18:44 -04:00
|
|
|
: integer-derived-ops ( word -- words )
|
|
|
|
[ math-ops get (derived-ops) ] [ fast-math-ops get (derived-ops) ] bi
|
|
|
|
[
|
|
|
|
[
|
|
|
|
drop
|
|
|
|
[ second integer class<= ]
|
|
|
|
[ third integer class<= ]
|
|
|
|
bi and
|
|
|
|
] assoc-filter values
|
|
|
|
] bi@ append ;
|
|
|
|
|
2008-07-22 05:45:03 -04:00
|
|
|
: each-derived-op ( word quot -- )
|
|
|
|
>r derived-ops r> each ; inline
|
|
|
|
|
|
|
|
: each-fast-derived-op ( word quot -- )
|
|
|
|
>r fast-derived-ops r> each ; inline
|
|
|
|
|
2008-09-12 19:08:38 -04:00
|
|
|
: each-integer-derived-op ( word quot -- )
|
|
|
|
>r integer-derived-ops r> each ; inline
|
|
|
|
|
2008-07-22 05:45:03 -04:00
|
|
|
[
|
|
|
|
[
|
|
|
|
\ + define-math-ops
|
|
|
|
\ - define-math-ops
|
|
|
|
\ * define-math-ops
|
|
|
|
\ shift define-math-ops
|
|
|
|
\ mod define-math-ops
|
|
|
|
\ /i define-math-ops
|
|
|
|
|
|
|
|
\ bitand define-math-ops
|
|
|
|
\ bitor define-math-ops
|
|
|
|
\ bitxor define-math-ops
|
|
|
|
|
|
|
|
\ < define-math-ops
|
|
|
|
\ <= define-math-ops
|
|
|
|
\ > define-math-ops
|
|
|
|
\ >= define-math-ops
|
|
|
|
\ number= define-math-ops
|
|
|
|
|
|
|
|
\ + \ fixnum+ \ bignum+ define-integer-ops
|
|
|
|
\ - \ fixnum- \ bignum- define-integer-ops
|
|
|
|
\ * \ fixnum* \ bignum* define-integer-ops
|
|
|
|
\ shift \ fixnum-shift \ bignum-shift define-integer-ops
|
|
|
|
\ mod \ fixnum-mod \ bignum-mod define-integer-ops
|
|
|
|
\ /i \ fixnum/i \ bignum/i define-integer-ops
|
|
|
|
|
|
|
|
\ bitand \ fixnum-bitand \ bignum-bitand define-integer-ops
|
|
|
|
\ bitor \ fixnum-bitor \ bignum-bitor define-integer-ops
|
|
|
|
\ bitxor \ fixnum-bitxor \ bignum-bitxor define-integer-ops
|
|
|
|
|
|
|
|
\ < \ fixnum< \ bignum< define-integer-ops
|
|
|
|
\ <= \ fixnum<= \ bignum<= define-integer-ops
|
|
|
|
\ > \ fixnum> \ bignum> define-integer-ops
|
|
|
|
\ >= \ fixnum>= \ bignum>= define-integer-ops
|
|
|
|
\ number= \ eq? \ bignum= define-integer-ops
|
|
|
|
] { } make >hashtable math-ops set-global
|
|
|
|
|
2008-07-30 16:37:40 -04:00
|
|
|
H{
|
|
|
|
{ { + fixnum fixnum } fixnum+fast }
|
|
|
|
{ { - fixnum fixnum } fixnum-fast }
|
|
|
|
{ { * fixnum fixnum } fixnum*fast }
|
|
|
|
{ { shift fixnum fixnum } fixnum-shift-fast }
|
|
|
|
} fast-math-ops set-global
|
2008-07-22 05:45:03 -04:00
|
|
|
] with-compilation-unit
|