]> gitweb.factorcode.org Git - factor.git/blob - basis/prettyprint/prettyprint.factor
Move make to its own vocabulary, remove fry _ feature
[factor.git] / basis / prettyprint / prettyprint.factor
1 ! Copyright (C) 2003, 2008 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: arrays generic generic.standard assocs io kernel math
4 namespaces make sequences strings io.styles io.streams.string
5 vectors words prettyprint.backend prettyprint.sections
6 prettyprint.config sorting splitting grouping math.parser vocabs
7 definitions effects classes.builtin classes.tuple io.files
8 classes continuations hashtables classes.mixin classes.union
9 classes.intersection classes.predicate classes.singleton
10 combinators quotations sets accessors colors ;
11 IN: prettyprint
12
13 : make-pprint ( obj quot -- block in use )
14     [
15         0 position set
16         H{ } clone pprinter-use set
17         V{ } clone recursion-check set
18         V{ } clone pprinter-stack set
19         over <object
20         call
21         pprinter-block
22         pprinter-in get
23         pprinter-use get keys
24     ] with-scope ; inline
25
26 : with-pprint ( obj quot -- )
27     make-pprint 2drop do-pprint ; inline
28
29 : pprint-vocab ( vocab -- )
30     dup vocab present-text ;
31
32 : write-in ( vocab -- )
33     [ \ IN: pprint-word pprint-vocab ] with-pprint ;
34
35 : in. ( vocab -- )
36     [ write-in nl ] when* ;
37
38 : use. ( seq -- )
39     [
40         natural-sort [
41             \ USING: pprint-word
42             [ pprint-vocab ] each
43             \ ; pprint-word
44         ] with-pprint nl
45     ] unless-empty ;
46
47 : vocabs. ( in use -- )
48     dupd remove [ { "syntax" "scratchpad" } member? not ] filter
49     use. in. ;
50
51 : with-use ( obj quot -- )
52     make-pprint vocabs. do-pprint ; inline
53
54 : with-in ( obj quot -- )
55     make-pprint drop [ write-in bl ] when* do-pprint ; inline
56
57 : pprint ( obj -- ) [ pprint* ] with-pprint ;
58
59 : . ( obj -- ) pprint nl ;
60
61 : pprint-use ( obj -- ) [ pprint* ] with-use ;
62
63 : unparse ( obj -- str ) [ pprint ] with-string-writer ;
64
65 : unparse-use ( obj -- str ) [ pprint-use ] with-string-writer ;
66
67 : pprint-short ( obj -- )
68     H{
69        { line-limit 1 }
70        { length-limit 15 }
71        { nesting-limit 2 }
72        { string-limit? t }
73        { boa-tuples? t }
74     } clone [ pprint ] bind ;
75
76 : unparse-short ( obj -- str )
77     [ pprint-short ] with-string-writer ;
78
79 : short. ( obj -- ) pprint-short nl ;
80
81 : .b ( n -- ) >bin print ;
82 : .o ( n -- ) >oct print ;
83 : .h ( n -- ) >hex print ;
84
85 : stack. ( seq -- ) [ short. ] each ;
86
87 : .s ( -- ) datastack stack. ;
88 : .r ( -- ) retainstack stack. ;
89
90 <PRIVATE
91
92 SYMBOL: ->
93
94 \ ->
95 { { foreground T{ rgba f 1 1 1 1 } } { background T{ rgba f 0 0 0 1 } } }
96 "word-style" set-word-prop
97
98 : remove-step-into ( word -- )
99     building get [ nip pop wrapped>> ] unless-empty , ;
100
101 : (remove-breakpoints) ( quot -- newquot )
102     [
103         [
104             {
105                 { [ dup word? not ] [ , ] }
106                 { [ dup "break?" word-prop ] [ drop ] }
107                 { [ dup "step-into?" word-prop ] [ remove-step-into ] }
108                 [ , ]
109             } cond
110         ] each
111     ] [ ] make ;
112
113 : remove-breakpoints ( quot pos -- quot' )
114     over quotation? [
115         1+ cut [ (remove-breakpoints) ] bi@
116         [ -> ] swap 3append
117     ] [
118         drop
119     ] if ;
120
121 PRIVATE>
122
123 : callstack. ( callstack -- )
124     callstack>array 2 <groups> [
125         remove-breakpoints
126         3 nesting-limit [ . ] with-variable
127     ] assoc-each ;
128
129 : .c ( -- ) callstack callstack. ;
130
131 : pprint-cell ( obj -- ) [ pprint ] with-cell ;
132
133 GENERIC: see ( defspec -- )
134
135 : comment. ( string -- )
136     [ H{ { font-style italic } } styled-text ] when* ;
137
138 : seeing-word ( word -- )
139     vocabulary>> pprinter-in set ;
140
141 : definer. ( defspec -- )
142     definer drop pprint-word ;
143
144 : stack-effect. ( word -- )
145     [ [ parsing-word? ] [ symbol? ] bi or not ] [ stack-effect ] bi and
146     [ effect>string comment. ] when* ;
147
148 : word-synopsis ( word -- )
149     {
150         [ seeing-word ]
151         [ definer. ]
152         [ pprint-word ]
153         [ stack-effect. ] 
154     } cleave ;
155
156 M: word synopsis* word-synopsis ;
157
158 M: simple-generic synopsis* word-synopsis ;
159
160 M: standard-generic synopsis*
161     {
162         [ definer. ]
163         [ seeing-word ]
164         [ pprint-word ]
165         [ dispatch# pprint* ]
166         [ stack-effect. ]
167     } cleave ;
168
169 M: hook-generic synopsis*
170     {
171         [ definer. ]
172         [ seeing-word ]
173         [ pprint-word ]
174         [ "combination" word-prop var>> pprint* ]
175         [ stack-effect. ]
176     } cleave ;
177
178 M: method-spec synopsis*
179     first2 method synopsis* ;
180
181 M: method-body synopsis*
182     [ definer. ]
183     [ "method-class" word-prop pprint-word ]
184     [ "method-generic" word-prop pprint-word ] tri ;
185
186 M: mixin-instance synopsis*
187     [ definer. ]
188     [ class>> pprint-word ]
189     [ mixin>> pprint-word ] tri ;
190
191 M: pathname synopsis* pprint* ;
192
193 : synopsis ( defspec -- str )
194     [
195         0 margin set
196         1 line-limit set
197         [ synopsis* ] with-in
198     ] with-string-writer ;
199
200 : synopsis-alist ( definitions -- alist )
201     [ dup synopsis swap ] { } map>assoc ;
202
203 : definitions. ( alist -- )
204     [ write-object nl ] assoc-each ;
205
206 : sorted-definitions. ( definitions -- )
207     synopsis-alist sort-keys definitions. ;
208
209 GENERIC: declarations. ( obj -- )
210
211 M: object declarations. drop ;
212
213 : declaration. ( word prop -- )
214     tuck name>> word-prop [ pprint-word ] [ drop ] if ;
215
216 M: word declarations.
217     {
218         POSTPONE: parsing
219         POSTPONE: delimiter
220         POSTPONE: inline
221         POSTPONE: recursive
222         POSTPONE: foldable
223         POSTPONE: flushable
224     } [ declaration. ] with each ;
225
226 : pprint-; ( -- ) \ ; pprint-word ;
227
228 : (see) ( spec -- )
229     <colon dup synopsis*
230     <block dup definition pprint-elements block>
231     dup definer nip [ pprint-word ] when* declarations.
232     block> ;
233
234 M: object see
235     [ (see) ] with-use nl ;
236
237 GENERIC: see-class* ( word -- )
238
239 M: union-class see-class*
240     <colon \ UNION: pprint-word
241     dup pprint-word
242     members pprint-elements pprint-; block> ;
243
244 M: intersection-class see-class*
245     <colon \ INTERSECTION: pprint-word
246     dup pprint-word
247     participants pprint-elements pprint-; block> ;
248
249 M: mixin-class see-class*
250     <block \ MIXIN: pprint-word
251     dup pprint-word <block
252     dup members [
253         hard line-break
254         \ INSTANCE: pprint-word pprint-word pprint-word
255     ] with each block> block> ;
256
257 M: predicate-class see-class*
258     <colon \ PREDICATE: pprint-word
259     dup pprint-word
260     "<" text
261     dup superclass pprint-word
262     <block
263     "predicate-definition" word-prop pprint-elements
264     pprint-; block> block> ;
265
266 M: singleton-class see-class* ( class -- )
267     \ SINGLETON: pprint-word pprint-word ;
268
269 GENERIC: pprint-slot-name ( object -- )
270
271 M: string pprint-slot-name text ;
272
273 M: array pprint-slot-name
274     <flow \ { pprint-word
275     f <inset unclip text pprint-elements block>
276     \ } pprint-word block> ;
277
278 : unparse-slot ( slot-spec -- array )
279     [
280         dup name>> ,
281         dup class>> object eq? [
282             dup class>> ,
283             initial: ,
284             dup initial>> ,
285         ] unless
286         dup read-only>> [
287             read-only ,
288         ] when
289         drop
290     ] { } make ;
291
292 : pprint-slot ( slot-spec -- )
293     unparse-slot
294     dup length 1 = [ first ] when
295     pprint-slot-name ;
296
297 M: tuple-class see-class*
298     <colon \ TUPLE: pprint-word
299     dup pprint-word
300     dup superclass tuple eq? [
301         "<" text dup superclass pprint-word
302     ] unless
303     <block "slots" word-prop [ pprint-slot ] each block>
304     pprint-; block> ;
305
306 M: word see-class* drop ;
307
308 M: builtin-class see-class*
309     drop "! Built-in class" comment. ;
310
311 : see-class ( class -- )
312     dup class? [
313         [
314             dup seeing-word dup see-class*
315         ] with-use nl
316     ] when drop ;
317
318 M: word see
319     dup see-class
320     dup class? over symbol? not and [
321         nl
322     ] when
323     dup class? over symbol? and not [
324         [ dup (see) ] with-use nl
325     ] when
326     drop ;
327
328 : see-all ( seq -- )
329     natural-sort [ nl ] [ see ] interleave ;
330
331 : (see-implementors) ( class -- seq )
332     dup implementors [ method ] with map natural-sort ;
333
334 : (see-methods) ( generic -- seq )
335     "methods" word-prop values natural-sort ;
336
337 : see-methods ( word -- )
338     [
339         dup class? [ dup (see-implementors) % ] when
340         dup generic? [ dup (see-methods) % ] when
341         drop
342     ] { } make prune see-all ;