1 ! Copyright (C) 2009, 2011 Doug Coleman, John Benediktsson.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors arrays assocs combinators effects fry
4 generalizations kernel macros math math.order memoize sequences
5 sequences.generalizations sequences.private stack-checker
6 stack-checker.backend stack-checker.errors stack-checker.values
7 stack-checker.visitor words ;
10 GENERIC: infer-known* ( known -- effect )
12 : infer-known ( value -- effect )
13 known dup (literal-value?) [
14 (literal) [ infer-literal-quot ] with-infer drop
15 ] [ infer-known* ] if ;
17 IDENTITY-MEMO: inputs/outputs ( quot -- in out )
18 infer [ in>> ] [ out>> ] bi [ length ] bi@ ;
20 : inputs ( quot -- n ) inputs/outputs drop ; inline
22 : outputs ( quot -- n ) inputs/outputs nip ; inline
27 [ pop-d 1array #drop, ]
28 [ [ in>> ] [ out>> ] bi [ length apply-object ] bi@ ] bi*
30 \ inputs/outputs dup required-stack-effect apply-word/effect
32 [ [ input-parameter swap set-known ] [ push-d ] bi ] bi@
34 ] "special" set-word-prop
36 M: curried infer-known*
37 quot>> infer-known dup [
43 M: composed infer-known*
44 [ quot1>> ] [ quot2>> ] bi
46 2dup and [ compose-effects ] [ 2drop f ] if ;
48 M: declared-effect infer-known*
49 known>> infer-known* ;
51 M: input-parameter infer-known* drop f ;
53 M: object infer-known* drop f ;
55 : drop-inputs ( quot -- )
58 : drop-outputs ( quot -- )
59 [ call ] [ outputs ndrop ] bi ; inline
61 : keep-inputs ( quot -- )
62 [ ] [ inputs ] bi nkeep ; inline
64 : output>sequence ( quot exemplar -- seq )
65 [ [ call ] [ outputs ] bi ] dip nsequence ; inline
67 : output>array ( quot -- array )
68 { } output>sequence ; inline
70 : cleave>array ( obj quots -- array )
71 '[ _ cleave ] output>array ; inline
73 : cleave>sequence ( x seq exemplar -- array )
74 [ '[ _ cleave ] ] dip output>sequence ; inline
76 : input<sequence ( seq quot -- )
77 [ inputs firstn ] [ call ] bi ; inline
79 : input<sequence-unsafe ( seq quot -- )
80 [ inputs firstn-unsafe ] [ call ] bi ; inline
82 : reduce-outputs ( quot operation -- )
83 [ [ call ] [ [ drop ] compose outputs ] bi ] dip swap call-n ; inline
85 : sum-outputs ( quot -- n )
86 [ + ] reduce-outputs ; inline
88 : map-outputs ( quot mapper -- )
89 [ drop call ] [ swap outputs ] 2bi napply ; inline
91 MACRO: map-reduce-outputs ( quot mapper reducer -- quot )
92 [ '[ _ _ map-outputs ] ] dip '[ _ _ reduce-outputs ] ;
94 : append-outputs-as ( quot exemplar -- seq )
95 [ [ call ] [ outputs ] bi ] dip nappend-as ; inline
97 : append-outputs ( quot -- seq )
98 { } append-outputs-as ; inline
100 : preserving ( quot -- )
101 [ inputs ndup ] [ call ] bi ; inline
103 : dropping ( quot -- quot' )
104 inputs '[ _ ndrop ] ; inline
106 : nullary ( quot -- )
107 dropping call ; inline
109 : smart-if ( pred true false -- )
110 [ preserving ] 2dip if ; inline
112 : smart-when ( pred true -- )
113 [ ] smart-if ; inline
115 : smart-unless ( pred false -- )
116 [ [ ] ] dip smart-if ; inline
118 : smart-if* ( pred true false -- )
119 [ [ [ preserving ] [ dropping ] bi ] dip swap ] dip compose if ; inline
121 : smart-when* ( pred true -- )
122 [ ] smart-if* ; inline
124 : smart-unless* ( pred false -- )
125 [ [ ] ] dip smart-if* ; inline
127 : smart-apply ( quot n -- )
128 [ dup inputs ] dip mnapply ; inline
130 : smart-with ( param obj quot -- obj curry )
131 swapd dup inputs '[ [ _ -nrot ] dip call ] 2curry ; inline
133 MACRO: smart-reduce ( reduce-quots -- quot )
134 unzip [ [ ] like ] bi@ dup length dup '[
135 [ @ ] dip [ @ _ cleave-curry _ spread* ] each
138 MACRO: smart-map-reduce ( map-reduce-quots -- quot )
139 [ keys ] [ [ [ ] concat-as ] [ ] map-as ] bi dup length dup '[
140 [ first _ cleave ] keep
141 [ @ _ cleave-curry _ spread* ]
142 [ 1 ] 2dip (each) (each-integer)
145 MACRO: smart-2reduce ( 2reduce-quots -- quot )
146 unzip [ [ ] like ] bi@ dup length dup '[
148 [ @ _ [ cleave-curry ] [ cleave-curry ] bi _ spread* ] 2each
151 MACRO: smart-2map-reduce ( 2map-reduce-quots -- quot )
152 [ keys ] [ [ [ ] concat-as ] [ ] map-as ] bi dup length dup '[
153 [ [ first ] bi@ _ 2cleave ] 2keep
154 [ @ _ [ cleave-curry ] [ cleave-curry ] bi _ spread* ]
155 [ 1 ] 3dip (2each) (each-integer)