]> gitweb.factorcode.org Git - factor.git/blob - core/generic/math/math.factor
8cdb645880ad3602adc00ccb7a3e3e8daf16d7f4
[factor.git] / core / generic / math / math.factor
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 ;
7 IN: generic.math
8
9 PREDICATE: math-class < class
10     dup null bootstrap-word eq? [
11         drop f
12     ] [
13         number bootstrap-word class<=
14     ] if ;
15
16 <PRIVATE
17
18 : bootstrap-words ( classes -- classes' )
19     [ bootstrap-word ] map ;
20
21 : math-precedence ( class -- pair )
22     [
23         { fixnum integer rational real number object } bootstrap-words
24         swap [ swap class<= ] curry find drop -1 or
25     ] [
26         { fixnum bignum ratio float complex object } bootstrap-words
27         swap [ class<= ] curry find drop -1 or
28     ] bi 2array ;
29
30 : (math-upgrade) ( max class -- quot )
31     dupd = [ drop [ ] ] [ "coercer" word-prop [ ] or ] if ;
32
33 PRIVATE>
34
35 : math-class-max ( class1 class2 -- class )
36     [ [ math-precedence ] bi@ after? ] most ;
37
38 : math-upgrade ( class1 class2 -- quot )
39     [ math-class-max ] 2keep
40     [
41         (math-upgrade)
42         dup empty? [ [ dip ] curry [ ] like ] unless
43     ] [ (math-upgrade) ]
44     bi-curry* bi append ;
45
46 ERROR: no-math-method left right generic ;
47
48 : default-math-method ( generic -- quot )
49     [ no-math-method ] curry [ ] like ;
50
51 <PRIVATE
52
53 : (math-method) ( generic class -- quot )
54     over ?lookup-method
55     [ 1quotation ]
56     [ default-math-method ] ?if ;
57
58 PRIVATE>
59
60 : object-method ( generic -- quot )
61     object bootstrap-word (math-method) ;
62
63 : math-method ( word class1 class2 -- quot )
64     2dup and [
65         [ 2array [ declare ] curry nip ]
66         [ math-upgrade nip ]
67         [ math-class-max over nearest-class (math-method) ]
68         3tri 3append
69     ] [
70         2drop object-method
71     ] if ;
72
73 <PRIVATE
74
75 SYMBOL: generic-word
76
77 : make-math-method-table ( classes quot: ( ... class -- ... quot ) -- alist )
78     [ bootstrap-words ] dip
79     [ [ drop ] [ call ] 2bi ] curry { } map>assoc ; inline
80
81 : math-alist>quot ( alist -- quot )
82     [ generic-word get object-method ] dip alist>quot ;
83
84 : tag-dispatch-entry ( tag picker -- quot )
85     [ "type" word-prop 1quotation [ tag ] [ eq? ] surround ] dip prepend ;
86
87 : tag-dispatch ( picker alist -- alist' )
88     swap [ [ tag-dispatch-entry ] curry dip ] curry assoc-map math-alist>quot ;
89
90 : tuple-dispatch-entry ( class picker -- quot )
91     [ 1quotation [ { tuple } declare class ] [ eq? ] surround ] dip prepend ;
92
93 : tuple-dispatch ( picker alist -- alist' )
94     swap [ [ tuple-dispatch-entry ] curry dip ] curry assoc-map math-alist>quot ;
95
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
100
101 PRIVATE>
102
103 SINGLETON: math-combination
104
105 M: math-combination make-default-method
106     drop default-math-method ;
107
108 M: math-combination perform-combination
109     drop dup generic-word [
110         dup
111         [ fixnum bootstrap-word dup math-method ]
112         [
113             [ over ] [
114                 dup math-class? [
115                     [ dup ] [ math-method ] with with math-dispatch-step
116                 ] [
117                     drop object-method
118                 ] if
119             ] with math-dispatch-step
120         ] bi
121         [ if ] 2curry [ 2dup both-fixnums? ] prepend
122         define
123     ] with-variable ;
124
125 PREDICATE: math-generic < generic ( word -- ? )
126     "combination" word-prop math-combination? ;
127
128 M: math-generic definer drop \ MATH: f ;