# 機能設計書 42-GDScript

## 概要

本ドキュメントは、Godot Engine専用のスクリプト言語「GDScript」について、その言語処理系の設計仕様を記載する。

### 本機能の処理概要

GDScriptは、Godot Engine専用に設計された高レベルの動的型付けプログラミング言語である。Pythonに似た構文を持ち、ゲーム開発に特化した機能（シグナル、ノードアクセス、await等）を備える。ソースコードはトークナイザ、パーサー、アナライザ、コンパイラを経てバイトコードに変換され、仮想マシン（VM）上で実行される。

**業務上の目的・背景**：ゲーム開発では迅速なプロトタイピングと直感的なコード記述が求められる。GDScriptは、C++のような低レベル言語の複雑さを排除し、ゲームロジックの記述に集中できる環境を提供する。Godotのノードシステムとの深い統合により、シーン操作やイベント駆動プログラミングが容易に行える。

**機能の利用シーン**：
- ゲームロジック（プレイヤー操作、AI、ゲームルール）の実装
- UI/UXの動的な制御
- シーン間のデータ受け渡しと状態管理
- カスタムリソースやツールスクリプトの作成
- エディタ拡張プラグインの開発

**主要な処理内容**：
1. ソースコードの字句解析（トークナイズ）
2. 構文解析（パース）によるAST生成
3. 意味解析（型チェック、名前解決）
4. バイトコードへのコンパイル
5. 仮想マシンでのバイトコード実行
6. Language Server Protocol（LSP）によるエディタ支援

**関連システム・外部連携**：スクリプトエディタ、デバッガー、プロファイラー、シーンツリー、シグナルシステムと連携する。

**権限による制御**：`@tool`アノテーションによりエディタ内での実行が可能。`@abstract`で抽象クラスを定義可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 5 | スクリプトエディタ | 主機能 | GDScriptコードの編集・構文ハイライト・補完 |
| 15 | デバッガ | 補助機能 | GDScriptデバッグ情報の解析・表示 |
| 30 | スクリプト作成ダイアログ | 主機能 | 新規GDScriptファイルの作成 |

## 機能種別

計算処理 / スクリプト実行エンジン

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| source_code | String | Yes | GDScriptソースコード | UTF-8エンコード |
| script_path | String | No | スクリプトファイルパス | res://形式のパス |
| for_completion | bool | No | コード補完モードで解析 | - |
| parse_body | bool | No | 関数本体を解析するか | デフォルトtrue |

### 入力データソース

- .gdファイル（テキスト形式）
- .gdcファイル（バイナリトークン形式）
- エディタ上でのリアルタイム入力

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| GDScript | Script | コンパイル済みスクリプトリソース |
| errors | List<ParserError> | パースエラー一覧 |
| warnings | List<GDScriptWarning> | 警告一覧 |
| bytecode | Vector<uint8_t> | コンパイル済みバイトコード |

### 出力先

- スクリプトリソースとしてシーンに埋め込み
- 外部.gdファイルとして保存
- .gdcバイナリ形式でエクスポート

## 処理フロー

### 処理シーケンス

```
1. ソースコード読み込み
   └─ load_source_code()でファイルからテキスト取得

2. 字句解析（Tokenization）
   └─ GDScriptTokenizerでトークン列に分解
   └─ キーワード、識別子、リテラル、演算子を識別

3. 構文解析（Parsing）
   └─ GDScriptParserでAST（抽象構文木）を構築
   └─ クラス、関数、変数、式の構造を解析

4. 意味解析（Analysis）
   └─ GDScriptAnalyzerで型チェック・名前解決
   └─ 継承関係、シグナル接続の検証

5. コード生成（Compilation）
   └─ GDScriptCompilerでバイトコード生成
   └─ GDScriptFunctionオブジェクトを作成

6. 実行
   └─ GDScript VMでバイトコードを逐次実行
   └─ 関数呼び出し、演算、オブジェクト操作
```

### フローチャート

```mermaid
flowchart TD
    A[ソースコード入力] --> B[GDScriptTokenizer]
    B --> C{トークン解析成功?}
    C -->|No| D[字句エラー]
    C -->|Yes| E[GDScriptParser]
    E --> F{構文解析成功?}
    F -->|No| G[構文エラー]
    F -->|Yes| H[AST生成]
    H --> I[GDScriptAnalyzer]
    I --> J{意味解析成功?}
    J -->|No| K[型エラー/名前解決エラー]
    J -->|Yes| L[GDScriptCompiler]
    L --> M[バイトコード生成]
    M --> N[GDScriptFunction]
    N --> O[VM実行]
    D --> P[エラー報告]
    G --> P
    K --> P
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-42-01 | インデントベース構文 | タブまたはスペース4個でブロックを表現 | 常時 |
| BR-42-02 | クラス継承 | extends キーワードで単一継承 | クラス定義時 |
| BR-42-03 | 型推論 | 変数宣言時に型注釈なしでも使用可能 | 変数定義時 |
| BR-42-04 | 静的型付け | :型名 または := で型を明示・推論 | 型安全コード記述時 |
| BR-42-05 | @toolアノテーション | エディタ内でスクリプト実行を許可 | エディタツール開発時 |

### 計算ロジック

- 演算子優先順位はPrecedence enumで定義（PREC_NONE〜PREC_PRIMARY）
- 型変換は暗黙的変換と明示的キャスト（as演算子）をサポート

## データベース操作仕様

本機能はデータベース操作を行わない（インメモリ処理）。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| PARSE_ERROR | 構文エラー | 不正なトークン配置 | コード修正 |
| TYPE_ERROR | 型エラー | 型の不一致 | 型注釈の修正または明示的キャスト |
| NAME_ERROR | 名前エラー | 未定義の識別子参照 | 変数/関数定義を確認 |
| CYCLIC_DEPENDENCY | 循環参照 | preloadの循環 | 依存関係の見直し |

### リトライ仕様

該当なし（コンパイルエラーは即座に報告）

## トランザクション仕様

該当なし

## パフォーマンス要件

- コード補完: リアルタイム応答（<100ms目標）
- スクリプトリロード: ホットリロード対応
- VM実行: ネイティブC++呼び出しによる高速化

## セキュリティ考慮事項

- sandboxed実行（OS直接アクセス制限）
- エクスポート時のスクリプト暗号化オプション
- @toolスクリプトはエディタ権限で実行

## 備考

- GDScript 2.0（Godot 4.x）では型付けが強化
- Language Server Protocol対応でVSCode等の外部エディタ連携

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、GDScriptの核となるデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | gdscript.h | `modules/gdscript/gdscript.h` | GDScript, GDScriptInstance, GDScriptLanguageクラスの定義 |
| 1-2 | gdscript_parser.h | `modules/gdscript/gdscript_parser.h` | ASTノード定義（ClassNode, FunctionNode, ExpressionNode等） |
| 1-3 | gdscript_function.h | `modules/gdscript/gdscript_function.h` | GDScriptFunctionクラス、バイトコード命令定義 |

**読解のコツ**: GDScriptはScriptクラスを継承しており、Godotの汎用スクリプトインターフェースに準拠している。`member_functions`ハッシュマップがメンバー関数を保持。

#### Step 2: 字句解析（Tokenizer）を理解する

ソースコードからトークン列を生成する処理。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | gdscript_tokenizer.h | `modules/gdscript/gdscript_tokenizer.h` | Token構造体、Token::Type enum（約100種類のトークン） |
| 2-2 | gdscript_tokenizer.cpp | `modules/gdscript/gdscript_tokenizer.cpp` | scan_token()メソッド |

**主要処理フロー**:
1. **Token::Type enum**: IF, FOR, FUNC等のキーワードトークン
2. **scan_token()**: 文字列を走査してトークンを識別

#### Step 3: 構文解析（Parser）を理解する

トークン列からASTを構築する処理。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | gdscript_parser.h | `modules/gdscript/gdscript_parser.h` | Node基底クラス、各種ASTノード |
| 3-2 | gdscript_parser.cpp | `modules/gdscript/gdscript_parser.cpp` | parse_program(), parse_class(), parse_function() |

**主要処理フロー**:
- **295-337行目（Node enum）**: ANNOTATION〜WHILEまでのノードタイプ定義
- **557-802行目（ClassNode）**: クラス構造を表現するノード
- **850-878行目（FunctionNode）**: 関数定義ノード

#### Step 4: 意味解析（Analyzer）を理解する

型チェックと名前解決を行う処理。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | gdscript_analyzer.h | `modules/gdscript/gdscript_analyzer.h` | GDScriptAnalyzerクラス |
| 4-2 | gdscript_analyzer.cpp | `modules/gdscript/gdscript_analyzer.cpp` | resolve_*メソッド群 |

**主要処理フロー**:
- resolve_class_interface(): クラスメンバーの型解決
- resolve_function_signature(): 関数シグネチャの解決
- reduce_expression(): 式の型推論

#### Step 5: コンパイル（Compiler）を理解する

ASTからバイトコードを生成する処理。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | gdscript_compiler.h | `modules/gdscript/gdscript_compiler.h` | GDScriptCompilerクラス、CodeGen構造体 |
| 5-2 | gdscript_compiler.cpp | `modules/gdscript/gdscript_compiler.cpp` | compile(), _parse_expression() |

**主要処理フロー**:
- **179行目**: compile()エントリーポイント
- _parse_expression(): 式をバイトコードに変換
- _parse_block(): ブロック（スイート）をコンパイル

#### Step 6: 仮想マシン（VM）を理解する

バイトコードを実行する処理。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 6-1 | gdscript_vm.cpp | `modules/gdscript/gdscript_vm.cpp` | call()メソッド、オペコード実行ループ |

**主要処理フロー**:
- 巨大なswitch文でオペコードをディスパッチ
- スタックベースの演算実行

### プログラム呼び出し階層図

```
ResourceFormatLoaderGDScript::load()
    │
    └─ GDScript::reload()
           │
           ├─ GDScriptTokenizer::set_source_code()
           │      └─ scan_token() [字句解析]
           │
           ├─ GDScriptParser::parse()
           │      ├─ parse_program() [構文解析]
           │      ├─ parse_class()
           │      └─ parse_function()
           │
           ├─ GDScriptAnalyzer::analyze()
           │      ├─ resolve_class_interface()
           │      ├─ resolve_function_signature()
           │      └─ resolve_function_body()
           │
           └─ GDScriptCompiler::compile()
                  ├─ _compile_class()
                  ├─ _parse_function()
                  │      └─ _parse_expression()
                  └─ GDScriptFunction [バイトコード]

GDScriptInstance::callp()
    │
    └─ GDScriptFunction::call()
           └─ [VM実行ループ] gdscript_vm.cpp
```

### データフロー図

```
[入力]                    [処理]                           [出力]

.gd ソースコード ───▶ GDScriptTokenizer ───▶ Token列
                              │
                              ▼
                       GDScriptParser ───▶ AST
                              │
                              ▼
                       GDScriptAnalyzer ───▶ 型付きAST
                              │
                              ▼
                       GDScriptCompiler ───▶ GDScriptFunction
                              │                  (バイトコード)
                              ▼
                       GDScript VM ───▶ 実行結果
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| gdscript.h | `modules/gdscript/gdscript.h` | ヘッダー | GDScript/GDScriptLanguageクラス定義 |
| gdscript.cpp | `modules/gdscript/gdscript.cpp` | ソース | スクリプトクラス実装 |
| gdscript_tokenizer.h | `modules/gdscript/gdscript_tokenizer.h` | ヘッダー | トークナイザ定義 |
| gdscript_tokenizer.cpp | `modules/gdscript/gdscript_tokenizer.cpp` | ソース | 字句解析実装 |
| gdscript_parser.h | `modules/gdscript/gdscript_parser.h` | ヘッダー | パーサー/ASTノード定義 |
| gdscript_parser.cpp | `modules/gdscript/gdscript_parser.cpp` | ソース | 構文解析実装 |
| gdscript_analyzer.h | `modules/gdscript/gdscript_analyzer.h` | ヘッダー | アナライザ定義 |
| gdscript_analyzer.cpp | `modules/gdscript/gdscript_analyzer.cpp` | ソース | 意味解析実装 |
| gdscript_compiler.h | `modules/gdscript/gdscript_compiler.h` | ヘッダー | コンパイラ定義 |
| gdscript_compiler.cpp | `modules/gdscript/gdscript_compiler.cpp` | ソース | コード生成実装 |
| gdscript_function.h | `modules/gdscript/gdscript_function.h` | ヘッダー | 関数/バイトコード定義 |
| gdscript_function.cpp | `modules/gdscript/gdscript_function.cpp` | ソース | 関数実装 |
| gdscript_vm.cpp | `modules/gdscript/gdscript_vm.cpp` | ソース | 仮想マシン実装 |
| gdscript_cache.h | `modules/gdscript/gdscript_cache.h` | ヘッダー | スクリプトキャッシュ |
| gdscript_cache.cpp | `modules/gdscript/gdscript_cache.cpp` | ソース | キャッシュ実装 |
| gdscript_warning.h | `modules/gdscript/gdscript_warning.h` | ヘッダー | 警告定義 |
| gdscript_warning.cpp | `modules/gdscript/gdscript_warning.cpp` | ソース | 警告実装 |
| editor/gdscript_highlighter.cpp | `modules/gdscript/editor/gdscript_highlighter.cpp` | ソース | 構文ハイライト |
| language_server/ | `modules/gdscript/language_server/` | ディレクトリ | LSP実装 |
