言語ゲーム

とあるエンジニアが嘘ばかり書く日記

Twitter: @propella

pretty print

現実逃避的に、Squeakはてな用 pretty print を書いてみる。はてなでは、連続する ] の記号やタブをうまく表示できないので、ソースを日記に貼り付ける時には手で修正する必要があった。そこで、このソースを使うと、pretty print (右クリックのさらにメニューにある) を実行するだけではてな用に整形してくれる。インストール方法は、以下のソースを file in するだけ。ScamperWorkspace なら直接 file it in 出来ます。もちろんこのソース自体 pretty print されている。なんと自己記述的。

'From TeaSqueak3.6 of 8 February 2004 [latest update: #618] on 23 June 2004 at 7:37:01 pm'!

!BlockNode methodsFor: 'printing' stamp: 'tak 6/23/2004 19:33'!
printArgumentsOn: aStream indent: level 
    arguments size = 0
        ifTrue: [
            statements size > 1
                ifTrue: [aStream crtab: level] .
            ^ self] .
    aStream dialect = #SQ00
        ifTrue: [
            aStream withStyleFor: #setOrReturn
                do: [aStream nextPutAll: 'With'] .
            arguments
                do: [:arg | 
                    aStream space.
                    aStream withStyleFor: #blockArgument
                        do: [aStream nextPutAll: arg key] ] .
            aStream nextPutAll: '. '] 
        ifFalse: [
            arguments
                do: [:arg | aStream withStyleFor: #blockArgument
                        do: [aStream nextPutAll: ':';
                                 nextPutAll: arg key;
                                 space] ] .
            aStream nextPutAll: '| '] .
    "If >0 args and >1 statement, put all statements on separate lines"
    statements size > 1
        ifTrue: [aStream crtab: level] ! !

!BlockNode methodsFor: 'printing' stamp: 'tak 6/23/2004 19:36'!
printOn: aStream indent: level 
    "statements size <= 1 ifFalse: [aStream crtab: level]."
    aStream nextPut: $[.
    self printArgumentsOn: aStream indent: level.
    self printTemporariesOn: aStream indent: level.
    self printStatementsOn: aStream indent: level.
    aStream nextPutAll: '] '! !


!MessageNode methodsFor: 'printing' stamp: 'tak 6/23/2004 19:34'!
printKeywords: key arguments: args on: aStream indent: level prefix: isPrefix 
    | keywords indent noColons arg kwd hasBrackets doCrTab |
    args size = 0
        ifTrue: [
            aStream space; nextPutAll: key.
            ^ self] .
    keywords _ key keywords.
    noColons _ aStream dialect = #SQ00
                and: [keywords first endsWith: ':'] .
    doCrTab _ args size = 1
                ifTrue: [false] 
                ifFalse: [(args size = 2
                            and: [(args first isKindOf: BlockNode) not] )
                        ifTrue: [false] 
                        ifFalse: [true] ] .
    1 to: (args size min: keywords size)
        do: [:i | 
            arg _ args at: i.
            kwd _ keywords at: i.
            (doCrTab
                    or: [arg isKindOf: BlockNode] )
                ifTrue: [
                    aStream crtab: level + 1.
                    indent _ 1
                    "newline after big args"] 
                ifFalse: [
                    aStream space.
                    indent _ 0] .
            noColons
                ifTrue: [
                    aStream withStyleFor: (isPrefix
                            ifTrue: [#prefixKeyword] 
                            ifFalse: [#keyword] )
                        do: [aStream nextPutAll: kwd allButLast;
                                 space] .
                    hasBrackets _ (arg isKindOf: BlockNode)
                                or: [arg isKindOf: BlockNode] .
                    hasBrackets
                        ifFalse: [aStream nextPutAll: '('] ] 
                ifFalse: [aStream nextPutAll: kwd;
                         space] .
            arg
                printOn: aStream
                indent: level + 1 + indent
                precedence: (precedence = 2
                        ifTrue: [1] 
                        ifFalse: [precedence] ).
            noColons
                ifTrue: [hasBrackets
                        ifFalse: [aStream nextPutAll: ')'] ] ] ! !


!WriteStream methodsFor: 'character writing' stamp: 'tak 6/23/2004 19:34'!
crtab: anInteger 
    self nextPut: Character cr.
    anInteger
        timesRepeat: [4
                timesRepeat: [self nextPut: Character space] ] ! !