factor/basis/prettyprint/backend/backend.factor

242 lines
6.9 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
2010-02-26 11:01:57 -05:00
sequences strings vectors words words.symbol hash-sets ;
2010-02-26 16:01:01 -05:00
FROM: sets => members ;
2007-09-20 18:09:08 -04:00
IN: prettyprint.backend
2008-12-06 19:58:45 -05:00
M: effect pprint* effect>string "(" ")" surround 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
: word-name* ( word -- str )
name>> "( no name )" or ;
2007-09-20 18:09:08 -04:00
: pprint-word ( word -- )
[ record-vocab ]
[ [ word-name* ] [ word-style ] bi styled-text ] bi ;
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*
[
[
[ "M\\ " % "method-class" word-prop word-name* % ]
[ " " % "method-generic" word-prop word-name* % ] bi
] "" make
] [ word-style ] bi styled-text ;
2007-09-20 18:09:08 -04:00
M: real pprint*
number-base get {
{ 16 [ \ HEX: [ 16 >base text ] pprint-prefix ] }
{ 8 [ \ OCT: [ 8 >base text ] pprint-prefix ] }
{ 2 [ \ BIN: [ 2 >base 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: [ 16 >base 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
2009-11-12 04:01:09 -05:00
[ class 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 )
[ class 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 -- )
[ [ \ T{ ] dip [ class ] [ 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
[ class ] [ 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 ;
M: hashtable pprint*
nesting-limit inc
[ pprint-object ] [ nesting-limit dec ] [ ] cleanup ;
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 ;