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