エンタープライズギークス (Enterprise Geeks)

企業システムの企画・開発に携わる技術者集団のブログです。開発言語やフレームワークなどアプリケーション開発に関する各種情報を発信しています。ウルシステムズのエンジニア有志が運営しています。

JavaScriptでLispインタープリターを作ろう(1)

プログラマーなら一度はLispを作る

プログラマーなら一度はLispを作る」という言葉は有名だ。実際、世の中にはLispの実装が山のように存在し、Lispの処理系を作成する記事を見かける事も少なくない。

しかし、今までその言葉は知っていたものの、自分でLispの処理系を作ったことは無かった。公開されているLispの処理系は完成度が高いものが多く、一気に読み解けるようなシロモノではなくなっている事が多かった。Lispの処理系を作成する記事をいくつか読んだこともあったが、内容が低レイヤーに寄っている事が多く、実装言語もC言語を使ったりと、なかなか全体観が容易には掴めない印象だったことを記憶している。

そうした中で、AIやコンピューターサイエンスの世界で名高い Peter Norvig 氏が 「http://norvig.com/lispy.html」という記事を公開していることを知った。たった113行のPythonスクリプトで作成されたLispインタープリターであり、丁寧な解説記事もある。

また、更に完全なLispインタープリターに育てたバージョンとして、「http://norvig.com/lispy2.html」という記事も Peter Norvig 氏によって公開されている。2つ目のLispインタープリターでは、型が導入され、Lispのマクロまで入った、より完成度の高いものになっている。

これらの素晴らしい教材に出会ったことで、自分でもLispインタープリターを作ることが出来た。利用した言語はJavaScriptである。完成したLispインタープリターは、以下のリンク先にある。

JavaScriptで作成したLispインタープリター(完成版)

エディター部分はCodeMirrorを使用した。動作を確認した環境はChromeブラウザーである。動作のさせ方は以下の通りだ。

  1. ChromeブラウザーのF12キーを押して、JavaScriptコンソールを表示する。
  2. 実行したいスクリプトを範囲選択する。
  3. 「F2」キーを押すと実行され、JavaScriptコンソールに結果が表示される。

さて、前置きが長くなってしまったが、以降では今回作成したLispインタープリターを紹介していく。ただし、このインタープリターは全部で147行もあるため、いきなりすべて説明するのも大変である。そのため、ステップ・バイ・ステップで小さなインタープリターを徐々に成長させていき、最終的に全体を説明する方法を取ろうと思う。そのため、まずは四則演算インタープリターを作ってみる。

四則演算インタープリタ

四則演算インタープリターのコードを以下に示す。コード量はたったの23行だ。とはいえ、インタープリターとしての骨格はすべて入っている。まずはこれを説明する。

使い方は次の通り。このコードはJSFiddleにて公開してある。上記右上にある「Edit in JSFiddle」の先に遷移すれば、自由にコードを編集可能なエディターがブラウザー内に開かれる。

インタープリターを動作させるためのスクリプトは以下のようなものだ。

// usage
d3.select('#out').text(
  evaluate(['*', ['+', 1, 2],['-', 8, 3]], globalEnv)
);

d3.select('#out').text の部分はDOMの書き換えなので無視してよく、実際のインタープリターの実行はevaluate関数の実行部分である。ここでは((1 + 2) * (8 - 3))の計算をしている。

JSFiddle上でコードを実行するためには、Runボタンを押す。そうすると右下の窓にResult: 15と記述されるはずだ。

この四則演算インタープリターが提供する演算は以下の5つだ。いずれも引数を2つのみ取る。

関数名 引数 処理内容
+ 2つの数値 a + b
- 2つの数値 a - b
* 2つの数値 a * b
/ 2つの数値 a / b
mod 2つの数値 a % b

JSFiddle上で数式をさまざまに変更してみて、動作を確かめて欲しい。

次回は、四則演算インタープリターの処理内容を解説する。

[近棟 稔]