butterfly dream

FX自動取引のための時系列分析・信号処理・戦略ブログ

科学技術計算用プログラミング言語:Sci-Lispの自作(3日目):言語開発のロードマップ

chaploud-blog.hatenablog.com

github.com

Sci-Lisp自作の3日目です。もともとはネット上の情報を拾い集めて言語(とそのインタプリタコンパイラ)を作成をしようとしていたのですが、ちょうとAmazonブラックフライデーに以下の本が推薦されて出てきたので思わず買ってしまいました。

インタプリタの作り方 -言語設計/開発の基本と2つの方式による実装

CRAFTING INTERPRETERS

ちなみにこちら、英文ですがWeb上で無料公開もされています。レビューを見るに大変な良書のようです。

craftinginterpreters.com

言語開発のロードマップ

さて、この本を頭から読んでいくだけでもかなり時間を要するので、Sci-Lisp開発とは同時並行で読み進めたいと思っていますが、2章にプログラミング言語開発(インタプリタ実装)についての概観がまとまっていましたので、紹介します。

言語開発のロードマップ

  1. 字句解析(Scanning)
  2. 構文解析(Parsing)
  3. 静的分析・意味分析(Analysis)
  4. 中間表現(Intermediate Representations)
  5. 最適化(Optimizing)
  6. コード生成(Code Generation)
  7. 仮想マシン(Virtual Machine)
  8. ランタイム(Runtime)

次のテキストに処理を施していくことを考えます。

var agerage = (min + max) / 2;

1. 字句解析(Scanning)

スキャナによって、コメントや空白を読み捨て、意味のあるトークンだけの純粋なシーケンスを残す。

var average = ( min + max ) / 2 ;

2. 構文解析(Parsing)

パーサによって、トークンの並びを受け取って、文法の入れ子構造を反映した木構造を構築する。これは「構文解析木」(parse tree)とも「抽象構文木」(abstract syntax tree: AST)とも呼ばれる。構文エラーがあれば、ここで報告される。

3. 静的分析・意味分析(Analysis)

変数や関数、文が何を参照しているかを、スコープに応じて明らかにする。型チェックをする言語であれば、ここで行う。

4. 中間表現(Intermediate Representation:IR)

ソース言語ごとにIRを生成するフロントエンドを1つずつ作り、ターゲットのアーキテクチャx86, ARM,...)ごとにバックエンドを1つずつ書けば、少ない労力でサポートすることができる。

5. 最適化(Optimizing)

ユーザーのプログラムが何を意味するのかを理解したら、それと同じセマンティクスを保ちながら、もっと実行効率の良い別のプログラムと自由に交換することができる。

pennyArea = 3.14159 * (0.75 / 2) * (0.75 / 2);
⇒ pennyArea = 0.4417860938;

6. コード生成(Code Generation)

マシンが実行できる形式に変換(アセンブリ機械語VM用のバイトコード等)する処理。

7. 仮想マシン(Virtual Machine)

架空のチップをエミュレートし、命令実行をランタイムでシミュレートする。ネイティブコードに変換した場合より遅くなるが、単純さと移植性が得られる。

8. ランタイム(Runtime)

ガベージコレクタやオブジェクトの種類を調べる等、実行時に行う作業。完全にコンパイルされる言語では、結果として生成される実行ファイルにランタイムの実装コードが直接挿入される。Go言語ならGoランタイムのコピーが直接埋め込まれ、VM内で実行される言語(Java, Python, JavaScript)ならランタイムはVMに含まれる。

終わりに

このインタプリタの作り方という書籍は、Sci-Lispが初めてβ版として公開されるまでには一度は読み通しておく必要があると感じました。長く果てしない道のりにも感じますが、今回紹介したロードマップを浮かべて、今自分がどの位置にいるのかを把握しておけば幾ばくか安心感を得られます。