# 機能設計書 33-文字（Char）操作

## 概要

本ドキュメントは、Julia Base ライブラリにおける文字（Char）操作機能の設計を記述する。`Char` 型の Unicode 文字処理（`isletter` / `isdigit` / `uppercase` / `lowercase` 等）を提供する。

### 本機能の処理概要

本機能は、Julia の基本文字型である `Char`（32ビット Unicode 文字）および抽象型 `AbstractChar` に対する生成・変換・分類・比較操作を提供する。

**業務上の目的・背景**：文字単位の操作は文字列処理の最も基本的な構成要素であり、文字分類（英字判定、数字判定、空白判定等）、大文字小文字変換、文字コードポイントの取得・変換など、あらゆるテキスト処理の基盤となる。Julia は Unicode を第一級サポートしており、多言語テキスト処理に不可欠な機能である。

**機能の利用シーン**：パーサーにおける文字種判定、入力バリデーション、文字列のケース変換、文字コードの変換・検査、文字の算術演算（次の文字の取得等）。

**主要な処理内容**：
1. `Char` 型と `AbstractChar` 抽象型の定義とコンストラクタ
2. `codepoint` による Unicode コードポイントの取得
3. `ncodeunits` による UTF-8 エンコード時のバイト数算出
4. 文字の比較（`==`, `isless`）とハッシュ計算
5. 文字の算術演算（`+`, `-`）
6. `ismalformed` / `isoverlong` による不正エンコーディング検出
7. `show` による文字のテキスト表現出力
8. `print` による UTF-8 出力

**関連システム・外部連携**：Unicode ライブラリ（`stdlib/Unicode/`）と連携し、文字カテゴリ情報を取得する。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | REPL | 主画面 | 文字リテラルの表示・操作 |

## 機能種別

基本データ型操作 / 文字処理ユーティリティ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| c | AbstractChar / Char | Yes | 操作対象の文字 | - |
| x | Number / UInt32 | Yes(コンストラクタ) | コードポイント値 | 0x00200000 未満 |
| y | Integer | Yes(算術) | 加減算の整数値 | 結果が有効なコードポイントであること |

### 入力データソース

関数の引数として直接受け取る。文字リテラル（`'a'`）や文字列のイテレーションから取得される。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| codepoint | UInt32 | Unicode コードポイント値 |
| ncodeunits | Int | UTF-8 エンコード時のバイト数（1-4） |
| 比較結果 | Bool | 文字の等値・順序比較結果 |
| 算術結果 | AbstractChar / Int | 文字の加減算結果 |
| 分類結果 | Bool | isletter, isdigit 等の判定結果 |

### 出力先

関数の戻り値として呼び出し元に返却する。`print` は指定された IO ストリームに UTF-8 バイト列を出力する。

## 処理フロー

### 処理シーケンス

```
1. Char(u::UInt32) コンストラクタ
   └─ u < 0x80: 上位バイトにシフトして bitcast
   └─ u < 0x00200000: UTF-8 マルチバイトエンコーディング
   └─ それ以上: CodePointError をスロー
2. UInt32(c::Char) - コードポイント取得
   └─ u < 0x80000000: 上位8ビットを返却（ASCII高速パス）
   └─ leading_ones でバイト数判定
   └─ マスク演算でコードポイントを復元
   └─ 不正エンコーディングの場合 InvalidCharError
3. codepoint(c::Char) = UInt32(c)
4. ncodeunits(c::Char)
   └─ reinterpret(UInt32, c) で生のビットパターン取得
   └─ trailing_zeros でゼロバイト数を算出し sizeof(UInt32) から減算
5. show(io, c::AbstractChar)
   └─ エスケープシーケンス文字（\0,\a,\b,\t,\n 等）の特別処理
   └─ isoverlong/ismalformed の場合 show_invalid で16進表示
   └─ isprint の場合そのまま表示
   └─ 非表示文字は \x, \u, \U 形式で表示
```

### フローチャート

```mermaid
flowchart TD
    A[開始: Char(u::UInt32)] --> B{u < 0x80?}
    B -->|Yes| C[bitcast Char, u << 24]
    B -->|No| D{u < 0x00200000?}
    D -->|Yes| E[UTF-8 マルチバイトエンコード]
    D -->|No| F[throw CodePointError]
    E --> G[bitcast Char, encoded]
    C --> H[終了: Char 値返却]
    G --> H
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-33-01 | Unicode 超集合 | Char は Unicode の超集合を表現可能（不正バイト列も格納） | Char 型全般 |
| BR-33-02 | ASCII 高速パス | u < 0x80 の場合は単純シフトで高速変換 | Char(u), UInt32(c) |
| BR-33-03 | 比較はビットパターン | Char の == と isless は bitcast(UInt32, c) で比較 | ==, isless |
| BR-33-04 | print は UTF-8 | print(io, c) は常に UTF-8 エンコーディングで出力 | print |
| BR-33-05 | write はエンコーディング依存 | write(io, c) は typeof(c) に依存したエンコーディング | write |
| BR-33-06 | AbstractChar フォールバック | AbstractChar の比較は Char への変換を経由 | AbstractChar 同士の比較 |

### 計算ロジック

- UTF-8 エンコード: `((u << 0) & 0x3f) | ((u << 2) & 0x3f00) | ((u << 4) & 0x3f0000) | ((u << 6) & 0x3f000000)` にヘッダバイトを付加
- UTF-8 デコード: `((u & 0x7f) >> 0) | ((u & 0x7f00) >> 2) | ((u & 0x7f0000) >> 4) | ((u & 0x7f000000) >> 6)`
- ncodeunits: `sizeof(UInt32) - div(trailing_zeros(u), 8)` + ゼロ文字補正

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

該当なし。

### テーブル別操作詳細

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | CodePointError | UInt32 -> Char で u >= 0x00200000 | 有効な Unicode コードポイントを使用 |
| - | InvalidCharError | Char -> UInt32 で不正エンコーディング | ismalformed で事前チェック |
| - | BoundsError | getindex で i != 1 | インデックスは 1 のみ有効 |

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

- `@constprop :aggressive` アノテーションにより、コンパイル時の定数畳み込みを積極的に実施
- ASCII 文字（u < 0x80）に対する高速パスを全ての変換関数で提供
- `bitcast` を使用して型変換のオーバーヘッドを排除
- Int8/UInt8 からの変換では、ASCII範囲の場合にインライン高速パスを使用

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

- `ismalformed` / `isoverlong` により不正な UTF-8 シーケンスを検出可能
- 不正バイト列を Char として格納可能な設計（ロスレスな往復変換のため）だが、コードポイント取得時にエラーとなる

## 備考

- `Char` は Unicode の超集合を表現するため、不正なバイトストリームも格納可能
- `AbstractChar` のサブタイプは最低限 `codepoint(::T)` と `T(::UInt32)` を実装すべき
- `hex_chars` 定数配列（282-285行目）は show やその他の16進表示で共有使用される
- Julia 1.12 以降、`codepoint(c)` はオーバーロングエンコーディングに対しても動作する

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | char.jl | `base/char.jl` | AbstractChar docstring（5-37行目）: 抽象文字型のインターフェース定義 |
| 1-2 | char.jl | `base/char.jl` | Char docstring（39-52行目）: 32ビット文字型の説明 |
| 1-3 | char.jl | `base/char.jl` | InvalidCharError / CodePointError 例外型（102-107行目） |

**読解のコツ**: `Char` は `Core` で定義されたプリミティブ型であり、char.jl はそのメソッド群を定義するファイルである。`bitcast(UInt32, c)` と `reinterpret(UInt32, c)` の使い分けに注意。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | char.jl | `base/char.jl` | Char(u::UInt32) コンストラクタ（190-198行目）: UTF-8 エンコード処理 |
| 2-2 | char.jl | `base/char.jl` | UInt32(c::Char) 変換（158-171行目）: UTF-8 デコード処理 |
| 2-3 | char.jl | `base/char.jl` | codepoint 関数（80-100行目）: コードポイント取得 |

**主要処理フロー**:
1. **190行目**: `u < 0x80` の場合、`bitcast(Char, u << 24)` で直接変換（ASCII高速パス）
2. **192行目**: `u < 0x00200000` の上限チェック（Unicode + 一部拡張の範囲）
3. **193-197行目**: UTF-8 マルチバイトエンコーディングのビット演算
4. **158-161行目**: UInt32 変換で `u < 0x80000000` の ASCII 高速パス

#### Step 3: 文字操作メソッドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | char.jl | `base/char.jl` | ncodeunits（71-78行目）: UTF-8 バイト数算出 |
| 3-2 | char.jl | `base/char.jl` | ismalformed / isoverlong（111-124行目）: 不正エンコーディング検出 |
| 3-3 | char.jl | `base/char.jl` | 比較演算子（242-250行目）: ==, isless, hash |
| 3-4 | char.jl | `base/char.jl` | 算術演算子（253-274行目）: +, - |
| 3-5 | char.jl | `base/char.jl` | show（310-344行目）: 文字の表示 |

**主要処理フロー**:
- **71-78行目**: `ncodeunits` は `trailing_zeros` で末尾ゼロバイト数を算出
- **242行目**: `==(x::Char, y::Char)` は `bitcast(UInt32, x) == bitcast(UInt32, y)` で高速比較
- **264-273行目**: `+(x::T, y::Integer)` は ASCII 高速パスを備え、範囲外の場合は一般変換にフォールバック

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

```
'a' (文字リテラル)
    |
    +-- Char(u::UInt32)                    [コンストラクタ]
    |       +-- bitcast(Char, ...)         [ビットレベル変換]
    |
    +-- codepoint(c::Char)                 [コードポイント取得]
    |       +-- UInt32(c::Char)
    |               +-- bitcast(UInt32, c)
    |               +-- leading_ones(u)
    |               +-- throw_invalid_char(c) [不正時]
    |
    +-- ncodeunits(c::Char)                [UTF-8バイト数]
    |       +-- reinterpret(UInt32, c)
    |       +-- trailing_zeros(u)
    |
    +-- ismalformed(c::Char)               [不正チェック]
    |       +-- bitcast(UInt32, c)
    |       +-- leading_ones / trailing_zeros
    |
    +-- show(io, c::AbstractChar)          [表示]
    |       +-- isoverlong(c) / ismalformed(c)
    |       +-- show_invalid(io, c)        [不正文字の16進表示]
    |       +-- isprint(c)
    |       +-- codepoint(c)
    |
    +-- show(io, ::MIME"text/plain", c)    [詳細表示]
            +-- show(io, c)
            +-- Unicode.category_abbrev(c)
            +-- Unicode.category_string(c)
```

### データフロー図

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

UInt32 コードポイント --> Char(u::UInt32) ---------> Char 値
                              |
                              +-> UTF-8 エンコード
                              +-> bitcast

Char 値 -----------------> codepoint(c) -----------> UInt32
                              |
                              +-> UTF-8 デコード
                              +-> ビットマスク演算

Char 値 -----------------> show(io, c) -----------> IO ストリーム
                              |
                              +-> エスケープシーケンス変換
                              +-> Unicode カテゴリ情報
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| char.jl | `base/char.jl` | ソース | Char 型のメソッド群（コンストラクタ、変換、比較、算術、表示） |
| boot.jl | `base/boot.jl` | ソース | Char プリミティブ型の定義（Core） |
| strings/basic.jl | `base/strings/basic.jl` | ソース | 文字列中の文字アクセス基盤 |
| Unicode/ | `stdlib/Unicode/` | stdlib | Unicode 文字カテゴリ判定・正規化（isletter, isdigit 等） |
