2011-07-31 (Sun)
_ 3.1.0へのアップデート
3.1.0にアップデートした。
ついでにテーマをDefaultベースで書き直して、スマートフォンでサイドバーが表示されないようにした。 ただ、それでもFacebookプラグインのせいで画面からはみ出してしまう。 スマートフォンの時はFacebookプラグインを表示しないようにするのがいいかな。
あと、写真のアップロードが面倒なので、Picasaプラグインを入れてみた。 画像をリンクしてPicasaに飛ぶようにはできないのかな。 大き目の画像を貼るようにしとけば別にいいかという気もするけど。
追記:
Facebookプラグインについては、とりあえずスマートフォンだったらwidthを300にすることにした。
diff --git a/jit/misc/plugin/facebook_comments.rb b/jit/misc/plugin/facebook_comments.rb index 43bb30a..602d4c6 100644 --- a/jit/misc/plugin/facebook_comments.rb +++ b/jit/misc/plugin/facebook_comments.rb @@ -11,7 +11,7 @@ end def facebook_comments(href = '') <<-HTML -<div id="fb-root"></div><script src="http://connect.facebook.net/ja_JP/all.js#appId=#{h @conf['facebook_comments.YOUR_APPLICATION_ID']}&xfbml=1"></script><fb:comments href="#{h href}" num_posts="#{h @conf['facebook_comments.num_posts']}" width="#{h @conf['facebook_comments.width']}"></fb:comments> +<div id="fb-root"></div><script src="http://connect.facebook.net/ja_JP/all.js#appId=#{h @conf['facebook_comments.YOUR_APPLICATION_ID']}&xfbml=1"></script><fb:comments href="#{h href}" num_posts="#{h @conf['facebook_comments.num_posts']}" width="#{h @conf.smartphone? ? 300 : @conf['facebook_comments.width']}"></fb:comments> HTML end
_ クラッチスイッチの交換
正確にはスタータロックアウトスイッチと言うべきなのかな。
しばらくは折れたところを接着剤でくっつけて凌いでいたが、バイク屋から部品が届いたとの連絡があったので、取りに行ってきた。 たったこれだけで1250円だよ。でも送料を取られなかったのでよかった。
帰ってから自分で交換したけど、今度は折らないように注意して作業した。
あと、KLX125はクラッチ切ってもニュートラルじゃないとセルが回らないんだと思っていたけど、クラッチレバーがグリップに付くくらい握り込むとニュートラル以外でもセルが回ることを発見した。 セル付きのバイクははじめてなので、このあたりの勝手が今一よくわかってない。
とりあえずは便利なんだけど、中身がよくわかんなくてちょっとイライラするのは、外部のWebサービスを使ったりする時とちょっと似ている。
2014-07-31 (Thu)
_ SECDマシンにおける再帰
先日のICFPCに会社のチームで参加して、コンパイラの実装を少しだけ手伝った。
後でわかったが、ICFPCの仮想マシンの仕様はLispKitをベースにしていて、SECDマシンという有名なものらしい。
SECDマシンはスタックマシンで、データスタック、制御スタック(関数呼び出しや条件分岐時に復帰するための情報が積まれる)、環境フレーム(変数が格納される)という三つのスタックを持っている(環境フレームは親フレームへのポインタを持っていて、単純にpopされる代りに参照されなくなったらGCされるので、厳密にはスタックではない)。
Stack/Environment/Control/Dumpという4つのレジスタを持つのがSECDマシンという名前の由来。
例えば、((lambda (x) (+ x x)) 21)
のようなプログラムは以下のように表現される。
LDC 21 ; 定数21をスタックにpushする。 LDF body ; bodyを本体とするクロージャを生成してスタックにpushする。 AP 1 ; 新しい環境フレームを生成して、21に関数を適用する。 RTN ; 呼び出し元に戻る。 body: LD 0 0 ; 0番目の環境フレームの0番目の変数(x)の値をスタックにpushする。 LD 0 0 ; 0番目の環境フレームの0番目の変数(x)の値をスタックにpushする。 ADD ; スタックから二つの値をpopし、加算した結果をスタックにpushする。 RTN ; 呼び出し元に戻る。
APは新しい環境フレームを生成して関数を適用するが、APと似た命令に環境フレームを生成しないRAPというものがあり、空の環境フレームを生成するDUMという命令とセットで利用する。
例えば、(letrec ((loop (lambda () (loop)))) (loop))
のような再帰的なプログラムは以下のように表現される。
DUM 1 ; 空の環境フレームを生成する。 LDF loop ; loopを本体とするクロージャを生成してスタックにpushする。 LDF main ; mainを本体とするクロージャを生成してスタックにpushする。 RAP 1 ; DUMで生成した環境フレームを使用してloopにmainを適用する。 RTN main: LD 0 0 ; 0番目の環境フレームの0番目の変数(loop)の値をスタックにpushする。 AP 0 ; 関数を適用する RTN ; 呼び出し元に戻る。 loop: LD 1 0 ; 1番目の環境フレームの0番目の変数(loop)の値をスタックにpushする。 AP 0 RTN ; 呼び出し元に戻る。
DUMで生成した環境フレームがLDF loop
で生成されるクロージャによって捕捉されるところがポイントで、これによってloop内のLD 1 0
(loopの適用で環境フレームが積まれるのでLDの第1オペランドは1とする)でloop自身を参照できる。
上記の例でDUM/RAPの代りにAPを使うと、letrecの代りにletを使った場合のように、loop内でloop自身を参照できない。