docs(phase173): Phase 173 Task 1-3 complete - investigation, spec, and JsonParserBox bugfix
📚 Phase 173 前半完了(Task 1-3)! ✅ Task 1: 名前解決経路調査 - UsingResolverBox / CalleeResolverBox 構造把握 - 3つの重大問題発見: 1. 静的 Box が InstanceBox として扱われる 2. JsonParserBox _parse_number 無限ループ 3. new Alias.BoxName() 構文未サポート ✅ Task 2: 仕様固定(docs) - using.md: +179行(静的 Box 使用例) - LANGUAGE_REFERENCE_2025.md: +54行(static box ライブラリ方針) ✅ Task 3: JsonParserBox バグ修正 - MIR Nested-If-in-Loop Bug 発見・回避 - while → loop() 構文統一(10箇所) - ネスト if-else のフラット化 📋 成果物: - phase173_task1_investigation.md(220行) - phase173_using_static_box_resolution.md - phase173-2_using_resolver_mir_lowering.md(後半指示書) - mir-nested-if-loop-bug.md(バグ分析) - json_parser_min.hako(テストファイル) 🎯 次: Task 4-6(using resolver + MIR lowering 統合) 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -91,6 +91,186 @@ Deprecated: `include`
|
||||
- nyash.toml `[imports] HttpClient = "network.HttpClient"`
|
||||
- needs sugar: `needs plugin.network.HttpClient as HttpClient` (file‑scoped alias)
|
||||
|
||||
## 📦 静的 Box の using(Phase 173+)
|
||||
|
||||
**実装状況**: Phase 173 で実装中(2025-12-04)
|
||||
|
||||
### 基本概念
|
||||
|
||||
静的 Box(`static box`)をライブラリとして `using` で import し、静的メソッドを呼び出す機能。
|
||||
|
||||
```hako
|
||||
// 静的 Box の定義(ライブラリ側)
|
||||
static box JsonParserBox {
|
||||
method parse(json_str) {
|
||||
// JSON文字列をパース
|
||||
return me._parse_value(json_str, 0).get("value")
|
||||
}
|
||||
|
||||
_parse_value(s, pos) {
|
||||
// 内部メソッド(private的な扱い)
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```hako
|
||||
// 静的 Box の使用(呼び出し側)
|
||||
using tools.hako_shared.json_parser as JsonParserBox
|
||||
|
||||
static box Main {
|
||||
main() {
|
||||
// 静的メソッド呼び出し(インスタンス化不要)
|
||||
local result = JsonParserBox.parse("{\"x\":1}")
|
||||
|
||||
// 結果の利用
|
||||
if result != null {
|
||||
local x = result.get("x")
|
||||
print("x = " + x)
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 許容される呼び出しパターン
|
||||
|
||||
#### ✅ Phase 173 で実装済み
|
||||
|
||||
1. **静的メソッド直接呼び出し**
|
||||
```hako
|
||||
using tools.hako_shared.json_parser as JsonParserBox
|
||||
|
||||
local value = JsonParserBox.parse("{\"x\":1}")
|
||||
```
|
||||
- `JsonParserBox` は静的 Box のエイリアス
|
||||
- `parse()` は静的メソッド
|
||||
- インスタンス化不要
|
||||
|
||||
#### 🚧 Phase 174+ で実装予定
|
||||
|
||||
2. **名前空間的な Box アクセス**(未実装)
|
||||
```hako
|
||||
using lib.containers as Containers
|
||||
|
||||
local list = new Containers.ListBox() // エラー(Phase 173 時点)
|
||||
local map = new Containers.MapBox() // エラー(Phase 173 時点)
|
||||
```
|
||||
- `new Alias.BoxName()` 構文は未サポート
|
||||
- パーサーエラー: `Unexpected token DOT, expected LPAREN`
|
||||
|
||||
### 静的 Box vs インスタンス Box
|
||||
|
||||
| 特徴 | 静的 Box | インスタンス Box |
|
||||
|-----|---------|----------------|
|
||||
| 定義 | `static box BoxName { }` | `box BoxName { }` |
|
||||
| インスタンス化 | 不要(シングルトン) | 必要(`new BoxName()`) |
|
||||
| メソッド呼び出し | `BoxName.method()` | `instance.method()` |
|
||||
| 状態保持 | 共有状態(グローバル的) | インスタンスごと |
|
||||
| using での扱い | 型として登録 | 型として登録 |
|
||||
| 典型的用途 | ユーティリティ、パーサー | データ構造、オブジェクト |
|
||||
|
||||
### 実装の技術的詳細
|
||||
|
||||
#### 名前解決の流れ
|
||||
|
||||
1. **using statement 解決**(`.hako` 側)
|
||||
- `UsingResolverBox.resolve_path_alias()` でファイルパス解決
|
||||
- エイリアスを「型」として環境に登録(Phase 173 で実装)
|
||||
|
||||
2. **AST 生成**(`.hako` パーサー)
|
||||
- `Alias.method()` を静的Box呼び出しとして認識
|
||||
- フラグ `is_static_box_call: true` を付与(Phase 173 で実装)
|
||||
|
||||
3. **MIR lowering**(Rust 側)
|
||||
- `CalleeResolverBox.resolve()` で Callee に変換
|
||||
- 静的Box呼び出しは `Callee::Global("BoxName.method/arity")` に解決
|
||||
- VM 実行時に正しく静的メソッドとして呼び出される
|
||||
|
||||
#### Phase 171-2 で発見された問題
|
||||
|
||||
**症状**:
|
||||
```
|
||||
[ERROR] ❌ [rust-vm] VM error: Unknown method '_skip_whitespace' on InstanceBox
|
||||
```
|
||||
|
||||
**原因**:
|
||||
- using で import した静的 Box が「インスタンス」として扱われていた
|
||||
- 内部メソッド(`_skip_whitespace` 等)が解決できず
|
||||
|
||||
**解決**: Phase 173 で using system を修正し、静的 Box を型として正しく登録
|
||||
|
||||
### 使用例
|
||||
|
||||
#### JsonParserBox の利用
|
||||
```hako
|
||||
using tools.hako_shared.json_parser as JsonParserBox
|
||||
|
||||
static box HakoAnalysisBuilderBox {
|
||||
_extract_cfg_from_mir_json(json_text) {
|
||||
// JsonParserBox を使った JSON パース
|
||||
local root = JsonParserBox.parse(json_text)
|
||||
if root == null { return me._empty_cfg() }
|
||||
|
||||
// CFG オブジェクトの抽出
|
||||
local cfg = root.get("cfg")
|
||||
if cfg == null { return me._empty_cfg() }
|
||||
|
||||
local functions = cfg.get("functions")
|
||||
// ... 以下、CFG 処理続行
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### ProgramJSONBox の利用(Phase 172)
|
||||
```hako
|
||||
using tools.hako_shared.json_parser as JsonParserBox
|
||||
|
||||
static box Compiler {
|
||||
load_program(json_str) {
|
||||
// Program JSON v0 をパース
|
||||
local program = JsonParserBox.parse_program(json_str)
|
||||
if program == null { return null }
|
||||
|
||||
// ProgramJSONBox インスタンスから情報取得
|
||||
local version = program.get_version() // "0"
|
||||
local kind = program.get_kind() // "program"
|
||||
local defs = program.get_defs() // ArrayBox
|
||||
|
||||
return program
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 制限事項(Phase 173 時点)
|
||||
|
||||
1. **パーサー制限**
|
||||
- `new Alias.BoxName()` 構文は未サポート
|
||||
- 静的 Box 内の Box 定義をインスタンス化できない
|
||||
|
||||
2. **名前空間階層**
|
||||
- `Alias.Namespace.BoxName` のような多階層は未サポート
|
||||
- エイリアスは1階層のみ
|
||||
|
||||
3. **型推論**
|
||||
- 静的メソッドの戻り値型は動的(MapBox/ArrayBox 等)
|
||||
- コンパイル時型チェックなし
|
||||
|
||||
### Phase 174+ での拡張予定
|
||||
|
||||
1. **名前空間的 Box アクセス**
|
||||
- `new Alias.BoxName()` 構文のサポート
|
||||
- パーサー修正による対応
|
||||
|
||||
2. **型システム統合**
|
||||
- HIR 層の導入
|
||||
- 静的型推論の強化
|
||||
|
||||
3. **明示的スコープ**
|
||||
- `::` 演算子のサポート
|
||||
- `BoxName::static_method()` 構文
|
||||
|
||||
## Plugins
|
||||
- Unified namespace with Boxes. Prefer short names when unique.
|
||||
- Qualified form: `network.HttpClient`
|
||||
|
||||
Reference in New Issue
Block a user