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-09-11 20:46:55 -04:00
|
|
|
USING: alien arrays generic hashtables io kernel lists math
|
|
|
|
namespaces parser sequences strings styles vectors words ;
|
2004-07-16 02:26:21 -04:00
|
|
|
|
2005-08-21 01:17:37 -04:00
|
|
|
! State
|
|
|
|
SYMBOL: column
|
|
|
|
SYMBOL: indent
|
|
|
|
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
|
2005-08-21 20:50:14 -04:00
|
|
|
SYMBOL: tab-size
|
2005-08-21 01:17:37 -04:00
|
|
|
SYMBOL: margin
|
|
|
|
SYMBOL: nesting-limit
|
|
|
|
SYMBOL: length-limit
|
|
|
|
SYMBOL: line-limit
|
2005-08-21 20:50:14 -04:00
|
|
|
SYMBOL: string-limit
|
2005-08-21 01:17:37 -04:00
|
|
|
|
|
|
|
global [
|
2005-08-21 20:50:14 -04:00
|
|
|
4 tab-size set
|
2005-08-21 01:17:37 -04:00
|
|
|
64 margin set
|
|
|
|
recursion-check off
|
|
|
|
0 column set
|
|
|
|
0 indent set
|
|
|
|
0 last-newline set
|
|
|
|
0 line-count set
|
2005-08-21 20:50:14 -04:00
|
|
|
string-limit off
|
2005-08-21 01:17:37 -04:00
|
|
|
] bind
|
|
|
|
|
2005-08-21 20:50:14 -04:00
|
|
|
TUPLE: pprinter stack ;
|
2005-08-21 01:17:37 -04:00
|
|
|
|
|
|
|
GENERIC: pprint-section*
|
|
|
|
|
2005-08-21 20:50:14 -04:00
|
|
|
TUPLE: section start end nl-after? indent ;
|
2005-08-21 01:17:37 -04:00
|
|
|
|
|
|
|
C: section ( length -- section )
|
|
|
|
>r column [ dup rot + dup ] change r>
|
|
|
|
[ set-section-end ] keep
|
2005-08-21 20:50:14 -04:00
|
|
|
[ set-section-start ] keep
|
|
|
|
0 over set-section-indent ;
|
2005-08-21 01:17:37 -04:00
|
|
|
|
|
|
|
: section-fits? ( section -- ? )
|
2005-08-21 20:50:14 -04:00
|
|
|
section-end last-newline get - indent get + margin get <= ;
|
2005-08-21 01:17:37 -04:00
|
|
|
|
|
|
|
: line-limit? ( -- ? )
|
|
|
|
line-limit get dup [ line-count get <= ] when ;
|
|
|
|
|
2005-08-21 20:50:14 -04:00
|
|
|
: do-indent indent get CHAR: \s fill write ;
|
|
|
|
|
|
|
|
: fresh-line ( n -- )
|
2005-08-29 01:00:55 -04:00
|
|
|
#! n is current column position.
|
2005-08-31 21:06:13 -04:00
|
|
|
dup last-newline get = [
|
|
|
|
drop
|
|
|
|
] [
|
|
|
|
last-newline set
|
|
|
|
line-count inc
|
2005-09-14 00:37:50 -04:00
|
|
|
line-limit? [ "..." write end-printing get continue ] when
|
2005-08-31 21:06:13 -04:00
|
|
|
"\n" write do-indent
|
2005-09-24 15:21:17 -04:00
|
|
|
] if ;
|
2005-08-21 01:17:37 -04:00
|
|
|
|
|
|
|
TUPLE: text string style ;
|
|
|
|
|
|
|
|
C: text ( string style -- section )
|
2005-09-16 22:47:28 -04:00
|
|
|
pick length 1+ <section> over set-delegate
|
2005-08-21 01:17:37 -04:00
|
|
|
[ set-text-style ] keep
|
|
|
|
[ set-text-string ] keep ;
|
|
|
|
|
|
|
|
M: text pprint-section*
|
2005-09-01 01:20:43 -04:00
|
|
|
dup text-string swap text-style format ;
|
2005-08-21 01:17:37 -04:00
|
|
|
|
|
|
|
TUPLE: block sections ;
|
|
|
|
|
|
|
|
C: block ( -- block )
|
|
|
|
0 <section> over set-delegate
|
2005-08-21 20:50:14 -04:00
|
|
|
{ } clone over set-block-sections
|
|
|
|
t over set-section-nl-after?
|
|
|
|
tab-size get over set-section-indent ;
|
|
|
|
|
|
|
|
: pprinter-block pprinter-stack peek ;
|
|
|
|
|
|
|
|
: block-empty? ( section -- ? )
|
2005-09-24 15:21:17 -04:00
|
|
|
dup block? [ block-sections empty? ] [ drop f ] if ;
|
2005-08-21 01:17:37 -04:00
|
|
|
|
|
|
|
: add-section ( section stream -- )
|
2005-08-21 20:50:14 -04:00
|
|
|
over block-empty? [
|
|
|
|
2drop
|
|
|
|
] [
|
|
|
|
pprinter-block block-sections push
|
2005-09-24 15:21:17 -04:00
|
|
|
] if ;
|
2005-08-21 01:17:37 -04:00
|
|
|
|
2005-08-29 01:00:55 -04:00
|
|
|
: text ( string style -- ) <text> pprinter get add-section ;
|
2005-08-21 01:17:37 -04:00
|
|
|
|
2005-08-21 20:50:14 -04:00
|
|
|
: <indent ( section -- ) section-indent indent [ + ] change ;
|
|
|
|
|
|
|
|
: indent> ( section -- ) section-indent indent [ swap - ] change ;
|
|
|
|
|
|
|
|
: inset-section ( section -- )
|
|
|
|
dup <indent
|
|
|
|
dup section-start fresh-line dup pprint-section*
|
|
|
|
dup indent>
|
|
|
|
dup section-nl-after?
|
2005-09-24 15:21:17 -04:00
|
|
|
[ section-end fresh-line ] [ drop ] if ;
|
2005-08-21 20:50:14 -04:00
|
|
|
|
2005-08-21 01:17:37 -04:00
|
|
|
: pprint-section ( section -- )
|
2005-08-31 21:06:13 -04:00
|
|
|
dup section-fits?
|
2005-09-24 15:21:17 -04:00
|
|
|
[ pprint-section* ] [ inset-section ] if ;
|
2005-08-21 01:17:37 -04:00
|
|
|
|
2005-08-29 01:00:55 -04:00
|
|
|
TUPLE: newline ;
|
2005-08-21 01:17:37 -04:00
|
|
|
|
2005-08-29 01:00:55 -04:00
|
|
|
C: newline ( -- section )
|
|
|
|
0 <section> over set-delegate ;
|
2005-08-21 01:17:37 -04:00
|
|
|
|
2005-08-29 01:00:55 -04:00
|
|
|
M: newline pprint-section* ( newline -- )
|
2005-08-31 21:06:13 -04:00
|
|
|
section-start fresh-line ;
|
2004-12-29 03:35:46 -05:00
|
|
|
|
2005-09-01 02:01:51 -04:00
|
|
|
: advance ( section -- )
|
2005-09-01 02:15:29 -04:00
|
|
|
dup newline? [
|
|
|
|
drop
|
|
|
|
] [
|
|
|
|
section-start last-newline get = [ " " write ] unless
|
2005-09-24 15:21:17 -04:00
|
|
|
] if ;
|
2005-09-01 02:01:51 -04:00
|
|
|
|
2005-08-21 01:17:37 -04:00
|
|
|
M: block pprint-section* ( block -- )
|
2005-09-01 01:20:43 -04:00
|
|
|
f swap block-sections [
|
2005-09-01 02:01:51 -04:00
|
|
|
over [ dup advance ] when pprint-section drop t
|
2005-09-01 01:20:43 -04:00
|
|
|
] each drop ;
|
2005-07-27 01:46:06 -04:00
|
|
|
|
2005-08-21 20:50:14 -04:00
|
|
|
: <block ( -- ) <block> pprinter get pprinter-stack push ;
|
2004-12-12 23:49:44 -05:00
|
|
|
|
2005-08-29 01:00:55 -04:00
|
|
|
: newline ( -- ) <newline> pprinter get add-section ;
|
2004-11-25 21:08:09 -05:00
|
|
|
|
2005-08-21 20:50:14 -04:00
|
|
|
: end-block ( block -- ) column get swap set-section-end ;
|
2005-02-09 20:57:19 -05:00
|
|
|
|
2005-08-21 20:50:14 -04:00
|
|
|
: pop-block ( pprinter -- ) pprinter-stack pop drop ;
|
2005-02-09 20:57:19 -05:00
|
|
|
|
2005-08-29 01:00:55 -04:00
|
|
|
: (block>) ( -- )
|
2005-08-21 20:50:14 -04:00
|
|
|
pprinter get dup pprinter-block
|
|
|
|
dup end-block swap dup pop-block add-section ;
|
|
|
|
|
2005-08-29 01:00:55 -04:00
|
|
|
: last-block? ( -- ? )
|
|
|
|
pprinter get pprinter-stack length 1 = ;
|
|
|
|
|
|
|
|
: block> ( -- )
|
|
|
|
#! Protect against malformed <block ... block> forms.
|
|
|
|
last-block? [ (block>) ] unless ;
|
|
|
|
|
2005-08-21 20:50:14 -04:00
|
|
|
: block; ( -- )
|
|
|
|
pprinter get pprinter-block f swap set-section-nl-after?
|
|
|
|
block> ;
|
2005-08-21 01:17:37 -04:00
|
|
|
|
2005-08-29 01:00:55 -04:00
|
|
|
: end-blocks ( -- ) last-block? [ (block>) end-blocks ] unless ;
|
|
|
|
|
2005-08-21 01:17:37 -04:00
|
|
|
C: pprinter ( -- stream )
|
2005-09-11 20:46:55 -04:00
|
|
|
<block> 1 <vector> [ push ] keep over set-pprinter-stack ;
|
2005-08-21 01:17:37 -04:00
|
|
|
|
|
|
|
: do-pprint ( pprinter -- )
|
|
|
|
[
|
|
|
|
end-printing set
|
|
|
|
dup pprinter-block pprint-section
|
2005-09-18 01:37:28 -04:00
|
|
|
] callcc0 drop ;
|
2005-08-21 01:17:37 -04:00
|
|
|
|
|
|
|
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 20:50:14 -04:00
|
|
|
: word-style ( word -- style )
|
|
|
|
dup word-vocabulary vocab-style swap presented swons add ;
|
2005-02-09 20:57:19 -05:00
|
|
|
|
2005-08-21 23:35:50 -04:00
|
|
|
: pprint-word ( obj -- )
|
|
|
|
dup word-name [ "( unnamed )" ] unless*
|
|
|
|
swap word-style text ;
|
2005-04-13 20:44:06 -04:00
|
|
|
|
2005-08-21 01:17:37 -04:00
|
|
|
M: object pprint* ( obj -- )
|
2005-08-21 20:50:14 -04:00
|
|
|
"( unprintable object: " swap class word-name " )" append3
|
|
|
|
f text ;
|
|
|
|
|
2005-08-29 01:00:55 -04:00
|
|
|
M: real pprint* ( obj -- ) number>string f text ;
|
2005-08-21 20:50:14 -04:00
|
|
|
|
|
|
|
: ch>ascii-escape ( ch -- esc )
|
2005-08-23 23:28:54 -04:00
|
|
|
{{
|
2005-08-21 20:50:14 -04:00
|
|
|
[[ CHAR: \e "\\e" ]]
|
|
|
|
[[ CHAR: \n "\\n" ]]
|
|
|
|
[[ CHAR: \r "\\r" ]]
|
|
|
|
[[ CHAR: \t "\\t" ]]
|
|
|
|
[[ CHAR: \0 "\\0" ]]
|
|
|
|
[[ CHAR: \\ "\\\\" ]]
|
|
|
|
[[ CHAR: \" "\\\"" ]]
|
2005-08-23 23:28:54 -04:00
|
|
|
}} hash ;
|
2005-08-21 20:50:14 -04:00
|
|
|
|
|
|
|
: ch>unicode-escape ( ch -- esc )
|
|
|
|
>hex 4 CHAR: 0 pad-left "\\u" swap append ;
|
|
|
|
|
|
|
|
: unparse-ch ( ch -- ch/str )
|
|
|
|
dup quotable? [
|
|
|
|
,
|
|
|
|
] [
|
2005-09-24 15:21:17 -04:00
|
|
|
dup ch>ascii-escape [ ] [ ch>unicode-escape ] ?if %
|
|
|
|
] if ;
|
2005-08-21 20:50:14 -04:00
|
|
|
|
|
|
|
: do-string-limit ( string -- string )
|
|
|
|
string-limit get [
|
|
|
|
dup length margin get > [
|
|
|
|
margin get 3 - swap head "..." append
|
|
|
|
] when
|
|
|
|
] when ;
|
|
|
|
|
|
|
|
: pprint-string ( string prefix -- )
|
2005-08-25 15:27:38 -04:00
|
|
|
[ % [ unparse-ch ] each CHAR: " , ] "" make
|
2005-08-21 20:50:14 -04:00
|
|
|
do-string-limit f text ;
|
|
|
|
|
|
|
|
M: string pprint* ( str -- str ) "\"" pprint-string ;
|
|
|
|
|
|
|
|
M: sbuf pprint* ( str -- str ) "SBUF\" " pprint-string ;
|
2005-02-09 20:57:19 -05:00
|
|
|
|
2005-08-21 01:17:37 -04:00
|
|
|
M: word pprint* ( word -- )
|
2005-09-22 16:21:36 -04:00
|
|
|
dup "pprint-close" word-prop [ block> ] when
|
2005-08-29 01:00:55 -04:00
|
|
|
dup pprint-word
|
2005-09-22 16:21:36 -04:00
|
|
|
"pprint-open" word-prop [ <block ] when ;
|
2005-08-21 20:50:14 -04:00
|
|
|
|
|
|
|
M: f pprint* drop "f" f text ;
|
|
|
|
|
|
|
|
M: dll pprint* ( obj -- str ) dll-path "DLL\" " pprint-string ;
|
2005-02-09 20:57:19 -05:00
|
|
|
|
2005-08-21 01:17:37 -04:00
|
|
|
: nesting-limit? ( -- ? )
|
|
|
|
nesting-limit get dup
|
2005-08-21 20:50:14 -04:00
|
|
|
[ pprinter get pprinter-stack length < ] when ;
|
2005-08-21 01:17:37 -04:00
|
|
|
|
|
|
|
: 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? [
|
2005-08-24 19:25:12 -04:00
|
|
|
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-24 19:25:12 -04:00
|
|
|
2drop "&" f text
|
2005-08-07 00:00:57 -04:00
|
|
|
] [
|
|
|
|
over recursion-check [ cons ] change
|
|
|
|
call
|
|
|
|
recursion-check [ cdr ] change
|
2005-09-24 15:21:17 -04:00
|
|
|
] if
|
|
|
|
] if ; 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
|
2005-09-24 15:21:17 -04:00
|
|
|
[ swap 2dup length < [ head t ] [ nip f ] if ]
|
|
|
|
[ drop f ] if ;
|
2005-01-13 19:49:47 -05:00
|
|
|
|
2005-08-29 01:00:55 -04:00
|
|
|
: pprint-element ( object -- )
|
|
|
|
dup parsing? [ \ POSTPONE: pprint-word ] when pprint* ;
|
|
|
|
|
2005-08-21 01:17:37 -04:00
|
|
|
: pprint-elements ( seq -- )
|
|
|
|
length-limit? >r
|
2005-08-29 01:00:55 -04:00
|
|
|
[ pprint-element ] each
|
2005-09-14 00:37:50 -04:00
|
|
|
r> [ "..." f text ] when ;
|
2005-08-21 01:17:37 -04:00
|
|
|
|
|
|
|
: pprint-sequence ( seq start end -- )
|
2005-08-29 01:00:55 -04:00
|
|
|
swap pprint* swap pprint-elements pprint* ;
|
|
|
|
|
|
|
|
M: complex pprint* ( num -- )
|
2005-09-11 20:46:55 -04:00
|
|
|
>rect 2array \ #{ \ }# pprint-sequence ;
|
2005-08-21 01:17:37 -04:00
|
|
|
|
|
|
|
M: cons pprint* ( list -- )
|
2005-02-10 23:58:28 -05:00
|
|
|
[
|
2005-09-24 15:21:17 -04:00
|
|
|
dup list? [ \ [ \ ] ] [ uncons 2array \ [[ \ ]] ] if
|
2005-08-21 01:17:37 -04:00
|
|
|
pprint-sequence
|
2005-02-10 23:58:28 -05:00
|
|
|
] check-recursion ;
|
2004-07-19 16:10:18 -04:00
|
|
|
|
2005-09-11 20:46:55 -04:00
|
|
|
M: array pprint* ( vector -- )
|
|
|
|
[ \ @{ \ }@ pprint-sequence ] check-recursion ;
|
|
|
|
|
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 -- )
|
2005-09-01 01:20:43 -04:00
|
|
|
[
|
|
|
|
\ << pprint*
|
2005-09-11 20:46:55 -04:00
|
|
|
tuple>array dup first pprint*
|
2005-09-01 01:20:43 -04:00
|
|
|
<block 1 swap tail-slice pprint-elements block>
|
|
|
|
\ >> pprint*
|
|
|
|
] check-recursion ;
|
2004-07-16 02:26:21 -04:00
|
|
|
|
2005-08-21 01:17:37 -04:00
|
|
|
M: alien pprint* ( alien -- )
|
2005-08-23 23:28:54 -04:00
|
|
|
dup expired? [
|
|
|
|
drop "( alien expired )"
|
|
|
|
] [
|
2005-08-29 01:00:55 -04:00
|
|
|
\ ALIEN: pprint-word alien-address number>string
|
2005-09-24 15:21:17 -04:00
|
|
|
] if f text ;
|
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-29 01:00:55 -04:00
|
|
|
\ \ pprint-word wrapped pprint-word
|
2005-08-03 23:56:28 -04:00
|
|
|
] [
|
2005-09-11 20:46:55 -04:00
|
|
|
wrapped 1array \ W[ \ ]W pprint-sequence
|
2005-09-24 15:21:17 -04:00
|
|
|
] if ;
|
2005-08-03 23:56:28 -04:00
|
|
|
|
2005-09-05 20:36:10 -04:00
|
|
|
: with-pprint ( quot -- )
|
2005-02-09 20:57:19 -05:00
|
|
|
[
|
2005-09-06 14:52:06 -04:00
|
|
|
<pprinter> pprinter set call end-blocks
|
2005-09-05 18:00:20 -04:00
|
|
|
pprinter get do-pprint
|
2005-09-05 20:36:10 -04:00
|
|
|
] with-scope ; inline
|
|
|
|
|
|
|
|
: pprint ( object -- ) [ pprint* ] with-pprint ;
|
2005-08-21 01:17:37 -04:00
|
|
|
|
2005-08-21 20:50:14 -04:00
|
|
|
: unparse ( object -- str ) [ pprint ] string-out ;
|
2005-08-21 01:17:37 -04:00
|
|
|
|
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
|
2005-08-26 18:18:07 -04:00
|
|
|
20 length-limit set
|
2005-08-21 14:40:12 -04:00
|
|
|
2 nesting-limit set
|
2005-08-21 20:50:14 -04:00
|
|
|
string-limit on
|
2005-08-21 14:40:12 -04:00
|
|
|
pprint
|
|
|
|
] with-scope ;
|
|
|
|
|
2005-08-21 20:50:14 -04:00
|
|
|
: unparse-short ( object -- str ) [ pprint-short ] string-out ;
|
2004-07-21 19:26:41 -04:00
|
|
|
|
2005-08-24 19:25:12 -04:00
|
|
|
: short. ( object -- )
|
2005-08-22 20:54:01 -04:00
|
|
|
dup unparse-short swap write-object terpri ;
|
|
|
|
|
2005-08-27 15:33:29 -04:00
|
|
|
: sequence. ( sequence -- ) [ short. ] each ;
|
2005-08-21 01:17:37 -04:00
|
|
|
|
2005-08-29 01:00:55 -04:00
|
|
|
: stack. ( sequence -- ) reverse-slice sequence. ;
|
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 ;
|
2005-08-29 01:00:55 -04:00
|
|
|
|
|
|
|
: define-open
|
|
|
|
#! The word will be pretty-printed as a block opener.
|
2005-09-05 18:00:20 -04:00
|
|
|
#! Examples are [ { {{ [[ << and so on.
|
2005-09-21 01:12:16 -04:00
|
|
|
t "pprint-open" set-word-prop ;
|
2005-08-29 01:00:55 -04:00
|
|
|
|
2005-09-01 01:20:43 -04:00
|
|
|
: define-close ( word -- )
|
|
|
|
#! The word will be pretty-printed as a block closer.
|
2005-09-05 18:00:20 -04:00
|
|
|
#! Examples are ] } }} ]] >> and so on.
|
2005-09-21 01:12:16 -04:00
|
|
|
t "pprint-close" set-word-prop ;
|
2005-09-01 01:20:43 -04:00
|
|
|
|
2005-08-29 01:00:55 -04:00
|
|
|
{
|
|
|
|
{ POSTPONE: [ POSTPONE: ] }
|
|
|
|
{ POSTPONE: { POSTPONE: } }
|
2005-09-16 02:39:33 -04:00
|
|
|
{ POSTPONE: @{ POSTPONE: }@ }
|
2005-08-29 01:00:55 -04:00
|
|
|
{ POSTPONE: {{ POSTPONE: }} }
|
|
|
|
{ POSTPONE: [[ POSTPONE: ]] }
|
|
|
|
{ POSTPONE: [[ POSTPONE: ]] }
|
2005-09-02 23:44:23 -04:00
|
|
|
} [ first2 define-close define-open ] each
|