Schemeをつくろう(22) - JavaScriptのメモ
JavaScriptでSchemeを作る為に必要なことをメモっとく。
字句解析
tokenize = function(src) { return src.match(/\(|\)|'|[^\s()']+/g); }; // tokenize("(hello Javascript and Scheme world !!)") // => #(( hello Javascript and Scheme world !! ))
配列に分解出来る。ステキ。
ほうほう。
/\"(?:[^"])*\"/
eval
<div onclick="eval(this.firstChild.nodeValue)">alert("hello")</div>
タグの中をeval。便利。
apply
無いと死ねる。
var scm = new Scheme(); function len() { return arguments.length } alert(len.apply(this, [1, 2, 3, 4])); // => 4
関数.apply(環境, 引数の配列)
JavaScriptにはクロージャがある。
thisの部分で遊ぶと時空を越えられるかも知れない。
型
- 連想配列はObject型
- 配列はArray型
- null,undefinedはObjectを継承していない。。
括弧って便利ね
コロンで区切って複数式が書ける。
(alert("hello"), alert("world"))
構文はエラーになるので、無名関数で囲む。
参考
- 僕 Lisp
- リンク切れてるけど、わーい \(^o^)/ Scheme もどきを JS で書いたよー! - IT戦記のソース。
- JavaScript の配列と連想配列の違い - IT戦記
- 6の例が全て。
Biwa Schemeを読む(3) - コンパイラ〜インタプリタ
ここからが本題。CompilerとInterpreterは一緒に読んだ方がよさげ。
Biwa Schemeの中間言語は[命令,値(複数),次の命令]という形になっていて再帰的な構造をしているようだ。
命令一覧
- halt
- 終わり。
- constant 値
- レジスタに値を入れる。
- argument
- レジスタの値をスタックに積む。
- refer-global 名前,-local 名前, refer-free 名前
- 環境を参照する,assignで書く。
- apply 引数の数
- 命令の実行。
- frame 命令・・・
- ローカル環境っぽい。
まだ読み中。
突っ込み
0.5の時点では積み方が逆。
(define (p x) (display x) (newline) x) (+ (p 1) (p 2)) 2 1 3
破壊的でなければ何の問題も無い。
Biwa Schemeを読む(0) - 斜め読み
こんな感じ?
僕のイメージとしては、パーサーを通してS式に変換して、S式を順番に読み上げてリスト形式のForth(アセンブリ言語に毛が生えたような言語)作る。で、リスト形式のForthを実行してるのかなぁと。しかし、謎の部分が多すぎていきなり作る訳にもいかなそうだ。
そうだBiwa Schemeを読もう
ということで、JavaScriptで書かれたスタックベースのSchemeBiwaScheme0.5を簡単に写経しながら読み解いていきたいと思います。
とりあえずファイル構造から理解する事に。
- index.html
- ブラウザで動作確認が取れる。メインっぽい。
- ブラウザのボタン押したら、bs_evalを呼ぶ。
- new WebScheme.Interpreter()がメインのクラスかな?
- コードを取得して、コンパイルしたものを表示しているようだ。
- evaluate(コード,継続?)で評価して表示。
- 2番目の引数はイマイチ謎なので、後で追う事にする。
- lib/prototype.160.js
- prototype1.6使ってるらしい。これも未読なので、積読にしておこう。
- lib/stackbase.js
- たぶんコア部分。次回からはここを中心に読むと思われる。
- lib/r6rs_lib.js
- R6RSのライブラリ。0.5の時点では未完っぽい。
- lib/webscheme_lib.js
- Ajax関連?
- lib/extra_lib.js
- SRFIとか。無いと困っちゃいそうな関数群。
- サンプルコード色々。
- ネットワーク関連が充実してるっぽい。
ここまでの感想
- 丁寧なソースで非常に読みやすいです。
- そういやJavaScriptをずっと書いてなかった気がする。
caseには式
久しぶりに更新してみるよ。
var k = 3; switch (k) { case 1 + 2 : alert("caseに式が使えるよ!"); break; }
ifと変わらん。