私の最初の言語フロントエンドとLLVMのチュートリアル

前提条件:このチュートリアルは、C++の知識があることを前提としていますが、コンパイラの経験は必要ありません。

「私の最初の言語フロントエンドとLLVM」チュートリアルへようこそ。ここでは、シンプルな言語の実装を通して、それがいかに楽しく簡単であるかを示します。このチュートリアルでは、迅速に作業を開始し、LLVMを使用してコードを生成する具体的な例を示します。

このチュートリアルでは、シンプルな「Kaleidoscope」言語を紹介し、いくつかの章にわたって反復的に構築することで、時間の経過とともにどのように構築されるかを示します。これにより、幅広い言語設計とLLVM固有のアイデアを網羅し、その過程でコードをすべて表示して説明し、最初に大量の詳細を提示することを削減できます。このコードを使って作業することを強くお勧めします - コピーを作成して変更し、実験してください。

警告:コンパイラ技術とLLVMのみに焦点を当てるため、このチュートリアルではソフトウェアエンジニアリングのベストプラクティスは示していません。たとえば、コードはグローバル変数を広範に使用し、ビジターパターンを使用していません。しかし、代わりに、シンプルさを保ち、当面のトピックに焦点を当てています。

このチュートリアルは、個々のトピックを網羅する章に構成されているため、必要に応じて先に進むことができます。

  • 第1章:Kaleidoscope言語と字句解析器 - どこを目指していて、構築したい基本的な機能を示します。字句解析器は言語のパーサー構築の最初の部分でもあります。そして、理解しやすいシンプルなC++字句解析器を使用します。

  • 第2章:パーサーとASTの実装 - 字句解析器が整ったら、構文解析技術と基本的なAST構築について説明できます。このチュートリアルでは、再帰下降構文解析と演算子優先順位構文解析について説明します。

  • 第3章:LLVM IRへのコード生成 - ASTの準備ができたら、LLVM IRを生成するのがいかに簡単かを示し、プロジェクトにLLVMを組み込む簡単な方法を示します。

  • 第4章:JITと最適化サポートの追加 - LLVMの優れた機能の1つはJITコンパイルのサポートであるため、すぐにその機能に深く掘り下げ、JITサポートを追加するために必要な3行のコードを示します。後の章では、.oファイルの生成方法を示します。

  • 第5章:言語の拡張:制御フロー - 基本的な言語が動作したら、制御フロー操作(「if」文と「for」ループ)を使用して拡張する方法を示します。これにより、SSA構築と制御フローについて説明する機会が得られます。

  • 第6章:言語の拡張:ユーザー定義演算子 - この章では、ユーザーが任意の一項演算子と二項演算子を定義できるように言語を拡張します - 割り当て可能な優先順位付き!これにより、「言語」の重要な部分をライブラリルーチンとして構築できます。

  • 第7章:言語の拡張:変更可能な変数 - この章では、代入演算子とともにユーザー定義のローカル変数の追加について説明します。これにより、LLVMでSSA形式を構築するのがいかに簡単かがわかります。LLVMでは、使用するためにフロントエンドでSSA形式を構築する必要はありません!

  • 第8章:オブジェクトファイルへのコンパイル - この章では、LLVM IRを取得して静的コンパイラのようにオブジェクトファイルにコンパイルする方法について説明します。

  • 第9章:デバッグ情報 - 本格的な言語ではデバッガーをサポートする必要があるため、Kaleidoscope関数にブレークポイントを設定し、引数変数をプリントアウトし、関数を呼び出すことができるデバッグ情報を追加します!

  • 第10章:結論とその他の詳細 - この章では、言語を拡張する方法について説明し、ガベージコレクションのサポート、例外、デバッグ、「スパゲッティスタック」のサポートなどの「特殊なトピック」に関する情報のポインタを含めてシリーズを締めくくります。

チュートリアルの最後までに、1000行未満の(コメント、空白行を除く)コード行を作成します。この少量のコードで、手書きの字句解析器、パーサー、AST、および静的およびJITの両方のコード生成サポートを含む、非自明な言語の優れた小型コンパイラーを構築します。この幅広さは、LLVMの強さを示す素晴らしい証であり、それが言語設計者や高性能コード生成を必要とする人々に人気のあるターゲットである理由を示しています。