factor/basis/prettyprint/backend/backend.factor

258 lines
7.2 KiB
Factor
Raw Normal View History

! Copyright (C) 2003, 2009 Slava Pestov.
2007-09-20 18:09:08 -04:00
! See http://factorcode.org/license.txt for BSD license.
USING: accessors arrays assocs byte-arrays byte-vectors classes
classes.tuple classes.tuple.private colors colors.constants
combinators continuations effects generic hashtables io
io.pathnames io.styles kernel make math math.order math.parser
namespaces prettyprint.config prettyprint.custom
prettyprint.sections prettyprint.stylesheet quotations sbufs
sequences strings vectors words words.symbol hash-sets
classes.maybe ;
2010-02-26 16:01:01 -05:00
FROM: sets => members ;
2007-09-20 18:09:08 -04:00
IN: prettyprint.backend
M: effect pprint* effect>string text ;
2008-06-08 16:32:55 -04:00
2007-09-20 18:09:08 -04:00
: ?effect-height ( word -- n )
stack-effect [ effect-height ] [ 0 ] if* ;
: ?start-group ( word -- )
?effect-height 0 > [ start-group ] when ;
: ?end-group ( word -- )
?effect-height 0 < [ end-group ] when ;
! Atoms
GENERIC: word-name* ( obj -- str )
M: maybe word-name*
class>> word-name* "maybe: " prepend ;
M: word word-name* ( word -- str )
[ name>> "( no name )" or ] [ record-vocab ] bi ;
2007-09-20 18:09:08 -04:00
: pprint-word ( word -- )
[ word-name* ] [ word-style ] bi styled-text ;
GENERIC: pprint-class ( obj -- )
M: maybe pprint-class pprint* ;
M: class pprint-class \ f or pprint-word ;
2007-09-20 18:09:08 -04:00
: pprint-prefix ( word quot -- )
<block swap pprint-word call block> ; inline
2009-04-06 03:57:39 -04:00
M: parsing-word pprint*
\ POSTPONE: [ pprint-word ] pprint-prefix ;
2007-09-20 18:09:08 -04:00
M: word pprint*
2009-04-06 03:57:39 -04:00
[ pprint-word ] [ ?start-group ] [ ?end-group ] tri ;
M: method pprint*
<block
[ \ M\ pprint-word "method-class" word-prop pprint-class ]
[ "method-generic" word-prop pprint-word ] bi
block> ;
2007-09-20 18:09:08 -04:00
M: real pprint*
number-base get {
{ 16 [ \ HEX: [ >hex text ] pprint-prefix ] }
{ 8 [ \ OCT: [ >oct text ] pprint-prefix ] }
{ 2 [ \ BIN: [ >bin text ] pprint-prefix ] }
[ drop number>string text ]
} case ;
2007-09-20 18:09:08 -04:00
M: float pprint*
dup fp-nan? [
\ NAN: [ fp-nan-payload >hex text ] pprint-prefix
] [
number-base get {
{ 16 [ \ HEX: [ >hex text ] pprint-prefix ] }
[ drop number>string text ]
} case
] if ;
2007-09-20 18:09:08 -04:00
M: f pprint* drop \ f pprint-word ;
: pprint-effect ( effect -- )
[ effect>string ] [ effect-style ] bi styled-text ;
2007-09-20 18:09:08 -04:00
! Strings
: ch>ascii-escape ( ch -- str )
H{
2008-02-11 15:19:47 -05:00
{ CHAR: \a CHAR: a }
2008-02-02 00:07:19 -05:00
{ CHAR: \e CHAR: e }
{ CHAR: \n CHAR: n }
{ CHAR: \r CHAR: r }
{ CHAR: \t CHAR: t }
{ CHAR: \0 CHAR: 0 }
{ CHAR: \\ CHAR: \\ }
{ CHAR: \" CHAR: \" }
2007-09-20 18:09:08 -04:00
} at ;
: unparse-ch ( ch -- )
2008-02-02 00:07:19 -05:00
dup ch>ascii-escape [ "\\" % ] [ ] ?if , ;
2007-09-20 18:09:08 -04:00
: do-string-limit ( str -- trimmed )
string-limit? get [
2007-09-20 18:09:08 -04:00
dup length margin get > [
margin get 3 - head "..." append
] when
] when ;
2007-12-03 19:19:18 -05:00
: unparse-string ( str prefix suffix -- str )
2008-12-03 09:46:16 -05:00
[ [ % do-string-limit [ unparse-ch ] each ] dip % ] "" make ;
2007-09-20 18:09:08 -04:00
2007-12-03 19:19:18 -05:00
: pprint-string ( obj str prefix suffix -- )
2007-09-20 18:09:08 -04:00
unparse-string swap string-style styled-text ;
2007-12-03 19:19:18 -05:00
M: string pprint*
dup "\"" "\"" pprint-string ;
2007-09-20 18:09:08 -04:00
2007-12-03 19:19:18 -05:00
M: sbuf pprint*
dup "SBUF\" " "\"" pprint-string ;
2007-09-20 18:09:08 -04:00
2007-12-03 19:19:18 -05:00
M: pathname pprint*
dup string>> "P\" " "\"" pprint-string ;
2007-09-20 18:09:08 -04:00
! Sequences
: nesting-limit? ( -- ? )
nesting-limit get dup [ pprinter-stack get length < ] when ;
: present-text ( str obj -- )
presented associate styled-text ;
: check-recursion ( obj quot -- )
nesting-limit? [
drop
2011-10-24 07:47:42 -04:00
[ class-of name>> "~" dup surround ] keep present-text
2007-09-20 18:09:08 -04:00
] [
over recursion-check get member-eq? [
2007-09-20 18:09:08 -04:00
drop "~circularity~" swap present-text
] [
over recursion-check get push
call
recursion-check get pop*
] if
] if ; inline
: filter-tuple-assoc ( slot,value -- name,value )
[ [ initial>> ] dip = not ] assoc-filter
[ [ name>> ] dip ] assoc-map ;
: tuple>assoc ( tuple -- assoc )
2011-10-24 07:47:42 -04:00
[ class-of all-slots ] [ tuple-slots ] bi zip filter-tuple-assoc ;
: pprint-slot-value ( name value -- )
<flow \ { pprint-word
[ text ] [ f <inset pprint* block> ] bi*
\ } pprint-word block> ;
: (pprint-tuple) ( opener class slots closer -- )
<flow {
[ pprint-word ]
[ pprint-word ]
[ t <inset [ pprint-slot-value ] assoc-each block> ]
[ pprint-word ]
} spread block> ;
: ?pprint-tuple ( tuple quot -- )
[ boa-tuples? get [ pprint-object ] ] dip [ check-recursion ] curry if ; inline
2009-05-03 19:32:35 -04:00
: pprint-tuple ( tuple -- )
2011-10-24 07:47:42 -04:00
[ [ \ T{ ] dip [ class-of ] [ tuple>assoc ] bi \ } (pprint-tuple) ] ?pprint-tuple ;
2009-05-03 19:32:35 -04:00
M: tuple pprint*
pprint-tuple ;
: recover-pprint ( try recovery -- )
pprinter-stack get clone
[ pprinter-stack set ] curry prepose recover ; inline
: pprint-c-object ( object content-quot pointer-quot -- )
[ c-object-pointers? get ] 2dip
[ nip ]
[ [ drop ] prepose [ recover-pprint ] 2curry ] 2bi if ; inline
2007-09-20 18:09:08 -04:00
: do-length-limit ( seq -- trimmed n/f )
length-limit get dup [
over length over [-]
dup zero? [ 2drop f ] [ [ head-slice ] dip ] if
2007-09-20 18:09:08 -04:00
] when ;
: pprint-elements ( seq -- )
2008-12-03 09:46:16 -05:00
do-length-limit
[ [ pprint* ] each ] dip
2009-11-12 04:01:09 -05:00
[ number>string "~" " more~" surround text ] when* ;
2007-09-20 18:09:08 -04:00
M: quotation pprint-delims drop \ [ \ ] ;
M: curry pprint-delims drop \ [ \ ] ;
M: compose pprint-delims drop \ [ \ ] ;
2007-09-20 18:09:08 -04:00
M: array pprint-delims drop \ { \ } ;
M: byte-array pprint-delims drop \ B{ \ } ;
M: byte-vector pprint-delims drop \ BV{ \ } ;
2007-09-20 18:09:08 -04:00
M: vector pprint-delims drop \ V{ \ } ;
M: hashtable pprint-delims drop \ H{ \ } ;
M: tuple pprint-delims drop \ T{ \ } ;
M: wrapper pprint-delims drop \ W{ \ } ;
M: callstack pprint-delims drop \ CS{ \ } ;
2010-02-26 11:01:57 -05:00
M: hash-set pprint-delims drop \ HS{ \ } ;
2007-09-20 18:09:08 -04:00
M: object >pprint-sequence ;
2008-01-30 00:13:47 -05:00
M: vector >pprint-sequence ;
M: byte-vector >pprint-sequence ;
M: callable >pprint-sequence ;
2007-09-20 18:09:08 -04:00
M: hashtable >pprint-sequence >alist ;
M: wrapper >pprint-sequence wrapped>> 1array ;
2007-09-20 18:09:08 -04:00
M: callstack >pprint-sequence callstack>array ;
2010-02-26 11:01:57 -05:00
M: hash-set >pprint-sequence members ;
2007-09-20 18:09:08 -04:00
2009-08-12 13:16:43 -04:00
: class-slot-sequence ( class slots -- sequence )
2008-09-08 18:52:11 -04:00
[ 1array ] [ [ f 2array ] dip append ] if-empty ;
2008-09-03 04:46:56 -04:00
2009-08-12 13:16:43 -04:00
M: tuple >pprint-sequence
2011-10-24 07:47:42 -04:00
[ class-of ] [ tuple-slots ] bi class-slot-sequence ;
2009-08-12 13:16:43 -04:00
2007-09-20 18:09:08 -04:00
M: object pprint-narrow? drop f ;
2009-05-16 09:56:09 -04:00
M: byte-vector pprint-narrow? drop f ;
2007-09-20 18:09:08 -04:00
M: array pprint-narrow? drop t ;
M: vector pprint-narrow? drop t ;
M: hashtable pprint-narrow? drop t ;
M: tuple pprint-narrow? drop t ;
2008-12-08 15:58:00 -05:00
M: object pprint-object ( obj -- )
2007-09-20 18:09:08 -04:00
[
<flow
2008-12-03 09:46:16 -05:00
dup pprint-delims [
pprint-word
dup pprint-narrow? <inset
>pprint-sequence pprint-elements
block>
] dip pprint-word block>
2007-09-20 18:09:08 -04:00
] check-recursion ;
2007-09-20 18:09:08 -04:00
M: object pprint* pprint-object ;
M: vector pprint* pprint-object ;
M: byte-vector pprint* pprint-object ;
: with-extra-nesting-level ( quot -- )
nesting-limit [ dup [ 1 + ] [ f ] if* ] change
[ nesting-limit set ] curry [ ] cleanup ; inline
M: hashtable pprint*
[ pprint-object ] with-extra-nesting-level ;
M: curry pprint* pprint-object ;
M: compose pprint* pprint-object ;
2010-02-26 11:01:57 -05:00
M: hash-set pprint* pprint-object ;
2007-09-20 18:09:08 -04:00
M: wrapper pprint*
2009-04-06 03:57:39 -04:00
{
{ [ dup wrapped>> method? ] [ wrapped>> pprint* ] }
2009-04-06 03:57:39 -04:00
{ [ dup wrapped>> word? ] [ <block \ \ pprint-word wrapped>> pprint-word block> ] }
[ pprint-object ]
} cond ;
M: maybe pprint*
<block \ maybe: pprint-word class>> pprint-word block> ;