音の鳴るブログ

鳴らないこともある

JavaScript から見た SuperCollider

去年は CoffeeScript で 書ける SuperColliderCoffeeScript だ!!とか言っていたけど、コンセプト以外はさっぱり考えていなくて、実際やってみると色々問題点が多くて、ぶっちゃけ失敗したなと思う。

そこで SuperCollider のコードをそのままブラウザで実行してみようと取り敢えずの一念発起でパーサーとコードジェネレーターを書いた。クラスの構文以外は大体サポートできたけど、実行できないという欠点がある。

SuperCollider のコードを JavaScript に変換する。

// SuperCollider
69.midicps
// JavaScript
$SC('midicps', 69)

二項演算子だと色々書き方があるけど解釈はひとつ。

// SuperCollider
1 max: 2
1.max(2)
max(1, 2)
$SC('max', 1, [ 2 ])

ちょっと複雑なのだとこんな感じ。

// SuperCollider
if (a) { true.postln } { false.postln }
// JavaScript
$SC('if', $SC.I.a, [function() {
  return $SC('postln', true);
}, function() {
  return $SC('postln', false);
}]);

$SC という関数は引数に メッセージ, レシーバー, 引数 を取る。 SuperCollider も含めて大体のオブジェクト指向言語Smalltalk から影響を受けていると思うのだけどそれと同じ感じだと思う (よく知らんけど)

最後のやつは少し面白くて、if はキーワードでもなんでもなくて普通のメッセージ式となる。ブレースで囲まれた部分は関数式となるので、special case も不要で凄くシンプル。SuperCollider の本質は(非純粋)関数型言語と言えるので実行環境以外の部分なら JavaScript のサブセットで書ける。

ここで試せる

長めのコードだとわけがわからない感じになる

あとは $SC の実装をすればブラウザで動く SuperCollider が作れるはず。


パーサーは Esprima を参考にして一文字ずつコピペして書いた。

Espeima は ECMA262 の仕様そのままにコード化されていて凄く読みやすいので、パーサーを自分で書きたいとかいうときにコード参考にしやすいと思う。

コードジェネレーターは Escodegen を参考にした。

ECMA-262 Edition 5.1を読む

ECMA-262 Edition 5.1を読む