erg/doc/JA/compiler/architecture.md
2023-06-19 11:28:38 +09:00

5.3 KiB

ergc のアーキテクチャ

badge

1. Erg スクリプト (.er) をスキャンし、TokenStream を生成する

src: erg_parser/lex.rs

  • parser/lexer/Lexer が TokenStream を生成する (これは Token のイテレータである。TokenStreamLexer::collect() によって生成できる)
    • LexerLexer::new または Lexer::from_str から構築される。Lexer::new はファイルまたはコマンド オプションからコードを読み取る。
    • Lexer はイテレータとしてトークンを順次生成できるので、一度に TokenStream を取得したい場合は Lexer::lex を使う。
    • LexerLexError をエラーとして出力するが、LexError 自体には表示するだけの情報がない。エラーを表示したい場合は、LexerRunner を使用してエラーを変換する。
    • Lexer を単体で使用する場合は、代わりにLexerRunner を使用します。Lexer は単なるイテレータであり、Runnable トレイトを実装していない。
      • Runnable は、 LexerRunnerParserRunnerCompiler 、および DummyVM に実装されている。

2. TokenStream -> AST

src: erg_parser/parse.rs

  • ParserLexer と同様に Parser::newParser::from_str の 2 つのコンストラクタを持ち、Parser::parseAST を返す。
  • ASTVec<Expr>のラッパー型で、「抽象構文木」を表す。

2.1 ASTの脱糖

src: erg_parser/desugar.rs

  • Desugarer
  • パターンマッチを単一の変数代入列へ変換 (Desugarer::desugar_nest_vars_pattern)
  • 複数パターン定義構文をmatchへ変換 (Desugarer::desugar_multiple_pattern_def)

2.2 ASTの並び替え・結合

src: erg_compiler/link_ast.rs

  • クラスメソッドをクラス定義に結合する
    • メソッド定義は定義ファイル外でも可能となっている
    • 現在の実装は不完全、同一ファイル内のみ

3. AST -> HIR

(主要な)ソースコード: erg_compiler/lower.rs

3.1 名前解決

現在の実装では型チェック中に行われる

  • 型推論の前に全てのAST(importされたモジュール含む)を走査し、名前解決を行う
  • 定数の循環検査や並び替えなどが行われるほか、型推論のためのContextが作成される(ただし、このContextに登録された変数の情報ははまだ殆どが未確定)

3.2 import解決

  • importに出会うと、新しくスレッドを作成して検査を行う
  • JoinHandleSharedCompilerResourceに格納され、該当モジュールが必要になったときにjoinされる
  • 使用されなかったモジュールはjoinされないことがあるが、現在のところはそのようなモジュールも全て検査される

3.3 型チェックと推論

ソースコード: erg_compiler/lower.rs

  • HIR は、すべての変数の型情報を持っており、「高レベルの中間表現」を表す。
  • ASTLowerer は Parser や Lexer と同じように構築できる。
  • ASTLowerer::lower は、CompleteArtifactIncompleteArtifactを出力する。両者ともHIRLowerWarnings を持ち、後者はLowerErrorsも持つ。
  • ASTLowererCompiler によって所有されている。ASTLowererLexerParserとは異なり、文脈を保持し、1 回限りの使い捨てではない。
  • 型推論の結果が不完全な場合(未知の型変数がある場合)、名前解決時にエラーが発生する。

4. 副作用のチェック

ソースコード: erg_compiler/effectcheck.rs

5. 所有権の確認

ソースコード: erg_compiler/ownercheck.rs

6. 最適化

ソースコード: erg_compiler/optimize.rs

  • 不要な変数(import含む)を削除する

7. リンク

ソースコード: erg_compiler/link_hir.rs

  • 全てのモジュールを読み込み、依存関係を解決し、単一のHIRに結合する

8. HIRの脱糖

ソースコード: erg_compiler/desugar_hir.rs

  • Pythonの文法と整合しない部分を変換する
    • クラスのメンバ変数を関数に変換

8. HIR からバイトコード (CodeObj) を生成

ソースコード: erg_compiler/codegen.rs