跳转到内容

ADR-0005: Primitive Type Expansion with Rust-Style Built-in Type Names

此内容尚不支持你的语言。

Accepted

ADR-0004 では、実装簡素化のために組み込み数値型を 32 ビット中心に絞る前提で整理していた。

しかし実装を進めた結果、少なくとも 32 ビット整数・浮動小数点だけでは不足することが明らかになった。

また、Sobakasu は C# 互換言語ではないが、VRChat / Unity / UdonSharp 由来の基本型を広く扱える必要がある。一方で、言語としての型名表記は Sobakasu 独自方針として Rust 風の固定幅名を維持したい。

そのため、固定幅数値型だけを最小導入する方針ではなく、実用上よく使う基本プリミティブ型を早い段階で揃える方針へ変更する。ただし、表面上の型名は C# 風別名へ寄せず、Rust 風の固定幅名で統一する。

特に以下の要求がある。

  • double 相当を扱いたい
  • 64 ビット整数 (long, ulong) 相当を扱いたい
  • bool, char, string を含む基本型を最初から揃えたい
  • C# / Unity 由来の基本型相当を広く扱いたい
  • ただし言語上の型名は Rust 風のまま維持したい

Sobakasu は組み込みプリミティブ型として以下を採用する。型名は Rust 風の固定幅表記を用いる。

  • bool
  • char
  • i8
  • i16
  • i32
  • i64
  • u8
  • u16
  • u32
  • u64
  • f32
  • f64
  • string

この ADR 時点では、これらを Sobakasu の標準的な組み込み型名として扱う。

これらは概念的には次の既知の基本型に相当する。

  • i8 ≒ sbyte
  • u8 ≒ byte
  • i16 ≒ short
  • u16 ≒ ushort
  • i32 ≒ int
  • u32 ≒ uint
  • i64 ≒ long
  • u64 ≒ ulong
  • f32 ≒ float
  • f64 ≒ double
  • bool ≒ bool
  • char ≒ char
  • string ≒ string

各型のビット幅は以下とする。

  • bool: 真偽値
  • char: 文字
  • i8: 8-bit signed integer
  • u8: 8-bit unsigned integer
  • i16: 16-bit signed integer
  • u16: 16-bit unsigned integer
  • i32: 32-bit signed integer
  • u32: 32-bit unsigned integer
  • i64: 64-bit signed integer
  • u64: 64-bit unsigned integer
  • f32: 32-bit floating-point number
  • f64: 64-bit floating-point number
  • string: 文字列

bool, char, string の内部表現や実行時表現の詳細は、将来の runtime / ABI / lowering 設計で確定する。

リテラル仕様は以下を基本方針とする。

整数リテラルは 10 進 / 2 進 / 8 進 / 16 進を許可する。

42
1_000
0b1010
0o755
0xFF

整数リテラルには型サフィックスを付与できる。

1i8
1u8
1i16
1u16
1i32
1u32
1i64
1u64

規則:

  • サフィックスなし整数リテラルの既定型は i32 とする
  • - は負数リテラルの一部ではなく単項演算子として扱う
  • _ は桁区切りとして許可する
  • 範囲外の値はコンパイルエラーとする
  • 自動昇格は行わない

つまり、2147483648 は自動で i64 にならず、サフィックスなしのままではエラーとする。

浮動小数点リテラルは小数点または指数表記を含む。

3.14
0.5
1e3
2.5e-4

浮動小数点リテラルには型サフィックスを付与できる。

3.14f32
3.14f64
10f32
10f64

規則:

  • サフィックスなし浮動小数点リテラルの既定型は f32 とする
  • f64 を使いたい場合は f64 サフィックスを明示する
  • 対象型に変換できない値はコンパイルエラーとする

3. 論理値・文字・文字列リテラル

Section titled “3. 論理値・文字・文字列リテラル”

以下を組み込みリテラルとして扱う。

true
false
'a'
"hello"

規則:

  • true と false は bool
  • 文字リテラルは char
  • 文字列リテラルは string

エスケープシーケンスや Unicode エスケープの詳細は将来の文字列 / 文字リテラル仕様で確定する。

当面の Binder では、プリミティブ型間の暗黙変換を最小限に制限する。

暫定的に許可する候補:

  • i8 -> i16 -> i32 -> i64
  • u8 -> u16 -> u32 -> u64
  • f32 -> f64

原則として禁止するもの:

  • 符号付き整数と符号なし整数の暗黙相互変換
  • 整数から浮動小数点への暗黙変換
  • 浮動小数点から整数への暗黙変換
  • 縮小変換
  • u64 から f32 / f64 への暗黙変換

変換規則の最終確定は別 ADR に分離する。

Lexer は少なくとも以下を識別できる必要がある。

  • 整数リテラル
  • 浮動小数点リテラル
  • true / false
  • 文字リテラル
  • 文字列リテラル
  • 数値型サフィックス
  • 基数接頭辞 (0b, 0o, 0x)
  • 指数表記 (e, E, +, -)

SyntaxKind には少なくとも以下を追加する。

  • IntegerLiteral
  • FloatLiteral
  • CharacterLiteral
  • TrueKeyword
  • FalseKeyword

Parser はこれらを一次式として扱う。

Binder はリテラルトークンから厳密な型付き定数を生成する。

例:

  • 123 -> i32
  • 123i64 -> i64
  • 0xFFu64 -> u64
  • 1.0 -> f32
  • 1.0f64 -> f64
  • true -> bool
  • 'A' -> char
  • "abc" -> string

IR では定数値に型情報を保持し、lowering / extern 解決 / UASM 生成時に失われないようにする。

1. 32 ビット型中心のまま維持する

Section titled “1. 32 ビット型中心のまま維持する”

問題:

  • f64, i64, u64 が早期に必要になる要求へ対応できない
  • 実用上の型カバレッジが不足する

2. C# 風型名 (int, long, float, double) を採用する

Section titled “2. C# 風型名 (int, long, float, double) を採用する”

利点:

  • Unity / C# / UdonSharp 利用者には直感的である

問題:

  • Sobakasu の型命名規則と一貫しない
  • 型幅を名前から機械的に読める一貫性が弱くなる
  • Rust 風の明示的な幅表記という設計方針から外れる

3. 範囲に応じて整数リテラルを自動昇格する

Section titled “3. 範囲に応じて整数リテラルを自動昇格する”

例:

  • 2147483648 を自動で i64 にする

問題:

  • 見た目から型が分かりにくい
  • Binder / extern 解決 / overload 解決が複雑になる
  • 診断メッセージが曖昧になりやすい
  • 基本プリミティブ型を早期に揃えたほうが、言語体験の土台が安定する
  • bool, char, string を含めることで、最小限のスクリプト記述力が大きく上がる
  • Rust 風の固定幅名は、型幅と符号が名前から一貫して分かる
  • C# / Unity / UdonSharp 由来の基本型相当を十分にカバーできる
  • 自動昇格を避けることで Binder と診断を単純に保てる
  • 今は数値トークンや型付け周りを整理している段階であり、ここで型体系をまとめて広げるのが自然である
  • 基本的な値表現を広くカバーできる
  • f64 や 64 ビット整数を必要とする API に対応しやすくなる
  • Rust 風型名を維持したまま基本型の表現力を広げられる
  • Binder / IR / extern 解決の前提となる型集合を早い段階で安定化できる
  • ADR-0004 の数値型制限を明確に更新する必要がある
  • Lexer / Parser / Binder / IR の実装範囲が広がる
  • 変換規則や演算結果型の定義を後続 ADR で詰める必要がある

ADR-0004 のうち、組み込み数値型を限定していた部分はこの ADR によって更新される。

特に以下の前提は有効ではなくなる。

  • 数値型を 32 ビット中心に限定する方針
  • 組み込み型を 32 ビット中心に限定する前提

今後は、ADR-0004 の該当箇所を改訂するか、この ADR により supersede されたものとして扱う。

初手の実装順は以下が妥当である。

  1. SyntaxKind に各リテラル種別と真偽値キーワードを追加する
  2. Lexer に整数 / 浮動小数点 / 文字 / 文字列 / 真偽値の読み取りを実装する
  3. Parser に各種リテラル式を追加する
  4. Binder にプリミティブ型付けを追加する
  5. その後に数値変換規則と演算結果型規則を別 ADR で確定する