# 機能設計書 75-mirbコマンド

## 概要

本ドキュメントは、mrubyの対話型シェル（REPL: Read-Eval-Print Loop）であるmirbコマンドの設計について記述する。ユーザがRubyコードを対話的に入力し、即座に実行結果を確認できる環境を提供する。

### 本機能の処理概要

mirbコマンドは、端末からの入力を受け取り、パース・コンパイル・実行・結果表示を繰り返す対話型シェルである。マルチラインエディタ、構文ハイライト、タブ補完、履歴管理等の高度な端末機能を備える。

**業務上の目的・背景**：mrubyの学習、プロトタイピング、デバッグ時にコードを対話的に実行できる環境が必要。CRubyのirbに相当し、開発者がコードの動作を即座に確認するための重要なツールである。

**機能の利用シーン**：mrubyの構文学習、API動作確認、小規模なスクリプトのプロトタイピング、ライブラリの動作検証。

**主要な処理内容**：
1. Read: マルチラインエディタまたは簡易入力でコード入力
2. Eval: パース→コード生成→VM実行
3. Print: 実行結果のinspect出力（構文ハイライト付き）
4. Loop: 上記を繰り返し
5. コード完成度判定による複数行入力サポート
6. タブ補完による入力支援
7. 入力履歴の管理

**関連システム・外部連携**：端末エミュレータ（ANSI対応）、mruby-compilerに依存。

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

## 関連画面

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

## 機能種別

対話型シェル（REPL） / コマンドラインツール

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| -d | フラグ | No | デバッグモード（$DEBUG=true） | - |
| -r library | 文字列 | No | 事前ライブラリ読み込み | ライブラリパスが指定されていること |
| -v | フラグ | No | バージョン表示＋詳細モード | - |
| --verbose | フラグ | No | 詳細モード | - |
| --version | フラグ | No | バージョン表示して終了 | - |
| --copyright | フラグ | No | 著作権表示して終了 | - |
| programfile | 文字列 | No | 入力ファイル（非対話モード） | - |
| Rubyコード | 文字列 | Yes | 対話入力されるRubyコード | - |

### 入力データソース

- 端末からのキーボード入力（マルチラインエディタ経由）
- ファイル入力（programfile指定時）
- 標準入力

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 結果出力 | String | 実行結果のinspect表示（ハイライト付き） |
| エラー出力 | String | 例外メッセージとバックトレース |
| プロンプト | String | "N> "（通常）/"N* "（継続行） |

### 出力先

標準出力。

## 処理フロー

### 処理シーケンス

```
1. mrb_open() でVM初期化
2. parse_args() で引数解析
3. -r ライブラリ読み込み
4. _ 変数の初期化（MRB_NO_MIRB_UNDERSCORE未定義時）
5. マルチラインエディタ初期化（ttyの場合）
6. REPLループ:
   a. プロンプト表示＋入力受付
   b. quit/exit判定
   c. パース（mrb_parser_parse）
   d. コード完成度判定（is_code_block_open）
      - 未完: 継続行として追加入力
      - 完成: 次へ
   e. コード生成（mrb_generate_code）
   f. VM実行（mrb_vm_run）
   g. 結果表示（inspect）/ エラー表示
   h. 履歴追加
7. クリーンアップ・終了
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[mrb_open]
    B --> C[parse_args]
    C --> D[ライブラリ読み込み]
    D --> E[エディタ初期化]
    E --> F[プロンプト表示]
    F --> G[入力受付]
    G --> H{quit/exit?}
    H -->|Yes| I[終了]
    H -->|No| J[パース]
    J --> K{コード完成?}
    K -->|No| L[継続行モード]
    L --> F
    K -->|Yes| M{構文エラー?}
    M -->|Yes| N[エラー表示]
    M -->|No| O[コード生成]
    O --> P[VM実行]
    P --> Q{例外?}
    Q -->|Yes| R[例外表示]
    Q -->|No| S[結果表示]
    N --> F
    R --> F
    S --> F
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-75-1 | コード完成度判定 | パーサの状態から複数行入力の要否を判定する | 入力のたびに実行 |
| BR-75-2 | _変数 | 直前の評価結果が_変数に格納される | MRB_NO_MIRB_UNDERSCORE未定義時 |
| BR-75-3 | マルチラインエディタ | tty接続時はマルチラインエディタを使用 | isatty(stdin)がtrue |
| BR-75-4 | フォールバック | エディタ未対応時は簡易行入力にフォールバック | エディタ初期化失敗時 |
| BR-75-5 | Ctrl+C | SIGINT受信時は入力をキャンセル | 簡易入力モード時 |

### 計算ロジック

特になし。

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 構文エラー | パースエラー発生時 | 行番号・列番号付きエラー表示、キャレット表示 |
| - | 実行時例外 | VM実行中に例外発生 | p_errorでバックトレース付きエラー表示 |
| EXIT_FAILURE | 初期化失敗 | mrb_openが失敗 | エラーメッセージ表示して終了 |

### リトライ仕様

REPLのため、エラー後も入力を続行可能。

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

該当なし。

## パフォーマンス要件

- 入力バッファ: ruby_code 4096バイト、last_code_line 1024バイト

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

- MRB_NO_STDIO定義時はコンパイルエラー
- capture_errors=TRUEにより、実行時例外がREPLをクラッシュさせない

## 備考

- is_code_block_openはパーサの状態（lstate、lex_strterm、heredoc等）から未完のコードブロックを検出
- エディタモジュール（mirb_editor.c/h）がマルチライン編集、mirb_completion.c/hがタブ補完、mirb_highlight.c/hが構文ハイライトを担当
- NO_COLOR環境変数でカラー出力を無効化可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | mirb.c | `mrbgems/mruby-bin-mirb/tools/mirb/mirb.c` | struct _args定義（204-212行目） |
| 1-2 | mirb.c | `mrbgems/mruby-bin-mirb/tools/mirb/mirb.c` | mirb_check_data構造体（399-402行目） |

#### Step 2: エントリーポイントを理解する

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

**主要処理フロー**:
1. **496-501行目**: mrb_open、初期化失敗チェック
2. **503-508行目**: parse_args
3. **528-551行目**: コンパイルコンテキスト設定、ライブラリ読み込み
4. **544-546行目**: _変数初期化
5. **554-569行目**: マルチラインエディタ初期化
6. **573-787行目**: メインREPLループ

#### Step 3: コード完成度判定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | mirb.c | `mrbgems/mruby-bin-mirb/tools/mirb/mirb.c` | is_code_block_open関数（109-202行目） |

**主要処理フロー**:
- **115-116行目**: heredoc/lex_strterm未完チェック
- **121-140行目**: パースエラー"unexpected end of file"で継続
- **142-199行目**: レキサ状態による判定（EXPR_DOT/CLASS/FNAME/VALUEで継続）

#### Step 4: エディタ・補完・ハイライトモジュールを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | mirb_editor.h | `mrbgems/mruby-bin-mirb/tools/mirb/mirb_editor.h` | エディタAPI |
| 4-2 | mirb_completion.h | `mrbgems/mruby-bin-mirb/tools/mirb/mirb_completion.h` | 補完API |
| 4-3 | mirb_highlight.h | `mrbgems/mruby-bin-mirb/tools/mirb/mirb_highlight.h` | ハイライトAPI |

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

```
main
    ├─ mrb_open
    ├─ parse_args
    ├─ mrb_ccontext_new
    ├─ decl_lv_underscore (_変数初期化)
    ├─ mirb_editor_init
    ├─ [REPLループ]
    │   ├─ mirb_editor_read / getchar
    │   ├─ mrb_parser_new → mrb_parser_parse
    │   ├─ is_code_block_open (完成度判定)
    │   ├─ mrb_generate_code
    │   ├─ mrb_vm_run
    │   ├─ p (結果表示)
    │   │   └─ mirb_highlight_print_result
    │   ├─ p_error (エラー表示)
    │   │   └─ mirb_highlight_print_error
    │   └─ mirb_editor_history_add
    ├─ mirb_cleanup_editor_completion
    ├─ mirb_editor_cleanup
    └─ mrb_close
```

### データフロー図

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

キーボード ────▶ mirb_editor_read ─────▶ コード文字列
                     │
                     ▼
              mrb_parser_parse ─────▶ AST
                     │
                     ▼
              is_code_block_open
              ├─ 未完 → 継続入力
              └─ 完成 ↓
                     │
              mrb_generate_code ────▶ RProc
                     │
              mrb_vm_run ──────────▶ mrb_value
                     │
              inspect + highlight ──▶ 結果表示(stdout)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| mirb.c | `mrbgems/mruby-bin-mirb/tools/mirb/mirb.c` | ソース | メインREPLロジック |
| mirb_editor.c/h | `mrbgems/mruby-bin-mirb/tools/mirb/mirb_editor.c` | ソース | マルチラインエディタ |
| mirb_completion.c/h | `mrbgems/mruby-bin-mirb/tools/mirb/mirb_completion.c` | ソース | タブ補完 |
| mirb_highlight.c/h | `mrbgems/mruby-bin-mirb/tools/mirb/mirb_highlight.c` | ソース | 構文ハイライト |
| mirb_buffer.c/h | `mrbgems/mruby-bin-mirb/tools/mirb/mirb_buffer.c` | ソース | バッファ管理 |
| mirb_term.c/h | `mrbgems/mruby-bin-mirb/tools/mirb/mirb_term.c` | ソース | 端末制御 |
| mirb_history.c/h | `mrbgems/mruby-bin-mirb/tools/mirb/mirb_history.c` | ソース | 履歴管理 |
| mrbgem.rake | `mrbgems/mruby-bin-mirb/mrbgem.rake` | 設定 | gem定義 |
| mirb.rb | `mrbgems/mruby-bin-mirb/bintest/mirb.rb` | テスト | 統合テスト |
