# 画面設計書 4-nim js（JavaScript生成）

## 概要

本ドキュメントは、NimソースコードをJavaScriptにコンパイルするサブコマンド`nim js`のCLIインターフェース設計書です。

### 本画面の処理概要

`nim js`コマンドは、Nim言語で書かれたソースコードをJavaScriptコードに変換するサブコマンドです。生成されたJavaScriptは、Webブラウザ上で直接実行したり、Node.js環境で実行したりすることができます。フロントエンド開発やクロスプラットフォームアプリケーションの構築に使用されます。

**業務上の目的・背景**：Nimの高水準な型システムとマクロ機能を活用しながら、Webブラウザで動作するクライアントサイドアプリケーションを開発できます。また、Node.js環境でのサーバーサイド開発や、Electronなどを用いたデスクトップアプリケーション開発にも利用可能です。

**画面へのアクセス方法**：ターミナルから`nim js <filename.nim>`または`nim compiletojs <filename.nim>`を実行します。

**主要な操作・処理内容**：
1. Nimソースファイルの字句解析・構文解析
2. 意味解析（型チェック、名前解決、マクロ展開）
3. 中間表現からJavaScriptコードへの変換（jsgen.nim）
4. 生成されたJavaScriptファイルを出力
5. ソースマップの生成（オプション）

**画面遷移**：
- 入力元：`nim`メインコマンドから`cmdCompileToJS`として呼び出し
- 遷移先：なし（コンパイル完了後終了）、`--run`オプション時はNode.jsで実行

**権限による表示制御**：OSのファイルシステム権限に依存。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 6 | JavaScriptコード生成 | 主機能 | NimコードからJavaScriptコードを生成するバックエンド処理 |

## 画面種別

CLIサブコマンド（コンパイラバックエンド）

## URL/ルーティング

```
nim js [options] <projectfile.nim>
nim compiletojs [options] <projectfile.nim>
```

オプション例：
- `nim js hello.nim` - デフォルト設定でJSコンパイル
- `nim js -d:release hello.nim` - リリースビルド（最適化）
- `nim js -r hello.nim` - コンパイル後にNode.jsで実行
- `nim js --sourceMap hello.nim` - ソースマップ生成
- `nim js -d:nodejs hello.nim` - Node.js向け最適化

## 入出力項目

| 項目名 | 型 | 入力/出力 | 必須 | 説明 |
|--------|-----|----------|------|------|
| projectfile | string | 入力 | はい | コンパイル対象のNimソースファイル |
| -d:nodejs | flag | 入力 | いいえ | Node.js向け最適化 |
| --sourceMap | flag | 入力 | いいえ | ソースマップ生成 |
| -d:release | flag | 入力 | いいえ | リリースビルド |
| -o:FILE | string | 入力 | いいえ | 出力ファイルパス |
| *.js | file | 出力 | - | 生成されたJavaScriptファイル |
| *.js.map | file | 出力 | - | ソースマップファイル（オプション） |

## 表示項目

| 項目 | 説明 | 表示条件 |
|------|------|----------|
| Hint: [Success] | コンパイル成功と出力パス | デフォルト |
| 進捗表示 | 処理中のモジュール名 | --verbosity:1以上 |
| Node.js出力 | 実行結果 | -r オプション使用時 |

## イベント仕様

### 1-コンパイル開始

`main.nim`の`commandCompileToJS`関数が呼び出されます：

1. `conf.exc = excCpp`（例外システム設定）
2. `setTarget(conf.target, osJS, cpuJS)`（ターゲット設定）
3. `defineSymbol(conf.symbols, "ecmascript")`（後方互換シンボル）
4. `setPipeLinePass(graph, JSgenPass)`（JS生成パス設定）
5. `compilePipelineProject(graph)`（コンパイル実行）

### 2-JavaScript型マッピング

jsgen.nimの`mapType`関数（行187-223）で型変換：
- `tyInt..tyInt64`, `tyUInt..tyUInt64`: etyInt
- `tyFloat..tyFloat128`: etyFloat
- `tyBool`: etyBool
- `tyString`, `tySequence`: etySeq
- `tyObject`, `tyArray`, `tyTuple`: etyObject
- `tyVar`, `tyRef`, `tyPtr`: etyBaseIndex（ファットポインタ）

### 3-コード生成

jsgen.nimの主要な生成関数：
- `gen`: 汎用ノード生成
- `genStmt`: 文の生成
- `genProc`: プロシージャの生成
- `genAnd/genOr`: 論理演算の最適化（短絡評価）

### 4-実行（-rオプション）

`--run`オプション指定時、Node.jsを使用して実行：
- `findNodeJs()`でNode.jsパスを検出
- `--unhandled-rejections=strict`オプションを追加

## データベース更新仕様

本CLIツールはデータベースを使用しません。

### ファイルシステム操作

| 操作 | 対象 | 種別 | 概要 |
|------|------|------|------|
| コンパイル | *.nim | READ | Nimソースファイル読み込み |
| コンパイル | *.js | WRITE | 生成JavaScriptファイル出力 |
| コンパイル | *.js.map | WRITE | ソースマップ出力（オプション） |

## メッセージ仕様

| メッセージ種別 | メッセージ | 発生条件 |
|---------------|----------|----------|
| ヒント | "Hint: [Success] ..." | コンパイル成功時 |
| エラー | "Error: ..." | コンパイルエラー時 |
| 警告 | JS非対応機能の警告 | 非サポート機能使用時 |

## 例外処理

| 状態 | エラーメッセージ | 処理 |
|------|-----------------|------|
| ソースファイル不在 | "cannot open file: $1" | エラー終了 |
| Node.js不在 | Node.js検出失敗 | 実行エラー（-rオプション時） |
| 非サポート機能 | 機能固有のエラーメッセージ | エラー終了 |

## 備考

- JSバックエンドではスレッドはサポートされない
- GCモードは自動的にJavaScript向けに調整される
- `{.importjs.}`プラグマでJavaScript関数を直接呼び出し可能
- `dom`モジュールでブラウザDOM操作が可能
- `jsffi`モジュールでJavaScriptオブジェクトとの相互運用
- `--jsBigInt64`オプションで64ビット整数にBigInt使用

---

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

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

### 推奨読解順序

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

JavaScript生成で使用される主要なデータ構造を把握します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | jsgen.nim | `compiler/jsgen.nim` | TJSTypeKind列挙型（行58-68）、TCompRes型（行74-85） |
| 1-2 | jsgen.nim | `compiler/jsgen.nim` | PProc型、TProc型（行100-116）、PGlobals型（行92-98） |

**読解のコツ**: TJSTypeKindはJavaScriptの型分類、TCompResは式のコンパイル結果を表す。etyBaseIndexは「ファットポインタ」で配列+インデックスのペア。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | main.nim | `compiler/main.nim` | commandCompileToJS関数（行180-191） |

**主要処理フロー**:
1. **main.nim 行185**: `conf.exc = excCpp` 例外システム設定
2. **main.nim 行186**: `setTarget(conf.target, osJS, cpuJS)` ターゲット設定
3. **main.nim 行187**: `defineSymbol("ecmascript")` 後方互換シンボル
4. **main.nim 行188**: `setPipeLinePass(graph, JSgenPass)` JS生成パス
5. **main.nim 行189**: `compilePipelineProject(graph)` コンパイル実行

#### Step 3: 型マッピングを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | jsgen.nim | `compiler/jsgen.nim` | mapType関数（行187-223） |

**主要処理フロー**:
- **行201**: 整数型 → etyInt
- **行202**: ブール型 → etyBool
- **行203**: 浮動小数点型 → etyFloat
- **行205**: 文字列・シーケンス → etySeq
- **行206-207**: オブジェクト・配列・タプル → etyObject

#### Step 4: コード生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | jsgen.nim | `compiler/jsgen.nim` | gen関数、genStmt関数（行323-324） |
| 4-2 | jsgen.nim | `compiler/jsgen.nim` | genAnd/genOr関数（行365-408） |

**主要処理フロー**:
- `gen`: 任意のノードをJavaScriptに変換
- `genStmt`: 文をJavaScriptステートメントに変換
- `genAnd/genOr`: 短絡評価の最適化実装

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

```
main.nim::mainCommand()
    │
    └─ case cmdCompileToJS
           │
           └─ commandCompileToJS()
                  │
                  ├─ conf.exc = excCpp
                  │
                  ├─ setTarget(osJS, cpuJS)
                  │
                  ├─ defineSymbol("ecmascript")
                  │
                  ├─ setPipeLinePass(JSgenPass)
                  │
                  └─ compilePipelineProject()
                         │
                         └─ jsgen.myProcess()
                                │
                                ├─ gen()
                                │     ├─ genStmt()
                                │     ├─ genExpr()
                                │     └─ genProc()
                                │
                                └─ JavaScript出力
```

### データフロー図

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

*.nim ───▶ セマンティック解析 ───▶ 型付きAST
                 │
                 ▼
型付きAST ───▶ jsgen.nim ───▶ Rope (JavaScript文字列)
                 │
                 ├─ mapType() でJS型決定
                 │
                 ├─ gen() でコード生成
                 │
                 └─ mangleName() で名前変換
                 │
                 ▼
Rope ───▶ ファイル出力 ───▶ *.js
                 │
                 ▼ (オプション)
         ソースマップ生成 ───▶ *.js.map
                 │
                 ▼ (-r オプション)
Node.js ───▶ 実行 ───▶ 標準出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| jsgen.nim | `compiler/jsgen.nim` | ソース | JavaScriptコード生成メインロジック |
| jstypes.nim | `compiler/jstypes.nim` | ソース | JS型関連処理（includeされる） |
| main.nim | `compiler/main.nim` | ソース | commandCompileToJS関数 |
| sourcemap.nim | `compiler/sourcemap.nim` | ソース | ソースマップ生成 |
| nodejs.nim | `compiler/nodejs.nim` | ソース | Node.js検出・実行 |
| dom.nim | `lib/js/dom.nim` | ライブラリ | ブラウザDOM操作 |
| jsffi.nim | `lib/js/jsffi.nim` | ライブラリ | JavaScript相互運用 |
| asyncjs.nim | `lib/js/asyncjs.nim` | ライブラリ | JavaScript async/await対応 |
