JavaScriptでLispインタープリターを作ろう(6) ~反復の導入~
前回の記事では変数を導入した。これで、反復処理を記述するための土台がひとまず整ったことになる。それでは早速、反復処理であるwhile
を導入してみよう。
反復処理を行うwhile
反復処理は、インタープリターのevaluate
関数に以下の記述を追加する事で導入できる。
var evaluate = function(x, env) { if (Array.isArray(x)) { if (x[0] === 'while') { // whileループ 追加行1 while (evaluate(x[1], env)) { // 追加行2 x.slice(2).forEach(function(a){evaluate(a, env);}); // 追加行3 } // 追加行4 return null; // 追加行5 } else if (x[0] === 'def') { // 変数定義 // ・・・以下略・・・
上記のコードについて簡単に説明しておこう。
まず「追加行2」の部分ではJavaScriptのwhile
ループに入っている。ここでwhile
の第1引数を評価(evaluate)し、ループを継続するかをチェックしている。そして「追加行3」の部分で、while
で実行したいコードを順次評価している。
以下にソースコード全体を掲載する。
このwhile
ループを試してみよう。たとえばJavaScriptにおいて以下のようなコードを書きたいとする。
var i = 0; while (i < 3) { console.log(i); i = i + 1; }
これを、このインタープリターで記述すると以下のようになる。
evaluate(['do', ['def', 'i', 0], ['while', ['<', 'i', 3], ['console.log', 'i'], ['set!', 'i', ['+', 'i', 1]]]], globalEnv);
このソースコードはJavaScript版とほぼ同じであるため、対応関係がよくお分かり頂けるのではないだろうか。
さて、以上で反復処理も記述可能になった。これにより、「順次・反復・分岐」のすべての制御構文がサポートできたことになる。
次回はいよいよ関数を導入する。
[近棟 稔]