Mais conteúdo relacionado
Mais de Masashi Umezawa (20)
MultilineクラスとMultilineメソッド
- 3. 例
いらないクラスということがすぐにわかる
Object subclass: #'
/ \
/ ─ ─\
/ (●) (●) \ よく考えたら俺いらないな
| (__人__) |
/ ∩ノ ⊃ /
( \ / _ノ | |
.\ “ /__| |
\ /___ /
'
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'Test-Multilines'
- 6. Multiline method (1)
開発環境の抵抗がなかなか強かったので、
メソッド追加で対処
ClassDescriptiopn >> addAAMethod: aa body: bodyCode
| code aaSymbol |
code := 'tmp' , String cr , bodyCode.
aaSymbol := aa asSymbol.
self compile: code classified: ''.
self addAndClassifySelector: aaSymbol
withMethod: (self methodDict at: #tmp)
inProtocol: 'AA' notifying: nil.
self removeSelector: #tmp
- 7. Multiline Method (2)
各クラスのMethodDictionaryをいじって
あげればよい
tmpという名前でまずメソッドをコンパイル
コンパイルされたバイトコード(CompiledMethod)を
アスキーアート(AA)をキーとして登録しなおす
tempのメソッドは消しておく
これでできた!
- 9. パーサライブラリの拡張 (2)
スキャナにバッククォートのトークンを加える
AAをバッククォートで囲むと、クラスやメソッドの識別子と
してパースされるようにしたいため
Scanner class >> initialize
...
newTable at: $` asciiValue put: #xBackQuote.
...
バッククォートを選んだ理由
他で使われていない
存在感が薄いのでアスキーアートを邪魔しない
- 10. パーサライブラリの拡張 (3)
Scanner >> xBackQuote
self step.
buffer reset.
[hereChar = $`
and: [aheadChar = $`
ifTrue: [self step. false]
ifFalse: [true]]]
whileFalse:
[buffer nextPut: self step.
(hereChar = 30 asCharacter and: [source atEnd])
ifTrue: [^self offEnd: 'Unmatched string quote']].
self step.
token := buffer contents asSymbol.
tokenType := #word
まじめに読む必要なし
xSingleQuoteメソッドをパクる
tokenTypeを#wordにする => 識別子になる
- 11. デモ
AAクラスの定義
AAメソッドの定義
実行
`
|┃三 ∩___∩
|┃ | ノ ヽ
|┃ ≡ / ● ● | きたクマー!
____,|ミ\___| (..●..) ミ
|┃=___ |∪| \
|┃ ≡ / ヽノ 人 \ ガラッ` new
`
/⌒ヽ
∩ ^ω ^) うはwww
| ⊂ノ
| _⊃
し ⌒`