24 評価プロセス(関数呼び出し式) [オリジナル言語インタプリタを作る]

関数と関数呼び出し式 関数と関数呼び出し式の評価を実装します。ここまで字句解析、構文解析、そして評価と実装を進めてきましたが、この実装で最後です。 関数の単純な呼び出しはもちろん、引数で関数を渡したり、クロージャも動作します。 このような動作を実現するにはまず、インタプリタにおける関数の内部表現を定義しなければなりません。整数や真偽値と同じようにオブジェクトの1つとして扱います。 それから Eva […]

23 評価プロセス(環境とlet文) [オリジナル言語インタプリタを作る]

環境を使ったlet文による束縛 ここではインタプリタにlet文の対応を追加し変数束縛の機能を実装します。let文に対応するということは、合わせて識別子にも対応しなければなりません。 let a = 1; この文を評価した後、x という識別子を評価すると 1 となるようにしなければならない。つまり、”a” という識別子と 1 という値の紐づけを何かしらの方法で管理する必要があ […]

22 評価プロセス(エラー処理) [オリジナル言語インタプリタを作る]

インタプリタのエラー処理 これまでの評価の実装で NullObject を返していたところがいくつかあります。未定義の動作で全て Null を返しているところは本来エラーとしてプログラムで処理できるべきです。そうしないと利用したりあるいはデバッグするのが大変です。 ここで実装しようとしているのはユーザー定義のエラーではなく、内部のエラー処理のことです。実行中に発生しうる誤った演算子の利用、未定義の […]

21 評価プロセス(if式, return文) [オリジナル言語インタプリタを作る]

条件分岐 if式 これから条件分岐の評価、if式の評価を実装します。if式の例を示します。 if (x > y) { x } else { y } このようなif式を考えるとき、どのような時にifのブロック文が評価されるでしょうか。条件式(x > y)が true の時なのか、それともtruthlyな値(trueもしくは非Null値)であればよいのか、これは設計上の判断です。この判断は […]

20 評価プロセス(中置演算, 四則演算ほか) [オリジナル言語インタプリタを作る]

中置演算式 の評価 プログラミング言語 Gorilla がサポートする中置演算子は以下の8つです。 1 + 2; 1 - 2; 1 * 2; 1 / 2; 1 > 2; 1 < 2; 1 == 2; 1 != 2; これらの演算子は大きく2つのグループに分かれます。上4行の四則演算は結果を整数として生成するグループで、下4つの比較を行う演算は結果を真偽値で生成するグループです。 まずは […]

19 評価プロセス(前置式 “-“, “!”) [オリジナル言語インタプリタを作る]

真偽値 整数リテラルの評価に続いて真偽値リテラルの評価を実装します。とはいえやることは整数リテラルの評価とほぼ変わりません。 テストの作成 まずはテストを作成します。 [TestMethod] public void TestEvalBooleanExpression() { var tests = new(string, bool)[] { ("true;", true), ("false", […]

18 評価プロセス(リテラル) [オリジナル言語インタプリタを作る]

評価プロセス ここまでで字句解析、構文解析と終りました。ようやくREPLでいうところの E(Eval, 評価)に移ることができます。 インタプリタにおける評価のプロセスは、プログラムがどのように動作するかを定義する必要があります。 例えば以下のプログラムを例に考えます。 let num = 5; if (num) { return 1; } else { return 0; } これが 1 を返す […]

17 REPLを構文解析に対応する [オリジナル言語インタプリタを作る]

TODO を修正する (return, let) 全ての構文解析機能の実装が終了しましたが、以前作成したTODOが残ったままになっています。これを修正することで本当の完成になります。 修正する箇所は以下の2点。ParseLetStatement() と ParseReturnStatement() です。 Parsing/Parser.cs public class Parser { // .. […]

16 構文解析器の拡張(関数呼び出し式) [オリジナル言語インタプリタを作る]

関数の呼び出し式 関数の呼び出し式を解析できるようにします。以下のような使い方ができます。 let result = add(1, 2); 式なので値を返せます。 識別子の後ろに引数指定の () がある、というのが構文規則でしょうか。実はそうではありません。あらゆる式に対して関数呼び出しを行えます。 どういうことでしょうか。たとえば関数リテラルを用いた即時呼び出しも有効です。 fn (a, b) […]

15 構文解析器の拡張(関数リテラル) [オリジナル言語インタプリタを作る]

関数リテラル これまでいろいろと構文解析を実装してきました。今回は関数リテラルを解析できるようにします。 関数もまた、真偽値や整数と同じくリテラルで定義できます。関数を宣言するのではなくリテラルで扱います。 つまり識別子や整数と同じように式として定義するので、引数で渡したり return で返したりできます。 fn(x, y) { return x + y; } これが関数リテラルです。キーワード […]

1 27