| 
									
										
										
										
											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 |