メインコンテンツまでスキップ
バージョン: 0.2.0 snapshot

コンパイラ内部(型付き状態ABI 2)

エントリーは関数1で、型は [Result<Memory,Int>] -> [Result<Memory,Int>,Int] です。Errで新しいコンパイルを初期化し、以降は各Okが不変の状態を次の呼び出しへ渡します。戻り値にはフェーズを含めます。0は初期化、1は字句解析、2は構文解析、3/30/31/32はメタデータ検証、4は関数の検査、5は許可エフェクトの検査、50は到達可能性の解決、6はモジュールの出力計画、7はジョブの出力、99は診断、100は完了です。ドライバーは、それ以外の内部状態を解釈しません。

関数の対応表​

関数役割
1型付き状態の作成と不変の入力テーブルの初期化
901ステップの振り分け
2ホスト不要の字句解析の遷移。Int入力12個・Int出力18個
3–8診断、ゼロ埋めの領域確保、出力ジョブの追加、数値の出力、ビット演算
10–11字句解析器の初期化と入力、トークンと位置範囲の保存
12–14期待トークンの検査、関数メタデータ、反復式の構文解析
15–16上限と最大スタックを追跡する、型付きスタックのpop/push
17–21検査フレーム、分岐・反復のスナップショット、復元、合流
22–25ホストメタデータとエフェクト名の検証
26–27関数・ホストのシグネチャ適用とエフェクトの和集合
28–30関数の完了、個々の命令の検査、検査器の進行
31–32許可エフェクトの検証と、到達する関数・インポートの閉包
40–47位置範囲、型、要約、エフェクト配列、JSON引用したテキストの出力
48–52到達するホスト宣言をID順に出力
53–58到達する関数、構造化した本体、具体的な命令の出力
59–61モジュールのエクスポートの計画、出力ジョブの実行、リテラル断片の出力
62–68名目的な型宣言、レコードのフィールド、ホスト参照の検証、型の出力
100–104言語側のページ参照・更新・コピー・充填・等価比較

記号の関数同士の呼び出しには循環がありません。入力されたソースの呼び出しの循環は、Dicks自身で再帰呼び出しすることなく、コンパイラの明示的な検証フレームで検出します。構文解析には、再帰的に確保するASTオブジェクトの代わりにトークンのリンクを使います。コード生成は、検査済みのリンクをジョブスタックでたどります。

メモリーの領域​

すべてのアドレスはバイトオフセットではなく、セルの添字です。セルは符号付き64ビット整数です。メモリーレコードは16,384ページのリストを持ち、各ページは4,096個のIntセルのリストです。言語の検査付きリスト操作で範囲を強制します。更新時は永続木の経路上のノードをコピーし、変わらないブロックは共有します。各関数はメモリーレコードを受け取って返し、読み取り専用の補助関数は受け取るだけです。メモリーを読み書きするホストはありません。

開始位置内容
0–99コンパイラのフェーズ、カーソル、個数、診断、一時的なフェーズ状態
100–110永続化する字句解析器の状態11個
200構文解析器の64要素のブロックスタック(要素間隔3)
1,024トークン(要素間隔10、最大65,536)
700,000関数(要素間隔32、最大256)
720,000関数ごとの入出力型配列(要素間隔2,048)
1,250,000関数IDの参照表(添字+1、0は存在しないことを示す)
1,320,000ホストIDの参照表(添字+1、0は存在しないことを示す)
2,000,000宣言順のホストレコード(要素間隔16)
3,100,000共通化したエフェクトのテキストのポインター・長さの記録
4,200,000関数ごとのエフェクトのビット集合(1ワード60ビット)
6,000,000不変の外部ABI配列とUnicodeスカラー文字列
10,000,000名目的な型の記述子(要素間隔40)
11,000,000名目的な型IDの参照表
16,000,000再利用可能な検査用領域
48,000,000出力ジョブのスタック(要素間隔4)

トークンは、オペコード、0または正数で表す省略可能な飛距離、ソースのバイトオフセット、バイト長、行、列、閉じトークンへのリンク、elseトークンへのリンク、開始トークンへのリンク、予約フィールドを持ちます。オフセットと範囲は元のUTF-8バイト列を指し、CRLFは1つの改行です。

関数レコードは、ID、ヘッダートークン、入力ポインターと個数、出力ポインターと個数、本体の開始・終了、暗黙関数のフラグ、検証状態(未訪問・処理中・完了)、呼び出しの深さ、非同期フラグ、最大スタック、到達可能フラグを持ちます。到達不能として出力から除くものも含め、すべての定義を検査します。

検査フレームは1,320セルです。親・フレームのカーソルと未処理呼び出しのメタデータ、1,024個のスタック型、5ワードの初期化ビット、256個の固定ローカル型を持ちます。ブロックのスナップショットは2,080セルで、親・開始位置・領域の印に加え、基準スタックと最初の分岐のスタック、初期化ビットを保持します。ブロックは合流時に、関数フレームは完了時に領域の印を戻します。再利用するセルは確保時にゼロにするため、ある関数の初期化済みローカル変数や型が別の関数へ漏れることはありません。

条件分岐では、その後へ処理が続く分岐だけを合流し、スタック全体の型を比較して、初期化済みローカル変数の集合の積を取ります。固定ローカル型は両分岐で共有します。ループは本体を検証しますが、実行回数が0の場合があるため、入力時のスタックと初期化状態へ戻します。呼び出しは先に対象を検証し、エフェクト・非同期性・深さを伝播します。その後、入力型をスタックの逆順で適用し、出力型を積みます。各呼び出しのfuelと割り当て予算に収めるため、シグネチャの適用は少しずつ進めます。

出力ジョブは、種類と3つの数値オペランドを持ちます。ジョブは断片を出力するか、さらに小さなジョブを計画します。JSONテキストのジョブは、引用符・バックスラッシュ・制御文字を記号のコード内でエスケープします。任意のABIテキストが実行可能なコードになることはありません。命令のジョブは、Rustシードと同じ具体的な演算、ソースの範囲、fuelの計上地点、後片付けのブロックを出力します。