“Lisp as 〜”のお題を Scala で、を Squeak Smalltalk で

こ、これは短い! Scala、恐るべし。 どういう動きなのかの解析と Scala の勉強を兼ねて、Squeak Smalltalk へ直訳っぽく。

Object subclass: #DD
    instanceVariableNames: 'word digits'

DD >> digits
    ^digits

DD >> isDigit
    ^word first isDigit

DD >> isLiteral
    ^true

DD >> printOn: stream
    stream nextPutAll: word

DD >> setWord: string digits: seq
    word := string.
    digits := seq

DD class >> word: string digits: seq
    ^self new setWord: string digits: seq; yourself
| map dictionary phones digitFromLetter digitsWord digiDict digits matchDigiDict patterns |

map := #('e' 'jnq' 'rwx' 'dsy' 'ft' 'am' 'civ' 'bku' 'lop' 'ghz').
dictionary := #('an' 'blau' 'Bo"' 'Boot' 'bo"s' 'da' 'Fee' 'fern' 'Fest' 'fort'
    'je' 'jemand' 'mir' 'Mix' 'Mixer' 'Name' 'neu' 'o"d' 'Ort' 'so' 'Tor' 'Torf' 'Wasser').
phones := #('112' '5624-82' '4824' '0721/608-4067' '10/783--5' '1078-913-5' '381482' '04824').

digitFromLetter := [:in | (map findFirst: [:each | each includes: in asLowercase]) - 1].
digitsWord := [:word | word asArray collect: [:each | digitFromLetter value: each] thenSelect: [:each | each ~= -1]].
digiDict := dictionary collect: [:w | DD word: w digits: (digitsWord value: w)].
digits := [:in | in asArray select: [:each | each isDigit] thenCollect: [:each | each digitValue]].

matchDigiDict := [:dgts1 |
    (digiDict select: [:dd | dgts1 beginsWith: dd digits])
        ifEmpty: [{DD word: dgts1 first asString digits: {dgts1 first}}]
        ifNotEmptyDo: [:x | x]].

patterns := [:dgts2 |
    dgts2
        ifEmpty: [#(())]
        ifNotEmpty: [((matchDigiDict value: dgts2) collect: [:dd |
            (patterns copy fixTemps value: (dgts2 allButFirst: dd digits size))
                 select: [:node | (dd isDigit and: [node notEmpty and: [node first isDigit]]) not]
                 thenCollect: [:node | {dd}, node]]) concatenation]].

World findATranscript: nil.
phones collect: [:p |
    Transcript cr;
        show: p,' => ';
        show: (patterns copy fixTemps value: (digits value: p))]
112 => #()
5624-82 => #(#(mir Tor) #(Mix Tor))
4824 => #(#(fort) #(Tor 4) #(Torf))
0721/608-4067 => #()
10/783--5 => #(#(je Bo" da) #(je bo"s 5) #(neu o"d 5))
1078-913-5 => #()
381482 => #(#(so 1 Tor))
04824 => #(#(0 fort) #(0 Tor 4) #(0 Torf))