0.2のデータ型
既存の35命令の意味は変わりません。モジュール内で有効な名目的な型を、明示的な関数定義より前で宣言します。IDは5〜65535です。基本型のIDは1:Int、2:Bool、3:Text、4:Jsonのままです。型宣言は先に宣言した型だけを参照でき、再帰的なレイアウトは作れません。宣言数は最大256、入れ子の深さは16、レコードのフィールド数は32です。
逆アセンブル時の表記例です。実行するファイルは引き続き記号だけで書きます。
type(5) list.type(1)はIntのリストを宣言します。type(6) record.type(2) int(1) int(3)はIntとTextのフィールドを持つレコードを宣言します。type(7) result.type int(6) int(1)はResult<Record6,Int>を宣言します。
関数シグネチャは通常の int(type) でこれらのIDを参照します。型は名目的に区別します。同じ要素型を持つリストでも、別々に宣言した型は異なる型です。ホストABIの参照は {"Ref":5} を使い、コンパイルするモジュール内で解決します。型宣言は不変のモジュールメタデータとして出力します。
| オペコード | 名前 | 飛距離 | スタックの動作 |
|---|---|---|---|
| 36 | type | IDが必須 | モジュールの型宣言の開始 |
| 37 | list.type | 要素型が必須 | リストの型記述 |
| 38 | record.type | フィールド数を省略可能 | 指定した数のint(type)が続く |
| 39 | result.type | なし | 成功型とエラー型のint(type)が続く |
| 40 | list.new | リスト型が必須 | [] -> [List<T>] |
| 41 | list.push | なし | [List<T>,T] -> [List<T>] |
| 42 | list.at | なし | [List<T>,Int] -> [T]、添字を検査 |
| 43 | list.set | なし | [List<T>,Int,T] -> [List<T>]、添字を検査 |
| 44 | list.length | なし | [List<T>] -> [Int] |
| 45 | record.new | レコード型が必須 | [fields...] -> [Record] |
| 46 | field.get | 1始まりのフィールド番号が必須 | [Record] -> [field type] |
| 47 | field.set | 1始まりのフィールド番号が必須 | [Record,value] -> [Record] |
| 48 | result.ok | Result型が必須 | [ok value] -> [Result] |
| 49 | result.err | Result型が必須 | [error value] -> [Result] |
| 50 | result.is_ok | なし | [Result] -> [Bool] |
| 51 | result.value | なし | [Result] -> [ok value]、Errならトラップ |
| 52 | result.error | なし | [Result] -> [error value]、Okならトラップ |
| 53 | list.try | Result<T,Int>型が必須 | [List<T>,Int] -> [Result<T,Int>]、Errは不正な添字を保持 |
| 54 | list.fill | リスト型が必須 | [T,Int] -> [List<T>]、不変の値を反復 |
| 55 | result.match | なし | Resultを消費し、thenはOkの値、必須のelseはErrの値を受け取る。両分岐を検査 |
| 56 | list.copy | なし | [target,to,source,from,count] -> [List<T>]、最大4096要素 |
| 57 | list.range_eq | なし | 同じ入力 -> [Bool]、Int・Bool・Textの要素のみ |
値は不変です。リストの更新には永続基数木を使い、更新前のリストは変わりません。レコードのフィールド更新も新しいレコードを返します。Resultのパターン分岐は両方の種類を処理し、終了時のスタックが一致しなければなりません。nullになり得る参照や暗黙の型変換はありません。構造化された値の等価比較とJsonへの変換は、アプリケーションで明示的に実装します。
リストの上限は1,048,576要素です。作成と更新のための割り当ては、既存のランタイム割り当て予算に計上します。不正な添字、Resultの種類の取り違え、コレクションの上限超過では、安定した実行時診断を返します。ホストが生成した構造化値は検証して凍結します。検証済みの不変値なら、同じモジュールの境界を深いコピーなしで通過できます。共有するのは値であり、変更可能なホストメモリーではありません。
一括操作では空の範囲も含め、コピーの前に両方の範囲を検証します。コピー元は不変のスナップショットなので、範囲が重なっていてもコピーの意味を保ちます。木のブロック全体に揃う部分は共有し、一部だけを使うブロックはコピーします。範囲の等価比較は基本型の値を比較し、オブジェクトの同一性は比較しません。