1 ! Copyright (C) 2005, 2009 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: arrays generic hashtables kernel kernel.private math
4 namespaces sequences words quotations layouts combinators
5 sequences.private classes classes.builtin classes.algebra
6 definitions math.order math.private assocs ;
9 PREDICATE: math-class < class
10 dup null bootstrap-word eq? [
13 number bootstrap-word class<=
18 : bootstrap-words ( classes -- classes' )
19 [ bootstrap-word ] map ;
21 : math-precedence ( class -- pair )
23 { fixnum integer rational real number object } bootstrap-words
24 swap [ swap class<= ] curry find drop -1 or
26 { fixnum bignum ratio float complex object } bootstrap-words
27 swap [ class<= ] curry find drop -1 or
30 : (math-upgrade) ( max class -- quot )
31 dupd = [ drop [ ] ] [ "coercer" word-prop [ ] or ] if ;
35 : math-class-max ( class1 class2 -- class )
36 [ [ math-precedence ] bi@ after? ] most ;
38 : math-upgrade ( class1 class2 -- quot )
39 [ math-class-max ] 2keep
42 dup empty? [ [ dip ] curry [ ] like ] unless
46 ERROR: no-math-method left right generic ;
48 : default-math-method ( generic -- quot )
49 [ no-math-method ] curry [ ] like ;
53 : applicable-method ( generic class -- quot )
56 [ default-math-method ] ?if ;
60 : object-method ( generic -- quot )
61 object bootstrap-word applicable-method ;
63 : math-method ( word class1 class2 -- quot )
65 [ 2array [ declare ] curry nip ]
67 [ math-class-max over order min-class applicable-method ]
77 : make-math-method-table ( classes quot: ( class -- quot ) -- alist )
78 [ bootstrap-words ] dip
79 [ [ drop ] [ call ] 2bi ] curry { } map>assoc ; inline
81 : math-alist>quot ( alist -- quot )
82 [ generic-word get object-method ] dip alist>quot ;
84 : tag-dispatch-entry ( tag picker -- quot )
85 [ "type" word-prop 1quotation [ tag ] [ eq? ] surround ] dip prepend ;
87 : tag-dispatch ( picker alist -- alist' )
88 swap [ [ tag-dispatch-entry ] curry dip ] curry assoc-map math-alist>quot ;
90 : tuple-dispatch-entry ( class picker -- quot )
91 [ 1quotation [ { tuple } declare class ] [ eq? ] surround ] dip prepend ;
93 : tuple-dispatch ( picker alist -- alist' )
94 swap [ [ tuple-dispatch-entry ] curry dip ] curry assoc-map math-alist>quot ;
96 : math-dispatch-step ( picker quot: ( class -- quot ) -- quot )
97 [ [ { bignum float fixnum } ] dip make-math-method-table ]
98 [ [ { ratio complex } ] dip make-math-method-table tuple-dispatch ] 2bi
99 tuple swap 2array prefix tag-dispatch ; inline
103 SINGLETON: math-combination
105 M: math-combination make-default-method
106 drop default-math-method ;
108 M: math-combination perform-combination
109 drop dup generic-word [
111 [ fixnum bootstrap-word dup math-method ]
115 [ dup ] [ math-method ] with with math-dispatch-step
119 ] with math-dispatch-step
121 [ if ] 2curry [ 2dup both-fixnums? ] prepend
125 PREDICATE: math-generic < generic ( word -- ? )
126 "combination" word-prop math-combination? ;
128 M: math-generic definer drop \ MATH: f ;