2005-01-14 12:01:48 -05:00
|
|
|
! Copyright (C) 2003, 2005 Slava Pestov.
|
2005-02-05 22:51:41 -05:00
|
|
|
! See http://factor.sf.net/license.txt for BSD license.
|
2004-07-16 02:26:21 -04:00
|
|
|
IN: prettyprint
|
2005-08-21 01:17:37 -04:00
|
|
|
USING: alien generic hashtables io kernel lists math namespaces
|
|
|
|
parser sequences strings styles unparser vectors words ;
|
2004-07-16 02:26:21 -04:00
|
|
|
|
2005-08-21 01:17:37 -04:00
|
|
|
! TODO:
|
|
|
|
! - newline styles: forced, long output style, normal
|
|
|
|
! - long output flag, off with .
|
|
|
|
! - margin & indent calculation fix
|
|
|
|
! - out of memory when printing global namespace
|
|
|
|
! - formatting HTML code
|
|
|
|
! - limit strings
|
2005-08-21 14:25:05 -04:00
|
|
|
! - merge unparse into this
|
2005-08-21 01:17:37 -04:00
|
|
|
|
|
|
|
! State
|
|
|
|
SYMBOL: column
|
|
|
|
SYMBOL: indent
|
|
|
|
SYMBOL: last-newline?
|
|
|
|
SYMBOL: last-newline
|
2005-02-09 20:57:19 -05:00
|
|
|
SYMBOL: recursion-check
|
2005-08-21 01:17:37 -04:00
|
|
|
SYMBOL: line-count
|
|
|
|
SYMBOL: end-printing
|
|
|
|
|
|
|
|
! Configuration
|
|
|
|
SYMBOL: margin
|
|
|
|
SYMBOL: nesting-limit
|
|
|
|
SYMBOL: length-limit
|
|
|
|
SYMBOL: line-limit
|
|
|
|
|
|
|
|
global [
|
|
|
|
64 margin set
|
|
|
|
recursion-check off
|
|
|
|
0 column set
|
|
|
|
0 indent set
|
|
|
|
last-newline? off
|
|
|
|
0 last-newline set
|
|
|
|
0 line-count set
|
|
|
|
] bind
|
|
|
|
|
|
|
|
TUPLE: pprinter blocks block ;
|
|
|
|
|
|
|
|
GENERIC: pprint-section*
|
|
|
|
|
|
|
|
TUPLE: section start end ;
|
|
|
|
|
|
|
|
C: section ( length -- section )
|
|
|
|
>r column [ dup rot + dup ] change r>
|
|
|
|
[ set-section-end ] keep
|
|
|
|
[ set-section-start ] keep ;
|
|
|
|
|
|
|
|
: section-fits? ( section -- ? )
|
|
|
|
section-end last-newline get - margin get <= ;
|
|
|
|
|
|
|
|
: line-limit? ( -- ? )
|
|
|
|
line-limit get dup [ line-count get <= ] when ;
|
|
|
|
|
|
|
|
: fresh-line ( section -- )
|
|
|
|
section-start last-newline set
|
|
|
|
line-count [ 1 + ] change
|
|
|
|
line-limit? [ " ..." write end-printing get call ] when
|
|
|
|
terpri indent get CHAR: \s fill write ;
|
|
|
|
|
|
|
|
TUPLE: text string style ;
|
|
|
|
|
|
|
|
C: text ( string style -- section )
|
|
|
|
pick length <section> over set-delegate
|
|
|
|
[ set-text-style ] keep
|
|
|
|
[ set-text-string ] keep ;
|
|
|
|
|
|
|
|
M: text pprint-section*
|
|
|
|
dup text-string swap text-style format ;
|
|
|
|
|
|
|
|
TUPLE: block sections ;
|
|
|
|
|
|
|
|
C: block ( -- block )
|
|
|
|
0 <section> over set-delegate
|
|
|
|
{ } clone over set-block-sections ;
|
|
|
|
|
|
|
|
: add-section ( section stream -- )
|
|
|
|
pprinter-block block-sections push ;
|
|
|
|
|
|
|
|
: text ( string style -- )
|
|
|
|
<text> pprinter get add-section ;
|
|
|
|
|
|
|
|
: bl ( -- ) " " f text ;
|
|
|
|
|
|
|
|
: pprint-section ( section -- )
|
|
|
|
last-newline? get [
|
|
|
|
dup section-fits? [
|
|
|
|
" " write
|
|
|
|
] [
|
|
|
|
dup fresh-line
|
|
|
|
] ifte last-newline? off
|
|
|
|
] when pprint-section* ;
|
|
|
|
|
|
|
|
TUPLE: newline forced? ;
|
|
|
|
|
|
|
|
C: newline ( forced -- section )
|
|
|
|
1 <section> over set-delegate
|
|
|
|
[ set-newline-forced? ] keep ;
|
|
|
|
|
|
|
|
M: newline pprint-section*
|
|
|
|
dup newline-forced?
|
|
|
|
[ fresh-line ] [ drop last-newline? on ] ifte ;
|
|
|
|
|
|
|
|
: section-length ( section -- n )
|
|
|
|
dup section-end swap section-start - ;
|
|
|
|
|
|
|
|
: block-indent ( block -- indent )
|
|
|
|
block-sections first
|
|
|
|
dup block? [ drop 0 ] [ section-length 1 + ] ifte ;
|
2004-12-29 03:35:46 -05:00
|
|
|
|
2005-08-21 01:17:37 -04:00
|
|
|
M: block pprint-section* ( block -- )
|
|
|
|
indent get dup >r
|
|
|
|
over block-indent + indent set
|
|
|
|
block-sections [ pprint-section ] each
|
|
|
|
r> indent set ;
|
2004-12-12 23:49:44 -05:00
|
|
|
|
2005-08-21 01:17:37 -04:00
|
|
|
: <block ( -- )
|
|
|
|
pprinter get dup pprinter-block over pprinter-blocks push
|
|
|
|
<block> swap set-pprinter-block ;
|
2005-07-27 01:46:06 -04:00
|
|
|
|
2005-08-21 01:17:37 -04:00
|
|
|
: newline ( forced -- )
|
|
|
|
<newline> pprinter get add-section ;
|
2004-12-12 23:49:44 -05:00
|
|
|
|
2005-08-21 01:17:37 -04:00
|
|
|
: end-block ( block -- )
|
|
|
|
column get swap set-section-end ;
|
2004-11-25 21:08:09 -05:00
|
|
|
|
2005-08-21 01:17:37 -04:00
|
|
|
: pop-block ( pprinter -- )
|
|
|
|
dup pprinter-blocks pop swap set-pprinter-block ;
|
2005-02-09 20:57:19 -05:00
|
|
|
|
2005-08-21 01:17:37 -04:00
|
|
|
: block-empty? block-sections empty? ;
|
2005-02-09 20:57:19 -05:00
|
|
|
|
2005-08-21 01:17:37 -04:00
|
|
|
: block> ( -- )
|
|
|
|
pprinter get dup pprinter-block dup block-empty? [
|
|
|
|
drop pop-block
|
|
|
|
] [
|
|
|
|
dup end-block swap dup pop-block add-section
|
|
|
|
] ifte ;
|
|
|
|
|
|
|
|
C: pprinter ( -- stream )
|
|
|
|
{ } clone over set-pprinter-blocks
|
|
|
|
<block> over set-pprinter-block ;
|
|
|
|
|
|
|
|
: do-pprint ( pprinter -- )
|
|
|
|
[
|
|
|
|
end-printing set
|
|
|
|
dup pprinter-block pprint-section
|
|
|
|
] callcc0 drop ;
|
|
|
|
|
|
|
|
GENERIC: pprint* ( obj -- )
|
|
|
|
|
|
|
|
: vocab-style ( vocab -- style )
|
|
|
|
{{
|
|
|
|
[[ "syntax" [ [[ foreground [ 128 128 128 ] ]] ] ]]
|
|
|
|
[[ "kernel" [ [[ foreground [ 0 0 128 ] ]] ] ]]
|
|
|
|
[[ "sequences" [ [[ foreground [ 128 0 0 ] ]] ] ]]
|
|
|
|
[[ "math" [ [[ foreground [ 0 128 0 ] ]] ] ]]
|
|
|
|
[[ "math-internals" [ [[ foreground [ 192 0 0 ] ]] ] ]]
|
|
|
|
[[ "kernel-internals" [ [[ foreground [ 192 0 0 ] ]] ] ]]
|
|
|
|
[[ "io-internals" [ [[ foreground [ 192 0 0 ] ]] ] ]]
|
|
|
|
}} hash ;
|
2005-02-09 20:57:19 -05:00
|
|
|
|
2005-08-21 01:17:37 -04:00
|
|
|
: object-style ( obj -- style )
|
|
|
|
dup word? [ dup word-vocabulary vocab-style ] [ { } ] ifte
|
|
|
|
swap presented swons add ;
|
2005-02-09 20:57:19 -05:00
|
|
|
|
2005-08-21 01:17:37 -04:00
|
|
|
: pprint-object ( obj -- )
|
|
|
|
dup unparse swap object-style text ;
|
2005-04-13 20:44:06 -04:00
|
|
|
|
2005-08-21 01:17:37 -04:00
|
|
|
M: object pprint* ( obj -- )
|
|
|
|
pprint-object ;
|
2005-02-09 20:57:19 -05:00
|
|
|
|
2005-08-21 01:17:37 -04:00
|
|
|
M: word pprint* ( word -- )
|
|
|
|
dup parsing? [ \ POSTPONE: pprint-object bl ] when
|
|
|
|
pprint-object ;
|
2005-02-09 20:57:19 -05:00
|
|
|
|
2005-08-21 01:17:37 -04:00
|
|
|
: nesting-limit? ( -- ? )
|
|
|
|
nesting-limit get dup
|
|
|
|
[ pprinter get pprinter-blocks length < ] when ;
|
|
|
|
|
|
|
|
: check-recursion ( obj quot -- indent )
|
2005-02-09 20:57:19 -05:00
|
|
|
#! We detect circular structure.
|
2005-08-21 01:17:37 -04:00
|
|
|
nesting-limit? [
|
|
|
|
2drop "&" f text
|
2005-02-09 20:57:19 -05:00
|
|
|
] [
|
2005-08-07 00:00:57 -04:00
|
|
|
over recursion-check get memq? [
|
2005-08-21 01:17:37 -04:00
|
|
|
2drop "#" f text
|
2005-08-07 00:00:57 -04:00
|
|
|
] [
|
|
|
|
over recursion-check [ cons ] change
|
|
|
|
call
|
|
|
|
recursion-check [ cdr ] change
|
|
|
|
] ifte
|
2005-07-28 23:33:18 -04:00
|
|
|
] ifte ; inline
|
2005-02-09 20:57:19 -05:00
|
|
|
|
2005-08-21 01:17:37 -04:00
|
|
|
: length-limit? ( seq -- seq ? )
|
|
|
|
length-limit get dup
|
|
|
|
[ swap 2dup length < [ head t ] [ nip f ] ifte ]
|
|
|
|
[ drop f ] ifte ;
|
2005-01-13 19:49:47 -05:00
|
|
|
|
2005-08-21 01:17:37 -04:00
|
|
|
: pprint-elements ( seq -- )
|
|
|
|
length-limit? >r
|
|
|
|
[ pprint* f newline ] each
|
|
|
|
r> [ "... " f text ] when ;
|
|
|
|
|
|
|
|
: pprint-sequence ( seq start end -- )
|
|
|
|
<block swap pprint-object f newline
|
|
|
|
swap pprint-elements pprint-object block> ;
|
|
|
|
|
|
|
|
M: cons pprint* ( list -- )
|
2005-02-10 23:58:28 -05:00
|
|
|
[
|
2005-08-21 01:17:37 -04:00
|
|
|
dup list? [ \ [ \ ] ] [ uncons 2list \ [[ \ ]] ] ifte
|
|
|
|
pprint-sequence
|
2005-02-10 23:58:28 -05:00
|
|
|
] check-recursion ;
|
2004-07-19 16:10:18 -04:00
|
|
|
|
2005-08-21 01:17:37 -04:00
|
|
|
M: vector pprint* ( vector -- )
|
|
|
|
[ \ { \ } pprint-sequence ] check-recursion ;
|
2004-11-25 20:37:05 -05:00
|
|
|
|
2005-08-21 01:17:37 -04:00
|
|
|
M: hashtable pprint* ( hashtable -- )
|
|
|
|
[ hash>alist \ {{ \ }} pprint-sequence ] check-recursion ;
|
2004-11-25 20:37:05 -05:00
|
|
|
|
2005-08-21 01:17:37 -04:00
|
|
|
M: tuple pprint* ( tuple -- )
|
|
|
|
[ <mirror> \ << \ >> pprint-sequence ] check-recursion ;
|
2004-07-16 02:26:21 -04:00
|
|
|
|
2005-08-21 01:17:37 -04:00
|
|
|
M: alien pprint* ( alien -- )
|
|
|
|
\ ALIEN: pprint-object bl alien-address pprint-object ;
|
2005-04-10 18:58:30 -04:00
|
|
|
|
2005-08-21 01:17:37 -04:00
|
|
|
M: wrapper pprint* ( wrapper -- )
|
2005-08-03 23:56:28 -04:00
|
|
|
dup wrapped word? [
|
2005-08-21 01:17:37 -04:00
|
|
|
\ \ pprint-object bl wrapped pprint-object
|
2005-08-03 23:56:28 -04:00
|
|
|
] [
|
2005-08-21 01:17:37 -04:00
|
|
|
wrapped 1vector \ W[ \ ]W pprint-sequence
|
2005-08-03 23:56:28 -04:00
|
|
|
] ifte ;
|
|
|
|
|
2005-08-21 01:17:37 -04:00
|
|
|
: with-pprint ( quot -- )
|
2005-02-09 20:57:19 -05:00
|
|
|
[
|
2005-08-21 01:17:37 -04:00
|
|
|
<pprinter> pprinter set call pprinter get do-pprint
|
|
|
|
] with-scope ; inline
|
|
|
|
|
|
|
|
: pprint ( object -- )
|
|
|
|
[ pprint* ] with-pprint ;
|
|
|
|
|
|
|
|
: pprint>string ( object -- string )
|
|
|
|
[ pprint ] string-out ;
|
|
|
|
|
2005-08-21 14:40:12 -04:00
|
|
|
: . ( obj -- ) pprint terpri ;
|
2004-07-16 02:26:21 -04:00
|
|
|
|
2005-08-21 14:40:12 -04:00
|
|
|
: pprint-short ( object -- string )
|
|
|
|
[
|
|
|
|
1 line-limit set
|
|
|
|
5 length-limit set
|
|
|
|
2 nesting-limit set
|
|
|
|
pprint
|
|
|
|
] with-scope ;
|
|
|
|
|
|
|
|
: pprint>short-string ( object -- string )
|
|
|
|
[ pprint-short ] string-out ;
|
2004-07-21 19:26:41 -04:00
|
|
|
|
2005-05-02 00:18:34 -04:00
|
|
|
: [.] ( sequence -- )
|
2004-10-27 21:21:31 -04:00
|
|
|
#! Unparse each element on its own line.
|
2005-08-21 14:40:12 -04:00
|
|
|
[ [ pprint>short-string print ] each ] with-scope ;
|
2005-08-21 01:17:37 -04:00
|
|
|
|
|
|
|
: stack. reverse-slice [.] ;
|
2004-10-27 21:21:31 -04:00
|
|
|
|
2005-08-21 01:17:37 -04:00
|
|
|
: .s datastack stack. ;
|
|
|
|
: .r callstack stack. ;
|
2004-09-14 23:23:05 -04:00
|
|
|
|
|
|
|
! For integers only
|
|
|
|
: .b >bin print ;
|
|
|
|
: .o >oct print ;
|
|
|
|
: .h >hex print ;
|