]> gitweb.factorcode.org Git - factor.git/blob - basis/prettyprint/backend/backend.factor
Removing more >r/r> usages
[factor.git] / basis / prettyprint / backend / backend.factor
1 ! Copyright (C) 2003, 2008 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors arrays byte-arrays byte-vectors generic
4 hashtables io assocs kernel math namespaces make sequences
5 strings sbufs io.styles vectors words prettyprint.config
6 prettyprint.sections quotations io io.files math.parser effects
7 classes.tuple math.order classes.tuple.private classes
8 combinators colors ;
9 IN: prettyprint.backend
10
11 GENERIC: pprint* ( obj -- )
12
13 M: effect pprint* effect>string "(" swap ")" 3append text ;
14
15 : ?effect-height ( word -- n )
16     stack-effect [ effect-height ] [ 0 ] if* ;
17
18 : ?start-group ( word -- )
19     ?effect-height 0 > [ start-group ] when ;
20
21 : ?end-group ( word -- )
22     ?effect-height 0 < [ end-group ] when ;
23
24 ! Atoms
25 : word-style ( word -- style )
26     dup "word-style" word-prop >hashtable [
27         [
28             [ presented set ]
29             [
30                 [ parsing-word? ] [ delimiter? ] [ t eq? ] tri or or
31                 [ bold font-style set ] when
32             ] bi
33         ] bind
34     ] keep ;
35
36 : word-name* ( word -- str )
37     name>> "( no name )" or ;
38
39 : pprint-word ( word -- )
40     dup record-vocab
41     dup word-name* swap word-style styled-text ;
42
43 : pprint-prefix ( word quot -- )
44     <block swap pprint-word call block> ; inline
45
46 M: word pprint*
47     dup parsing-word? [
48         \ POSTPONE: [ pprint-word ] pprint-prefix
49     ] [
50         {
51             [ "break-before" word-prop line-break ]
52             [ pprint-word ]
53             [ ?start-group ]
54             [ ?end-group ]
55             [ "break-after" word-prop line-break ]
56         } cleave
57     ] if ;
58
59 M: real pprint* number>string text ;
60
61 M: f pprint* drop \ f pprint-word ;
62
63 ! Strings
64 : ch>ascii-escape ( ch -- str )
65     H{
66         { CHAR: \a CHAR: a  }
67         { CHAR: \e CHAR: e  }
68         { CHAR: \n CHAR: n  }
69         { CHAR: \r CHAR: r  }
70         { CHAR: \t CHAR: t  }
71         { CHAR: \0 CHAR: 0  }
72         { CHAR: \\ CHAR: \\ }
73         { CHAR: \" CHAR: \" }
74     } at ;
75
76 : unparse-ch ( ch -- )
77     dup ch>ascii-escape [ "\\" % ] [ ] ?if , ;
78
79 : do-string-limit ( str -- trimmed )
80     string-limit? get [
81         dup length margin get > [
82             margin get 3 - head "..." append
83         ] when
84     ] when ;
85
86 : string-style ( obj -- hash )
87     [
88         presented set
89         T{ rgba f 0.3 0.3 0.3 1.0 } foreground set
90     ] H{ } make-assoc ;
91
92 : unparse-string ( str prefix suffix -- str )
93     [ [ % do-string-limit [ unparse-ch ] each ] dip % ] "" make ;
94
95 : pprint-string ( obj str prefix suffix -- )
96     unparse-string swap string-style styled-text ;
97
98 M: string pprint*
99     dup "\"" "\"" pprint-string ;
100
101 M: sbuf pprint*
102     dup "SBUF\" " "\"" pprint-string ;
103
104 M: pathname pprint*
105     dup string>> "P\" " "\"" pprint-string ;
106
107 ! Sequences
108 : nesting-limit? ( -- ? )
109     nesting-limit get dup [ pprinter-stack get length < ] when ;
110
111 : present-text ( str obj -- )
112     presented associate styled-text ;
113
114 : check-recursion ( obj quot -- )
115     nesting-limit? [
116         drop
117         "~" over class name>> "~" 3append
118         swap present-text
119     ] [
120         over recursion-check get memq? [
121             drop "~circularity~" swap present-text
122         ] [
123             over recursion-check get push
124             call
125             recursion-check get pop*
126         ] if
127     ] if ; inline
128
129 : tuple>assoc ( tuple -- assoc )
130     [ class all-slots ] [ tuple-slots ] bi zip
131     [ [ initial>> ] dip = not ] assoc-filter
132     [ [ name>> ] dip ] assoc-map ;
133
134 : pprint-slot-value ( name value -- )
135     <flow \ { pprint-word
136     [ text ] [ f <inset pprint* block> ] bi*
137     \ } pprint-word block> ;
138
139 M: tuple pprint*
140     boa-tuples? get [ call-next-method ] [
141         [
142             <flow
143             \ T{ pprint-word
144             dup class pprint-word
145             t <inset
146             tuple>assoc [ pprint-slot-value ] assoc-each
147             block>
148             \ } pprint-word
149             block>
150         ] check-recursion
151     ] if ;
152
153 : do-length-limit ( seq -- trimmed n/f )
154     length-limit get dup [
155         over length over [-]
156         dup zero? [ 2drop f ] [ [ head ] dip ] if
157     ] when ;
158
159 : pprint-elements ( seq -- )
160     do-length-limit
161     [ [ pprint* ] each ] dip
162     [ "~" swap number>string " more~" 3append text ] when* ;
163
164 GENERIC: pprint-delims ( obj -- start end )
165
166 M: quotation pprint-delims drop \ [ \ ] ;
167 M: curry pprint-delims drop \ [ \ ] ;
168 M: compose pprint-delims drop \ [ \ ] ;
169 M: array pprint-delims drop \ { \ } ;
170 M: byte-array pprint-delims drop \ B{ \ } ;
171 M: byte-vector pprint-delims drop \ BV{ \ } ;
172 M: vector pprint-delims drop \ V{ \ } ;
173 M: hashtable pprint-delims drop \ H{ \ } ;
174 M: tuple pprint-delims drop \ T{ \ } ;
175 M: wrapper pprint-delims drop \ W{ \ } ;
176 M: callstack pprint-delims drop \ CS{ \ } ;
177
178 GENERIC: >pprint-sequence ( obj -- seq )
179
180 M: object >pprint-sequence ;
181
182 M: vector >pprint-sequence ;
183 M: byte-vector >pprint-sequence ;
184 M: curry >pprint-sequence ;
185 M: compose >pprint-sequence ;
186 M: hashtable >pprint-sequence >alist ;
187 M: wrapper >pprint-sequence wrapped>> 1array ;
188 M: callstack >pprint-sequence callstack>array ;
189
190 M: tuple >pprint-sequence
191     [ class ] [ tuple-slots ] bi
192     [ 1array ] [ [ f 2array ] dip append ] if-empty ;
193
194 GENERIC: pprint-narrow? ( obj -- ? )
195
196 M: object pprint-narrow? drop f ;
197
198 M: array pprint-narrow? drop t ;
199 M: vector pprint-narrow? drop t ;
200 M: hashtable pprint-narrow? drop t ;
201 M: tuple pprint-narrow? drop t ;
202
203 : pprint-object ( obj -- )
204     [
205         <flow
206         dup pprint-delims [
207             pprint-word
208             dup pprint-narrow? <inset
209             >pprint-sequence pprint-elements
210             block>
211         ] dip pprint-word block>
212     ] check-recursion ;
213
214 M: object pprint* pprint-object ;
215 M: vector pprint* pprint-object ;
216 M: byte-vector pprint* pprint-object ;
217 M: hashtable pprint* pprint-object ;
218 M: curry pprint* pprint-object ;
219 M: compose pprint* pprint-object ;
220
221 M: wrapper pprint*
222     dup wrapped>> word? [
223         <block \ \ pprint-word wrapped>> pprint-word block>
224     ] [
225         pprint-object
226     ] if ;