Files
hakorune/docs/development/current/main/phase174-jsonparser-p5b-design.md
nyash-codex 309d0803c7 feat(joinir): Phase 174 - JsonParser complex loop P5 extension design
- Task 174-1: Complex loop inventory (_parse_string/_parse_array/_parse_object)
  - Analyzed remaining JsonParser loops for P5 expansion potential
  - Identified _parse_string as most Trim-like structure (99% similarity)
  - Documented complexity scores and minimization potential

- Task 174-2: Selected _parse_string as next P5 target (closest to Trim)
  - Reason: LoopBodyLocal 'ch' usage matches Trim pattern exactly
  - Structure: loop(pos < len) + substring + char comparison + break
  - Minimization: Remove escape/buffer/continue → identical to Trim

- Task 174-3: Design doc for P5B extension (TrimLoopHelper reuse strategy)
  - File: docs/development/current/main/phase174-jsonparser-p5b-design.md
  - Strategy: Reuse existing TrimLoopHelper without modifications
  - Proven: Pattern applies to any character comparison, not just whitespace

- Task 174-4: Minimal PoC (_parse_string without escape) successful
  - Test: local_tests/test_jsonparser_parse_string_min.hako
  - Result: [pattern2/trim] Safe Trim pattern detected 
  - Detection: Trim with literals=['"'] (quote instead of whitespace)
  - Routing: Added whitelist entries for JsonParserStringTest methods

- Task 174-5: Documentation updates
  - Updated CURRENT_TASK.md with Phase 174 summary
  - Updated joinir-architecture-overview.md with P5 generality proof
  - Created phase174-jsonparser-loop-inventory-2.md (detailed analysis)
  - Created phase174-jsonparser-p5b-design.md (implementation strategy)

Success Criteria Met:
 _parse_string minimized version runs on P5 pipeline
 TrimLoopHelper works with '"' (non-whitespace character)
 Proven: Trim pattern is character-comparison-generic, not whitespace-specific
 Two new design docs (inventory + design)
 Phase 175+ roadmap established (multi-carrier, escape sequences)

Technical Achievement:
The P5 Trim pipeline successfully handled a quote-detection loop with zero code changes,
proving the architecture's generality beyond whitespace trimming.
2025-12-08 13:08:44 +09:00

9.9 KiB
Raw Blame History

Phase 174-3: JsonParser _parse_string P5B 設計

Date: 2025-12-08 Target: _parse_string ループ(エスケープ処理付き文字列パース) Purpose: Trim P5 パイプラインを複雑ループに拡張する設計


ターゲットループ構造

完全版Phase 175+ のターゲット)

loop(p < s.length()) {
    local ch = s.substring(p, p+1)

    if ch == "\"" {  // 終端クォート
        // End of string
        local result = new MapBox()
        result.set("value", me._unescape_string(str))
        result.set("pos", p + 1)
        result.set("type", "string")
        return result
    }

    if ch == "\\" {  // エスケープ開始
        local has_next = 0
        if p + 1 < s.length() { has_next = 1 }
        if has_next == 0 { return null }

        str = str + ch
        p = p + 1
        str = str + s.substring(p, p+1)
        p = p + 1
        continue
    }

    str = str + ch
    p = p + 1
}

最小化版Phase 174-4 PoC

// エスケープ処理・文字列バッファ・continue・return を除外
loop(pos < len) {
    local ch = s.substring(pos, pos+1)
    if ch == "\"" {
        break
    } else {
        pos = pos + 1
    }
}

Pattern Space 分析

軸 A〜F での分類(最小化版)

説明
A. 継続条件 単純 pos < len
B. 早期終了 条件付き break if ch == "\"" { break }
C. スキップ なし continue 使用なし
D. PHI 分岐 なし if 分岐あるが PHI 不要
E. 条件変数のスコープ LoopBodyLocal ch が条件に使用
F. キャリア更新 単純 pos のみ更新

Pattern 分類: P5LoopBodyLocal 条件)+ Pattern2break 付き)


Trim との差分

同じ部分P5 パイプライン再利用可能)

  1. LoopBodyLocal 変数の使用:

    • Trim: local ch = s.substring(start, start+1)
    • Parse String: local ch = s.substring(pos, pos+1)
    • 完全一致(変数名が異なるだけ)
  2. 文字比較パターン:

    • Trim: if ch == " " || ch == "\t" || ch == "\n" || ch == "\r"
    • Parse String: if ch == "\""
    • 構造は同じ(比較対象が異なるだけ)
  3. Pattern2 構造:

    • Trim: loop(start < end) + { start = start + 1 } else { break }
    • Parse String: loop(pos < len) + { pos = pos + 1 } else { break }
    • 完全同型
  4. キャリア更新:

    • Trim: start = start + 1(単一キャリア)
    • Parse String: pos = pos + 1(単一キャリア)
    • 完全一致

⚠️ 追加部分完全版、Phase 175+ で必要)

  1. 複数キャリア:

    • pos: ループカウンタ
    • str: 文字列バッファ
    • 課題: 既存の TrimLoopHelper は単一キャリア想定
  2. エスケープ処理:

    • if ch == "\\" { ... } → 追加の文字読み込み
    • 課題: LoopBodyLocal の多重使用(chescaped
  3. continue:

    • エスケープ処理後に continue
    • 課題: Pattern4 対応が必要
  4. return による早期終了:

    • 成功時の return
    • 課題: ExitLine とループ外リターンの分離

箱の再利用 vs 追加

再利用可能な既存箱Phase 174-4

箱名 再利用可能性 理由
LoopConditionScopeBox 100% ch を LoopBodyLocal と分類可能
LoopBodyCarrierPromoter 100% ch の昇格検出Trim と同じ)
TrimPatternInfo 100% 基本構造は再利用可能
TrimLoopHelper 100% 単一キャリア版で完全対応
CarrierInfo 100% pos キャリア情報
ExitLine 100% break による終了
Boundary 100% ループ境界情報

結論: 最小化版では既存の箱をそのまま使える

追加が必要な箱Phase 175+ で検討)

  1. MultiCarrierTrimHelper(将来):

    • TrimLoopHelper の拡張版
    • 複数キャリア(pos + str)対応
    • Phase 175 で設計・実装
  2. EscapeSequenceHandler(将来):

    • エスケープ処理の追加ロジック
    • ch == "\\" 時の特殊処理
    • Phase 176 で設計・実装
  3. ContinuePatternHelper(将来):

    • Pattern4continue 付き)対応
    • Phase 176 で設計・実装

Phase 174 戦略

ステップ1: 最小化版で試験Phase 174-4

最小化方針:

  • エスケープ処理を除外
  • 文字列バッファ(str)を除外
  • continue を除外
  • return を break に置換

最小化版:

// Phase 174-4 PoC
loop(pos < len) {
    local ch = s.substring(pos, pos+1)
    if ch == "\"" {
        break
    } else {
        pos = pos + 1
    }
}

この構造の利点:

  • TrimLoopHelper がそのまま使える
  • Pattern2 Trim 特例経路が使える
  • 単一キャリア pos のみ
  • 既存コードの変更ゼロ

期待される動作:

  1. LoopConditionScopeBox::analyze()

    • ch: LoopBodyLocalsubstring でループ内定義)
    • pos, len: OuterLocalループ外定義
  2. LoopBodyCarrierPromoter::try_promote()

    • ch を carrier is_ch_match に昇格
    • 昇格理由: break 条件に使用
  3. TrimLoopHelper::is_safe_trim()

    • true を返すTrim と完全同型)
  4. Pattern2 lowerer

    • Trim 特例経路で JoinIR 生成
    • [pattern2/trim] Safe Trim pattern detected

ステップ2: エスケープ処理の追加Phase 175+

最小化版が成功したら、段階的に追加:

  1. Phase 175: 文字列バッファ追加(複数キャリア対応)

    loop(pos < len) {
        local ch = s.substring(pos, pos+1)
        if ch == "\"" {
            break
        } else {
            result = result + ch  // ← 追加
            pos = pos + 1
        }
    }
    
  2. Phase 176: エスケープ処理追加continue 対応)

    loop(pos < len) {
        local ch = s.substring(pos, pos+1)
        if ch == "\"" {
            break
        } else if ch == "\\" {
            // エスケープ処理
            pos = pos + 1
            result = result + s.substring(pos, pos+1)
            pos = pos + 1
            continue  // ← Pattern4 対応が必要
        } else {
            result = result + ch
            pos = pos + 1
        }
    }
    
  3. Phase 177: return 処理追加ExitLine 拡張)

    loop(pos < len) {
        local ch = s.substring(pos, pos+1)
        if ch == "\"" {
            return create_result(result, pos)  // ← ExitLine 拡張
        }
        // ... 以下同じ
    }
    

命名の汎用化Phase 175+ で検討)

現在の命名Trim 特化)

  • TrimLoopHelper - Trim 専用のような命名
  • is_safe_trim() - Trim 専用のような命名

汎用化案Phase 175+ で検討)

案1: CharComparison

  • CharComparisonLoopHelper
  • is_safe_char_comparison()
  • 利点: 文字比較ループの汎用名
  • 欠点: やや長い

案2: SingleCharBreak

  • SingleCharBreakLoopHelper
  • is_safe_single_char_break()
  • 利点: 構造を正確に表現
  • 欠点: 長い、やや複雑

案3: P5Pattern軸E準拠

  • P5LoopHelper
  • is_safe_p5_pattern()
  • 利点: Pattern Space 軸E と一貫性
  • 欠点: P5 の意味が不明瞭

Phase 174 での方針: 命名変更なし(既存コード保持)

  • Phase 175+ で複数キャリア対応時に再検討
  • 既存の TrimLoopHelper は Trim 専用として保持
  • 新しい汎用版を別途作成する可能性

テスト戦略

Phase 174-4 テストケース

ファイル: local_tests/test_jsonparser_parse_string_min.hako

static box JsonParserStringTest {
    s: StringBox
    pos: IntegerBox
    len: IntegerBox

    parse_string_min() {
        me.s = "hello world\""  // 終端クォート付き
        me.pos = 0
        me.len = me.s.length()

        // 最小化版: エスケープ処理なし、終端クォート検出のみ
        loop(me.pos < me.len) {
            local ch = me.s.charAt(me.pos)
            if ch == "\"" {
                break
            } else {
                me.pos = me.pos + 1
            }
        }

        print("Found quote at position: ")
        print(me.pos)
    }

    main() {
        me.parse_string_min()
        return "OK"
    }
}

期待される出力:

[pattern2/check] 'ch': LoopBodyLocal ✅
[pattern2/promoter] promoted to carrier 'is_ch_match' ✅
[pattern2/trim] Safe Trim pattern detected ✅
Found quote at position: 11

実行コマンド:

NYASH_JOINIR_CORE=1 NYASH_LEGACY_LOOPBUILDER=0 \
  ./target/release/hakorune local_tests/test_jsonparser_parse_string_min.hako

結論

Phase 174-4 では

  • 既存の TrimLoopHelper をそのまま再利用
  • 最小化版(ch == "\""のみ)で P5 パイプライン検証
  • 既存コードの変更ゼロ
  • エスケープ処理・複数キャリア・continue は Phase 175+ に延期

Phase 175+ で検討

  • MultiCarrierTrimHelper の設計
  • エスケープ処理の統合Pattern4 対応)
  • 命名の汎用化Trim → CharComparison
  • return 処理の ExitLine 拡張

技術的価値

Phase 174-4 で実証すべきこと:

  1. Trim パイプラインが文字比較対象が異なるだけで機能すること
  2. "\"(終端クォート)という異なる文字でも昇格パターンが機能すること
  3. TrimLoopHelper の汎用性(空白文字以外にも対応可能)

成功すれば:

  • Trim P5 パイプラインが「Trim 専用」ではなく「文字比較ループ汎用」であることが証明される
  • Phase 175+ での拡張複数キャリア・continue 等)の基盤が確立される