# 機能設計書 1-シェル実行環境

## 概要

本ドキュメントは、Nushellのコア実行環境機能について定義する。Nushellは従来のシェルとは異なり、パイプライン処理において構造化データ（テーブル、レコード、リスト等）をネイティブに取り扱う新世代シェルである。本機能はその中核となる実行エンジンを提供する。

### 本機能の処理概要

**業務上の目的・背景**：従来のUnixシェル（bash、zsh等）では、コマンド間のデータ受け渡しがテキストベースであり、データのパース・整形に多くの労力を要していた。Nushellは構造化データをパイプライン間でネイティブに受け渡すことで、データ処理の効率化とエラーの削減を実現する。システム管理、データ分析、スクリプト自動化など幅広い用途でユーザーの生産性を向上させる。

**機能の利用シーン**：ユーザーがコマンドラインでコマンドを入力し、実行結果を取得するすべての場面で使用される。対話的なREPL環境での即時実行、スクリプトファイルのバッチ実行、パイプラインによる複数コマンドの連携処理など、シェル操作のあらゆる基盤となる。

**主要な処理内容**：
1. EngineState の管理 - グローバルな状態（宣言、変数、ブロック、モジュール）をIDベースで管理
2. Stack によるランタイム状態管理 - 変数の値、環境変数、オーバーレイの実行時状態を管理
3. パイプライン実行 - PipelineData を通じた構造化データの受け渡しと処理
4. ブロック評価 - eval_block によるコードブロックの逐次実行
5. 関数呼び出し - eval_call による宣言されたコマンドの実行と引数処理
6. 外部コマンド実行 - run-external を通じた外部プロセスとの連携

**関連システム・外部連携**：nu-parser（構文解析）、nu-cli（REPL環境）、nu-command（組み込みコマンド群）と密接に連携する。外部コマンドはOSのプロセス実行機能を通じて呼び出される。

**権限による制御**：シェル実行環境自体には権限制御はないが、実行される個々のコマンドがファイルシステムアクセスやネットワーク通信等の権限を必要とする場合がある。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | メインREPL | 主画面 | コマンド入力・パイプライン実行・構造化データ処理の主処理を担当 |
| 7 | Tryビュー | 参照画面 | インタラクティブなコマンド入力・実行環境 |
| 8 | Nuコマンドビュー | 結果表示画面 | Nuコマンドのバックグラウンド実行 |

## 機能種別

計算処理 / パイプライン実行 / データ変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| block | Block | Yes | 実行するコードブロック（パース済みAST） | 有効なBlockIdであること |
| input | PipelineData | No | パイプライン入力データ | 構造化データまたはEmpty |
| engine_state | EngineState | Yes | エンジン状態への参照 | 有効な状態オブジェクト |
| stack | Stack | Yes | ランタイムスタック | 有効なスタックオブジェクト |

### 入力データソース

- ユーザーからのコマンドライン入力（REPL）
- スクリプトファイル（.nuファイル）
- パイプラインからの入力データ（前段コマンドの出力）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| PipelineData | PipelineData | 実行結果（Value、ListStream、ByteStream、Empty） |
| body | PipelineData | パイプライン本体のデータ |
| metadata | Option<PipelineMetadata> | データに付随するメタデータ |

### 出力先

- 画面表示（REPL）
- パイプライン後段のコマンド
- ファイル（リダイレクト時）
- 外部プロセス（パイプ接続時）

## 処理フロー

### 処理シーケンス

```
1. ブロック評価開始 (eval_block)
   └─ シグナルチェック（Ctrl+C等の割り込み確認）
2. IRブロック評価 (eval_ir_block)
   └─ 中間表現（IR）にコンパイルされたブロックを実行
3. パイプライン要素の逐次処理
   └─ 各式（Expression）を順番に評価
4. 式の評価 (eval_expression_with_input)
   └─ 式の種類に応じた評価処理
      ├─ Call: eval_call で関数呼び出し
      ├─ ExternalCall: eval_external で外部コマンド実行
      ├─ Subexpression: eval_subexpression でサブ式評価
      └─ その他: 直接評価
5. 関数呼び出し (eval_call)
   └─ 宣言の取得とパラメータバインディング
6. 結果の返却
   └─ PipelineDataとして結果を返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始: eval_block] --> B{シグナルチェック}
    B -->|割り込みあり| C[エラー返却]
    B -->|OK| D[eval_ir_block]
    D --> E{パイプライン要素}
    E -->|Call| F[eval_call]
    E -->|ExternalCall| G[eval_external]
    E -->|Subexpression| H[eval_subexpression]
    E -->|その他| I[eval_expression]
    F --> J{ブロックID あり?}
    J -->|Yes| K[ユーザー定義関数実行]
    J -->|No| L[組み込みコマンド実行]
    G --> M[run-external 呼び出し]
    H --> N[サブブロック評価]
    K --> O[スタックにキャプチャ変数設定]
    O --> P[再帰制限チェック]
    P --> Q[ブロック評価]
    L --> R[decl.run 実行]
    I --> S[結果をPipelineDataに変換]
    Q --> S
    R --> S
    M --> S
    N --> S
    S --> T[次の要素へ]
    T --> E
    E -->|完了| U[PipelineData返却]
    U --> V[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 再帰制限 | 関数呼び出しの再帰深度は50を上限とする | ユーザー定義関数の呼び出し時 |
| BR-002 | シグナル処理 | Ctrl+C等のシグナル受信時は処理を中断する | すべての評価処理 |
| BR-003 | 環境変数リダイレクト | --env フラグ付き関数は環境変数変更を呼び出し元に反映 | def --env で定義された関数 |
| BR-004 | 自動環境変数保護 | PWD, FILE_PWD, CURRENT_FILE は直接代入不可 | 環境変数への代入時 |

### 計算ロジック

再帰制限のチェック:
```
if callee_stack.recursion_count > engine_state.config.recursion_limit {
    return Err(ShellError::RecursionLimitReached)
}
```

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

本機能はデータベース操作を直接行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| RecursionLimitReached | 実行エラー | 再帰呼び出しが制限を超過 | 再帰ロジックの見直し |
| ExternalNotSupported | 実行エラー | run-externalが未登録 | 環境構成の確認 |
| VariableNotFoundAtRuntime | 実行エラー | 変数がスタックに存在しない | 変数定義の確認 |
| CantConvert | 型エラー | 引数の型が期待と不一致 | 引数の型を確認 |
| AssignmentRequiresMutableVar | 代入エラー | 不変変数への代入試行 | mut で宣言するか確認 |
| CannotReplaceEnv | 代入エラー | $env 全体の置換試行 | 個別のキーに代入 |
| AutomaticEnvVarSetManually | 代入エラー | 自動環境変数への手動設定 | 該当変数への代入を避ける |

### リトライ仕様

実行時エラーに対するリトライは行わない。try-catch によるエラーハンドリングはユーザースクリプトレベルで実装可能。

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

シェル実行環境はトランザクション管理を行わない。ただし、環境変数の変更は関数スコープ単位で管理され、--env フラグがない場合は呼び出し元に伝播しない。

## パフォーマンス要件

- 単純なコマンド実行: 1ms以下
- パイプライン処理: ストリーミング対応により大量データも逐次処理可能
- IRコンパイル: 初回実行時のみ発生、以降はキャッシュ

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

- 外部コマンド実行はOSの権限モデルに従う
- 環境変数の変更は意図的な--envフラグを必要とする
- 自動環境変数（PWD等）は保護されている

## 備考

- EngineState は Arc でラップされ、マルチスレッド環境で共有可能
- Stack はスレッドローカルな状態を管理
- PipelineData は lazy evaluation をサポートし、大量データの効率的な処理を実現

---

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

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

### 推奨読解順序

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

まず、プログラム間で受け渡されるデータ構造を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | engine_state.rs | `crates/nu-protocol/src/engine/engine_state.rs` | EngineState構造体の定義。グローバル状態の管理方法を理解する |
| 1-2 | stack.rs | `crates/nu-protocol/src/engine/stack.rs` | Stack構造体の定義。ランタイム状態の管理方法を理解する |
| 1-3 | pipeline.rs | `crates/nu-protocol/src/pipeline/` | PipelineData の定義。データの受け渡し形式を理解する |

**読解のコツ**: EngineState は `Arc` でラップされており、`Arc::make_mut` で変更時のみクローンされる。IDベースの参照（DeclId, VarId, BlockId等）がコア概念である。

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

処理の起点となるファイル・関数を特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | lib.rs | `crates/nu-engine/src/lib.rs` | モジュールのエクスポート一覧。eval_block, eval_call等の公開APIを確認 |
| 2-2 | eval.rs | `crates/nu-engine/src/eval.rs` | 評価処理のメインロジック。各関数の役割を把握 |

**主要処理フロー**:
1. **15-166行目**: `eval_call` - コマンド呼び出しの評価。引数のバインディングとブロック実行
2. **219-226行目**: `eval_expression` - 式の評価。EvalRuntime トレイトを通じて評価
3. **303-317行目**: `eval_block` - ブロック評価のエントリーポイント。IRブロック評価を呼び出す
4. **372-404行目**: `eval_variable` - 変数の評価。$nu, $env, 通常変数の処理を分岐

#### Step 3: IR評価を理解する

中間表現（IR）による評価処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | eval_ir.rs | `crates/nu-engine/src/eval_ir.rs` | IRブロックの評価ロジック。命令セットの実行方法を理解 |
| 3-2 | compile/ | `crates/nu-engine/src/compile/` | ASTからIRへのコンパイル処理 |

**主要処理フロー**:
- **eval_ir_block**: IR命令を順次実行し、結果をPipelineDataとして返却

#### Step 4: 環境・スコープ管理を理解する

環境変数とスコープの管理方法を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | env.rs | `crates/nu-engine/src/env.rs` | 環境変数の取得・設定ロジック |
| 4-2 | scope.rs | `crates/nu-engine/src/scope.rs` | スコープ情報の収集・表示 |

**主要処理フロー**:
- **168-188行目**: `redirect_env` - 環境変数のリダイレクト処理。calleeからcallerへの環境反映

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

```
eval_block (eval.rs:303)
    │
    ├─ eval_ir_block (eval_ir.rs)
    │      │
    │      ├─ (IR命令を順次実行)
    │      └─ eval_call / eval_expression_with_input
    │
    ├─ eval_call (eval.rs:15)
    │      │
    │      ├─ decl.run (組み込みコマンド)
    │      └─ eval_block_with_early_return (ユーザー定義関数)
    │             └─ eval_block (再帰)
    │
    ├─ eval_external (eval.rs:190)
    │      └─ run-external コマンド実行
    │
    └─ eval_expression (eval.rs:219)
           └─ EvalRuntime::eval (eval_base.rs)
```

### データフロー図

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

ユーザー入力 ───▶ Parser (nu-parser) ───▶ AST (Block)
                                              │
                                              ▼
                                        compile (IR生成)
                                              │
                                              ▼
PipelineData ────▶ eval_ir_block ────────▶ PipelineData
  (入力)           (命令実行)               (結果)
                       │
                       ├─ eval_call ─────▶ Command.run
                       │
                       ├─ eval_external ──▶ 外部プロセス
                       │
                       └─ eval_expression ▶ Value評価
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| lib.rs | `crates/nu-engine/src/lib.rs` | ソース | エンジンモジュールの公開API定義 |
| eval.rs | `crates/nu-engine/src/eval.rs` | ソース | 評価処理のメインロジック |
| eval_ir.rs | `crates/nu-engine/src/eval_ir.rs` | ソース | IR（中間表現）の評価処理 |
| env.rs | `crates/nu-engine/src/env.rs` | ソース | 環境変数管理 |
| scope.rs | `crates/nu-engine/src/scope.rs` | ソース | スコープ情報の収集 |
| engine_state.rs | `crates/nu-protocol/src/engine/engine_state.rs` | ソース | グローバル状態管理 |
| stack.rs | `crates/nu-protocol/src/engine/stack.rs` | ソース | ランタイムスタック管理 |
| pipeline/ | `crates/nu-protocol/src/pipeline/` | ソース | パイプラインデータ型定義 |
| compile/ | `crates/nu-engine/src/compile/` | ソース | ASTからIRへのコンパイル |
| closure_eval.rs | `crates/nu-engine/src/closure_eval.rs` | ソース | クロージャ評価処理 |
