# 機能設計書 74-mrbcコマンド

## 概要

本ドキュメントは、mrubyコンパイラコマンド（mrbc）の設計について記述する。Rubyソースコードをmrubyバイナリ形式（.mrb）またはCソースにコンパイルするコマンドラインツールである。

### 本機能の処理概要

mrbcコマンドは、Rubyソースファイルを読み込み、パース・コード生成を行い、結果をRiteBinary形式（.mrb）またはCソースコード形式で出力する。複数ファイルのコンパイル、構文チェック、デバッグ情報付与等の機能を提供する。

**業務上の目的・背景**：mrubyスクリプトを事前コンパイルすることで、実行時のパース処理を省略し高速な起動を実現する。また、Cソース出力により組み込みシステムへのスクリプト埋め込みが可能になる。

**機能の利用シーン**：スクリプトの事前コンパイル、組み込みシステム向けCソース生成、スクリプトの構文チェック、ビルドシステムでのコンパイルステップ。

**主要な処理内容**：
1. コマンドライン引数の解析（-o, -B, -S, -c, -g, -s等）
2. 入力ファイルの読み込みとパース（複数ファイル対応）
3. バイトコード（irep）への変換
4. RiteBinary(.mrb)/Cソース(.c)/C構造体の出力

**関連システム・外部連携**：mruby-compilerのパーサ・コードジェネレータに依存。

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | コマンドラインツール。画面なし |

## 機能種別

コンパイラ / コマンドラインツール

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| -c | フラグ | No | 構文チェックのみ | - |
| -o outfile | 文字列 | No | 出力ファイル名指定（複数ファイル時は必須） | - |
| -v | フラグ | No | バージョン表示＋詳細モード | - |
| -g | フラグ | No | デバッグ情報を付与 | - |
| -B symbol | 文字列 | No | Cソース出力時のシンボル名 | 空文字列でないこと |
| -S | フラグ | No | C構造体形式でダンプ（-B必須） | - |
| -s | フラグ | No | static変数として定義 | - |
| --remove-lv | フラグ | No | ローカル変数情報を除去 | - |
| --no-ext-ops | フラグ | No | OP_EXT使用を禁止 | - |
| --no-optimize | フラグ | No | ピープホール最適化を無効化 | - |
| programfile | 文字列 | Yes | 入力Rubyソースファイル（複数指定可） | - |

### 入力データソース

- Rubyソースファイル（.rb）
- 標準入力（ファイル名"-"指定時）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| RiteBinary | バイナリ | .mrbファイル |
| Cソース | テキスト | Cの配列初期化子形式 |
| C構造体 | テキスト | C構造体形式 |

### 出力先

ファイル（-oで指定）または標準出力（"-"指定時）。

## 処理フロー

### 処理シーケンス

```
1. mrb_open_core() で最小限のVM初期化
2. parse_args() でコマンドライン引数を解析
3. 出力ファイル名を決定
   ├─ -o指定あり → そのまま使用
   ├─ -B指定あり → 拡張子.c
   └─ それ以外 → 拡張子.mrb
4. load_file() でソースをパース（no_exec=TRUE）
   ├─ 複数ファイル → partial_hookで連結
   └─ 単一ファイル → 直接パース
5. dump_file() で出力
   ├─ -B指定あり → mrb_dump_irep_cfunc/cstruct
   └─ -B未指定 → mrb_dump_irep_binary
6. cleanup() でリソース解放
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[mrb_open_core]
    B --> C[parse_args]
    C --> D{解析成功?}
    D -->|No| E[usage表示→終了]
    D -->|Yes| F[出力ファイル名決定]
    F --> G[load_file]
    G --> H{パース成功?}
    H -->|No| I[エラー終了]
    H -->|Yes| J{-c指定?}
    J -->|Yes| K[Syntax OK→終了]
    J -->|No| L[dump_file]
    L --> M{-B指定?}
    M -->|Yes, -S| N[mrb_dump_irep_cstruct]
    M -->|Yes| O[mrb_dump_irep_cfunc]
    M -->|No| P[mrb_dump_irep_binary]
    N --> Q[cleanup→終了]
    O --> Q
    P --> Q
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-74-1 | 最小VM | mrb_open_core()で最小限のVM初期化（gem不要） | 常時 |
| BR-74-2 | 複数ファイル | 複数ファイル指定時はpartial_hookで連結パース | args->idx < args->argc |
| BR-74-3 | 出力形式自動決定 | -B未指定なら.mrb、指定なら.cが出力拡張子 | -o未指定時 |
| BR-74-4 | 複数ファイル時-o必須 | 2つ以上のファイル指定時は-oオプションが必須 | ファイル数 > 1 かつ -o未指定 |

### 計算ロジック

特になし。

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

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| EXIT_FAILURE | 初期化失敗 | mrb_open_coreがNULLを返した場合 | stderrにメッセージ出力 |
| EXIT_FAILURE | ファイルオープン失敗 | 入力/出力ファイルが開けない場合 | stderrにメッセージ出力 |
| EXIT_FAILURE | 入力なし | プログラムファイルが指定されていない場合 | "no program file given" |
| EXIT_FAILURE | ダンプエラー | mrb_dump_irep_*がMRB_DUMP_OKでない場合 | エラーコード表示 |
| -1 | 不正シンボル名 | MRB_DUMP_INVALID_ARGUMENT | "invalid C language symbol name" |

### リトライ仕様

リトライは不要。

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

該当なし。

## パフォーマンス要件

特に定義されていない。

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

- MRB_NO_STDIO定義時はコンパイルエラーとなる

## 備考

- stub.cはmrbcをスタンドアロンバイナリとしてビルドするためのスタブ（mrb_init_mrblib/mrb_init_mrbgemsの空実装）
- -Eオプションは廃止済み（メッセージのみ表示）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | mrbc.c | `mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c` | struct mrbc_args定義（17-30行目） |

**読解のコツ**: dump_struct/check_syntax等のビットフィールドとflags（MRB_DUMP_*フラグ）の使い分けに注目。flagsはダンプ時のオプションを累積する。

#### Step 2: エントリーポイント（main関数）を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | mrbc.c | `mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c` | main関数（283-350行目） |

**主要処理フロー**:
1. **286行目**: mrb_open_core()で最小VM
2. **295行目**: parse_argsで引数解析
3. **305-307行目**: 出力ファイル名の自動生成
4. **316行目**: load_fileでパース
5. **343行目**: dump_fileで出力

#### Step 3: 複数ファイルのパースメカニズムを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | mrbc.c | `mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c` | load_file関数（218-255行目） |
| 3-2 | mrbc.c | `mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c` | partial_hook関数（197-216行目） |

**主要処理フロー**:
- **243-246行目**: 残りファイルがある場合、partial_hookを設定
- **198-215行目**: partial_hookが次のファイルを開いてパーサに渡す

#### Step 4: ダンプ処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | mrbc.c | `mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c` | dump_file関数（257-281行目） |

**主要処理フロー**:
- **263-269行目**: -B指定時のCソース出力（cfunc/cstruct）
- **275行目**: バイナリ出力

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

```
main
    ├─ mrb_open_core
    ├─ parse_args
    ├─ get_outfilename (出力ファイル名決定)
    ├─ load_file
    │   ├─ mrb_ccontext_new
    │   ├─ mrb_ccontext_partial_hook (複数ファイル時)
    │   ├─ mrb_load_file_cxt
    │   └─ partial_hook (コールバック)
    │       └─ fopen (次ファイル)
    ├─ dump_file
    │   ├─ mrb_dump_irep_cstruct (-B -S)
    │   ├─ mrb_dump_irep_cfunc (-B)
    │   └─ mrb_dump_irep_binary (デフォルト)
    └─ cleanup
        ├─ mrb_free
        └─ mrb_close
```

### データフロー図

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

Rubyソース ────▶ mrb_load_file_cxt ──────▶ RProc (irep)
  (.rb)              │                          │
                     ▼                          ▼
              partial_hook ──────────▶ 複数ファイル連結
                                         │
                                         ▼
                                    dump_file
                                    ├─▶ .mrb (バイナリ)
                                    ├─▶ .c (Cソース)
                                    └─▶ .c (C構造体)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| mrbc.c | `mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c` | ソース | mrbcコマンドのメイン実装 |
| stub.c | `mrbgems/mruby-bin-mrbc/tools/mrbc/stub.c` | ソース | スタンドアロンビルド用スタブ |
| mrbgem.rake | `mrbgems/mruby-bin-mrbc/mrbgem.rake` | 設定 | gem定義ファイル |
| mrbc.rb | `mrbgems/mruby-bin-mrbc/bintest/mrbc.rb` | テスト | 統合テスト |
