[SML 7561] Re: 第8回Smalltalk勉強会@京都
AOKI Atsushi
atsushi @ cc.kyoto-su.ac.jp
2009年 6月 4日 (木) 09:40:12 JST
青木@京都上賀茂です。
昨夜に行った京都駅前でのSmalltalk勉強会の簡単な報告をします。
3.5 メッセージ(p.88)から始めて、3.6 文(p.95)のカスケード
までゆきました。8ページしか進んでいない!のですが、7.2 本格的
な文法を併せて行いましたので、こちらが15ページ分あります。合
計して23ページ分になります。ちょうど良いペースでしょう。:-)
デバッカによる逐次実行で、メッセージの種類や優先順位(どの順
番でメッセージが発信されるか)などを、より深く理解していただ
けたのではないかと思います。
#初学者ほどデバッカを使うのが望ましい。
以下に単項メッセージセレクタ・二項メッセージセレクタ・キーワ
ードメッセージセレクタを求めるプログラムを記載しておきます。
ウィンドウのラベルに個数をつけておきました。
------------------------------------------------------------
"メッセージセレクタを種類別に求めてウィンドウにリストする"
| aSet aPoint |
aSet := Set new: 50000.
Smalltalk allBehaviorsDo: [:each | aSet addAll: each selectors].
aPoint := nil.
(Array
with: 'Unary Message Selectors'
-> [:each | each numArgs = 0 and: [each isKeyword not]]
with: 'Binary Message Selectors'
-> [:each | each numArgs = 1 and: [each isKeyword not]]
with: 'Keyword Message Selectors'
-> [:each | each numArgs >= 1 and: [each isKeyword]])
do: [:anAssociation |
| aString aBlock aStream aCollection aModel |
aString := anAssociation key.
aBlock := anAssociation value.
aStream := WriteStream on: String new.
aCollection := (aSet select: aBlock) asSortedCollection.
aCollection do: [:each |
aStream
nextPutAll: each asString;
cr].
aModel := ValueHolder with: aStream contents.
TextEditorView
open: aModel
label: aString , ' : ' , aCollection size printString
extent: 400 @ 300.
(aModel dependents detect: [:each | each isKindOf: ScheduledWindow]
ifNone: [nil])
ifNotNil: [:aWindow |
| aBox |
aPoint
ifNil: [aPoint := aWindow displayBox origin]
ifNotNil: [aPoint := aPoint translatedBy: 40 @ 30.
aBox := aPoint extent: aWindow displayBox extent.
aWindow displayBox: aBox]]].
^aSet
------------------------------------------------------------
また、構文木(JunParseTreeもしくはFooProgramScanner)を援用し
ました。構文木を深さ優先でたどれば、それが実行順序になること
も得心していただけたと思います。
プログラムコードを文字列として構文木に渡し、出せ!というだけ。
(JunParseTree code: '3 + 4 * 5') show
(JunParseTree code: '3 + (4 * 5)') show
次のような単項メッセージ・二項メッセージ・キーワードメッセー
ジが混ざったものでも、コンパイラの気持ちを知ることができます。
(JunParseTree code: 'Rectangle origin: 1 asPoint + 2 asPoint extent: 3 asPoint + 4 asPoint') show
また、クラスとメッセージセレクタを指定して構文木を出したり、
コンパイルドメソッドを指定して構文木を出したりできます。
(JunParseTree class: Integer selector: #factorial) show
(JunParseTree method: (Integer compiledMethodAt: #factorial)) show
------------------------------------------------------------
さらに、なぜカスケードが有用であるのかを、バイトコードから証
を立てることも行いましたので、そのプログラムを記しておきます。
------------------------------------------------------------
"カスケードを使わない場合"
[Transcript clear.
Transcript nextPutAll: 'ASAOKA Hiroko'.
Transcript cr.
Transcript nextPutAll: 'SAWAMOTO Eri'.
Transcript cr.
Transcript nextPutAll: 'AOKI Atsushi'.
Transcript cr.
Transcript flush]
method symbolic
"以下のようなバイトコード列(30バイト)になります”
normal CompiledBlock numArgs=0 numTemps=0 frameSize=12
literals: ({Transcript} #clear 'ASAOKA Hiroko' 'SAWAMOTO Eri' 'AOKI Atsushi' #flush )
1 <34> push Transcript
2 <71> send clear
3 <66> pop
4 <34> push Transcript
5 <1E> push 'ASAOKA Hiroko'
6 <B5> send nextPutAll:
7 <66> pop
8 <34> push Transcript
9 <F0 21> send cr
11 <66> pop
12 <34> push Transcript
13 <1F> push 'SAWAMOTO Eri'
14 <B5> send nextPutAll:
15 <66> pop
16 <34> push Transcript
17 <F0 21> send cr
19 <66> pop
20 <34> push Transcript
21 <20> push 'AOKI Atsushi'
22 <B5> send nextPutAll:
23 <66> pop
24 <34> push Transcript
25 <F0 21> send cr
27 <66> pop
28 <34> push Transcript
29 <75> send flush
30 <65> return
------------------------------------------------------------
"カスケードを使った場合"
[Transcript
clear;
nextPutAll: 'ASAOKA Hiroko';
cr;
nextPutAll: 'SAWAMOTO Eri';
cr;
nextPutAll: 'AOKI Atsushi';
cr;
flush]
method symbolic
"以下のようなバイトコード列(24バイト)になります”
normal CompiledBlock numArgs=0 numTemps=0 frameSize=12
literals: ({Transcript} #clear 'ASAOKA Hiroko' 'SAWAMOTO Eri' 'AOKI Atsushi' #flush )
1 <34> push Transcript
2 <68> dup first
3 <71> send clear
4 <69> dup
5 <1E> push 'ASAOKA Hiroko'
6 <B5> send nextPutAll:
7 <69> dup
8 <F0 21> send cr
10 <69> dup
11 <1F> push 'SAWAMOTO Eri'
12 <B5> send nextPutAll:
13 <69> dup
14 <F0 21> send cr
16 <69> dup
17 <20> push 'AOKI Atsushi'
18 <B5> send nextPutAll:
19 <69> dup
20 <F0 21> send cr
22 <6A> dup last
23 <75> send flush
24 <65> return
------------------------------------------------------------
以上、簡単ですが、昨日の勉強の報告でした。不足や他に思うとこ
ろなどがありましたら、ご参加いただいた皆さん、フォローをお願
いします。
#きっと浅岡さんが差し入れの報告をしてくれるにちがいない。
------------------------------------------------------------
AOKI Atsushi http://www.cc.kyoto-su.ac.jp/~atsushi/
SML メーリングリストの案内