# 機能設計書 1-Nimコンパイラ本体

## 概要

本ドキュメントは、Nimコンパイラ本体の機能設計について記載する。Nimコンパイラは、Nimプログラミング言語のソースコードを解析し、C/C++/JavaScript/Objective-Cコードへ変換するコンパイラである。

### 本機能の処理概要

Nimコンパイラ本体は、Nimソースコードを受け取り、複数のバックエンド（C、C++、JavaScript、Objective-C、NIF）向けのコードを生成する統合コンパイラシステムである。

**業務上の目的・背景**：Nimは効率的でエレガントなシステムプログラミング言語であり、高性能なネイティブコードを生成するためのコンパイラが必要である。Nimコンパイラ本体は、ソースコードから各種ターゲット言語へのトランスパイルを行い、既存のCコンパイラやJavaScriptランタイムと連携することで、クロスプラットフォーム開発を実現する。これにより、開発者は単一のNimソースコードから複数のプラットフォーム向けの実行ファイルを生成できる。

**機能の利用シーン**：
- 開発者がNimソースコードをコンパイルして実行ファイルを生成する場面
- Nimスクリプトを実行する場面（NimScript）
- ドキュメントを生成する場面（nimDoc）
- 依存関係を解析する場面
- IDEとの連携でコード補完や定義ジャンプを行う場面

**主要な処理内容**：
1. コマンドライン引数の解析と設定の初期化
2. 設定ファイル（nim.cfg、config.nims）の読み込み
3. プロジェクトファイルの特定とモジュールグラフの構築
4. レキシカル解析（トークン化）
5. 構文解析（AST生成）
6. セマンティック解析（型チェック、名前解決、マクロ展開）
7. 選択されたバックエンドへのコード生成
8. 外部コンパイラの呼び出し（Cバックエンドの場合）
9. 生成されたプログラムの実行（--runオプション指定時）

**関連システム・外部連携**：
- GCC、Clang、MSVC等の外部Cコンパイラとの連携
- Node.jsとの連携（JavaScriptバックエンド）
- Nimbleパッケージマネージャとの連携（nimble.lock検出）
- IDEツール（nimsuggest）との連携

**権限による制御**：コンパイラ自体にはユーザー認証機構はないが、ファイルシステムのアクセス権限に従って動作する。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| N/A | コマンドラインインターフェース | 主画面 | コンパイラの全操作はCLIから実行される |

## 機能種別

コンパイル処理 / コード変換 / コード生成

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| command | string | Yes | 実行コマンド（c, cpp, js, check, doc等） | 有効なコマンド名であること |
| projectFile | string | Yes | コンパイル対象のNimソースファイル | .nim拡張子、ファイル存在確認 |
| --backend | TBackend | No | バックエンド指定（c/cpp/js/objc/nif） | 有効なバックエンド名 |
| --out | string | No | 出力ファイル名 | 有効なパス |
| --outdir | string | No | 出力ディレクトリ | 有効なディレクトリパス |
| --nimcache | string | No | キャッシュディレクトリ | 有効なディレクトリパス |
| --run | bool | No | コンパイル後に実行 | true/false |
| --gc | TGCMode | No | GCモード指定 | arc/orc/refc/none等 |
| --opt | string | No | 最適化レベル | speed/size/none |

### 入力データソース

- コマンドライン引数
- 設定ファイル（nim.cfg、config.nims、プロジェクト固有設定）
- 環境変数
- Nimソースファイル群

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 生成コード | File | C/C++/JavaScript/Objective-Cソースファイル |
| 実行ファイル | File | リンク済み実行可能バイナリ（Cバックエンド） |
| キャッシュファイル | File | nimcacheディレクトリ内の中間ファイル |
| ドキュメント | File | HTML/JSON/LaTeX形式のドキュメント |
| ビルド情報 | File | JSON形式のビルド指示ファイル |

### 出力先

- 標準出力（コンパイラメッセージ、警告、エラー）
- 出力ディレクトリ（--outdirで指定、デフォルトはプロジェクトディレクトリ）
- nimcacheディレクトリ（中間ファイル）

## 処理フロー

### 処理シーケンス

```
1. エントリーポイント（nim.nim）
   └─ コマンドライン引数がない場合はヘルプ表示
2. コマンドライン解析（processCmdLine）
   └─ passCmd1: 初回解析、プロジェクトファイル特定
3. 設定ファイルロード（loadConfigsAndProcessCmdLine）
   └─ nim.cfg、config.nims、プロジェクト固有設定を読み込み
4. コマンドライン再解析
   └─ passCmd2: 設定ファイル後のオプション上書き
5. モジュールグラフ構築（newModuleGraph）
   └─ 依存関係の初期化
6. メインコマンド実行（mainCommand）
   └─ コマンドに応じた処理分岐
7. バックエンド処理（compileToBackend）
   └─ C/C++/JS/ObjC/NIFコード生成
8. 外部コンパイラ呼び出し（Cバックエンド時）
   └─ gcc/clang/msvc等でコンパイル・リンク
9. プログラム実行（--run指定時）
   └─ 生成された実行ファイルを起動
```

### フローチャート

```mermaid
flowchart TD
    A[開始: nim.nim] --> B{引数あり?}
    B -->|No| C[ヘルプ表示]
    C --> Z[終了]
    B -->|Yes| D[processCmdLineAndProjectPath]
    D --> E[loadConfigsAndProcessCmdLine]
    E --> F[newModuleGraph]
    F --> G[mainCommand]
    G --> H{コマンド種別}
    H -->|compile| I[compileToBackend]
    H -->|check| J[commandCheck]
    H -->|doc| K[commandDoc]
    H -->|interactive| L[commandInteractive]
    I --> M{バックエンド}
    M -->|C/C++/ObjC| N[commandCompileToC]
    M -->|JS| O[commandCompileToJS]
    M -->|NIF| P[commandCompileToNif]
    N --> Q[cgenWriteModules]
    Q --> R[callCCompiler]
    R --> S{--run?}
    S -->|Yes| T[execExternalProgram]
    S -->|No| Z
    T --> Z
    O --> Z
    P --> Z
    J --> Z
    K --> Z
    L --> Z
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | nimble.lock優先 | nimble.lockが存在する場合、nimblepath無効化 | nimble.lockファイルが存在 |
| BR-02 | デフォルトGC | バックエンドがC/C++/ObjCの場合、ORCがデフォルト | GC未選択時 |
| BR-03 | バックエンド自動選択 | コマンドがcheckでbackend未指定の場合、Cを使用 | cmdCheck時 |
| BR-04 | 出力ディレクトリ | doc系コマンドはhtmldocsサブディレクトリに出力 | cmdDocLike時 |

### 計算ロジック

- ハッシュ計算：`hashMainCompilationParams`でSHA1ハッシュを計算し、nimcacheのサブディレクトリ名に使用
- 出力ファイル名：プロジェクト名 + プラットフォーム固有の拡張子

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

該当なし（コンパイラはデータベースを使用しない）

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| N/A | N/A | N/A | データベース操作なし |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| errGenerated | コマンドエラー | 無効なコマンドが指定された | 有効なコマンドを指定 |
| errGenerated | 引数エラー | --runなしで引数が渡された | --runオプションを追加 |
| errCannotOpenFile | ファイルエラー | 出力ディレクトリが無効 | 有効なパスを指定 |
| errGenerated | バックエンドエラー | --runが非対応のバックエンド | 対応するバックエンドを使用 |

### リトライ仕様

コンパイラは基本的にリトライを行わない。エラー発生時は即座にエラーメッセージを出力し、適切な終了コードで終了する。

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

該当なし（コンパイラはファイルベースの処理のみ）

## パフォーマンス要件

- インクリメンタルコンパイル対応（シンボルファイル使用時）
- 並列コンパイル対応（外部Cコンパイラ呼び出し時）
- nimcacheによるキャッシュ機構

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

- コンパイル時FFI（`compiletimeFFI`）は明示的に有効化が必要
- VMの実行には反復回数制限（`maxLoopIterationsVM`）と呼び出し深度制限（`maxCallDepthVM`）が設定されている
- nimble.lock存在時のnimblepath無効化によるサプライチェーン攻撃対策

## 備考

- Nimコンパイラ自体もNimで書かれている（セルフホスティング）
- ブートストラップビルドではCソースからコンパイラをビルド
- 定義済みシンボル（`nimPreviewSlimSystem`等）による条件付きコンパイル対応

---

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

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

### 推奨読解順序

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

まず、コンパイラ全体で使用される設定とオプションのデータ構造を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | options.nim | `compiler/options.nim` | ConfigRef型、TOption、TGlobalOption、Command列挙型の定義を理解する |
| 1-2 | lineinfos.nim | `compiler/lineinfos.nim` | TLineInfo、FileIndex等のソース位置情報の定義を理解する |

**読解のコツ**:
- `ConfigRef`（346行目〜）がコンパイラの全設定を保持する中心的なデータ構造
- `Command`列挙型（151行目〜）で利用可能な全コマンドが定義されている
- `TBackend`列挙型（141行目〜）でサポートされるバックエンドが定義されている

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | nim.nim | `compiler/nim.nim` | メインエントリーポイント、コマンドライン処理の流れを理解する |

**主要処理フロー**:
1. **167-172行目**: `when not defined(selftest)`ブロックでメイン処理開始
2. **168行目**: `newConfigRef()`で設定オブジェクト生成
3. **169行目**: `handleCmdLine(newIdentCache(), conf)`でコマンドライン処理開始
4. **98-127行目**: `handleCmdLine`プロシージャでコンパイル全体を制御

#### Step 3: コマンドライン処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | cmdlinehelper.nim | `compiler/cmdlinehelper.nim` | NimProg型とコマンドライン処理補助機能を理解する |

**主要処理フロー**:
- **32-36行目**: `NimProg`型定義（コマンドライン処理のコールバックを保持）
- **42-51行目**: `processCmdLineAndProjectPath`でプロジェクトファイルを特定
- **53-81行目**: `loadConfigsAndProcessCmdLine`で設定ファイルをロードし再度コマンドライン処理

#### Step 4: メインコマンド実行を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | main.nim | `compiler/main.nim` | 各コマンドの実装とコード生成へのディスパッチを理解する |

**主要処理フロー**:
- **254-294行目**: `mainCommand`プロシージャでコマンドに応じた処理を分岐
- **284-293行目**: `compileToBackend`でバックエンドに応じたコード生成を呼び出し
- **146-176行目**: `commandCompileToC`でCコード生成と外部コンパイラ呼び出し
- **180-191行目**: `commandCompileToJS`でJavaScriptコード生成

#### Step 5: パイプライン処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | pipelines.nim | `compiler/pipelines.nim` | コンパイルパイプラインの各パス定義を理解する |

**主要処理フロー**:
- パイプラインパス（SemPass、CgenPass、JSgenPass等）の切り替え
- `compilePipelineProject`でプロジェクト全体のコンパイル実行

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

```
nim.nim (エントリーポイント)
    │
    ├─ handleCmdLine
    │      ├─ processCmdLineAndProjectPath (cmdlinehelper.nim)
    │      │      └─ processCmdLine (nim.nim)
    │      │
    │      ├─ loadConfigsAndProcessCmdLine (cmdlinehelper.nim)
    │      │      ├─ loadConfigs (nimconf.nim)
    │      │      └─ processCmdLine (passCmd2)
    │      │
    │      └─ mainCommand (main.nim)
    │             ├─ compileToBackend
    │             │      ├─ commandCompileToC
    │             │      │      ├─ compilePipelineProject (pipelines.nim)
    │             │      │      ├─ cgenWriteModules (cgen.nim)
    │             │      │      └─ callCCompiler (extccomp.nim)
    │             │      │
    │             │      ├─ commandCompileToJS
    │             │      │      └─ compilePipelineProject (pipelines.nim)
    │             │      │
    │             │      └─ commandCompileToNif
    │             │             └─ compilePipelineProject (pipelines.nim)
    │             │
    │             ├─ commandCheck
    │             │      └─ compilePipelineProject (SemPass)
    │             │
    │             ├─ commandDoc / commandDoc2
    │             │      └─ compilePipelineProject (Docgen2Pass)
    │             │
    │             └─ commandInteractive
    │                    └─ compilePipelineModule
    │
    └─ execExternalProgram (--run時)
```

### データフロー図

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

Nimソースファイル ───────────▶ lexer.nim ────────────────────────▶ トークン列
       │                        (字句解析)
       │
       ▼
設定ファイル ─────────────────▶ nimconf.nim ─────────────────────▶ ConfigRef
(nim.cfg, config.nims)          (設定読み込み)
       │
       ▼
コマンドライン引数 ───────────▶ commands.nim ────────────────────▶ Command/オプション
                                (引数解析)
       │
       ▼
トークン列 ───────────────────▶ parser.nim ──────────────────────▶ AST (PNode)
                                (構文解析)
       │
       ▼
AST ──────────────────────────▶ sem.nim ─────────────────────────▶ 意味解析済みAST
                                (セマンティック解析)
       │
       ▼
意味解析済みAST ──────────────▶ cgen.nim / jsgen.nim ────────────▶ C/JSソースコード
                                (コード生成)
       │
       ▼
Cソースコード ────────────────▶ extccomp.nim ────────────────────▶ 実行ファイル
                                (外部コンパイラ呼び出し)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| nim.nim | `compiler/nim.nim` | ソース | コンパイラのメインエントリーポイント |
| main.nim | `compiler/main.nim` | ソース | コマンドディスパッチャーと各コマンドの実装 |
| cmdlinehelper.nim | `compiler/cmdlinehelper.nim` | ソース | コマンドライン処理の補助機能 |
| options.nim | `compiler/options.nim` | ソース | コンパイラ設定とオプションの定義 |
| commands.nim | `compiler/commands.nim` | ソース | コマンドライン引数の処理 |
| nimconf.nim | `compiler/nimconf.nim` | ソース | 設定ファイルの読み込み |
| modulegraphs.nim | `compiler/modulegraphs.nim` | ソース | モジュール依存関係グラフの管理 |
| pipelines.nim | `compiler/pipelines.nim` | ソース | コンパイルパイプラインの制御 |
| lexer.nim | `compiler/lexer.nim` | ソース | 字句解析器 |
| parser.nim | `compiler/parser.nim` | ソース | 構文解析器 |
| sem.nim | `compiler/sem.nim` | ソース | セマンティック解析 |
| cgen.nim | `compiler/cgen.nim` | ソース | Cコード生成バックエンド |
| jsgen.nim | `compiler/jsgen.nim` | ソース | JavaScriptコード生成バックエンド |
| extccomp.nim | `compiler/extccomp.nim` | ソース | 外部Cコンパイラ連携 |
| nim.cfg | ルートディレクトリ | 設定 | グローバル設定ファイル |
| config.nims | プロジェクトディレクトリ | 設定 | プロジェクト固有設定ファイル |
