================================================================================
Nyash 糖衣構文 可逆フォーマッター仕様
2025-09-03
================================================================================

【コンセプト】
極限短縮構文 ⇄ 標準構文の相互変換ツール（Nyashで実装）

================================================================================
1. 基本設計
================================================================================

box NyashFormatter {
    mode: FormatterMode  // Compact | Standard | Verbose
    
    birth() {
        me.mode = FormatterMode.Standard
    }
    
    // 短縮 → 標準への展開
    expand(code: StringBox) -> StringBox {
        code |> tokenize
             |> expandSugar
             |> format(me.mode)
             |> toString
    }
    
    // 標準 → 短縮への圧縮
    compact(code: StringBox) -> StringBox {
        code |> tokenize
             |> compactSugar
             |> minify
             |> toString
    }
}

================================================================================
2. 変換規則マッピング
================================================================================

// 糖衣構文の変換ルールを定義
static box SugarRules {
    // 暗黙変数の展開
    expandImplicit(ast) {
        peek ast {
            ImplicitVar("$_") => {
                // コンテキストから引数名を推論
                local argName = inferArgumentName(ast.context)
                Identifier(argName)
            }
            ImplicitVar("$1") => Identifier("_arg1")
            ImplicitVar("$2") => Identifier("_arg2")
            else => ast
        }
    }
    
    // パイプラインの展開
    expandPipeline(ast) {
        peek ast {
            Pipeline(expr, func) => {
                // x |> f(a,b) → f(a, b, x)
                peek func {
                    Call(name, args) => Call(name, [...args, expr])
                    PropertyAccess(prop) => PropertyAccess(expr, prop)
                    else => Call(func, [expr])
                }
            }
            else => ast
        }
    }
    
    // 短縮演算子の展開
    expandOperators(ast) {
        peek ast {
            MapOp(list, expr) => {
                // list /: expr → list.map(expr)
                MethodCall(list, "map", [expandLambda(expr)])
            }
            FilterOp(list, expr) => {
                // list \: expr → list.filter(expr)
                MethodCall(list, "filter", [expandLambda(expr)])
            }
            else => ast
        }
    }
}

================================================================================
3. フォーマットモード
================================================================================

// 3段階の詳細度
enum FormatterMode {
    Compact,   // 極限短縮
    Standard,  // 標準的な記法
    Verbose    // 初心者向け詳細
}

// モード別の変換例
box FormatExamples {
    showModes() {
        local code = "[$.name for users if $.age > 18]"
        
        print("=== Compact (極限) ===")
        print(code)
        
        print("=== Standard (標準) ===")
        local standard = formatter.expand(code)
        print(standard)
        // [user.name for user in users if user.age > 18]
        
        print("=== Verbose (詳細) ===")
        local verbose = formatter.expandVerbose(code)
        print(verbose)
        // local result = new ArrayBox()
        // for user in users {
        //     if user.age > 18 {
        //         result.push(user.name)
        //     }
        // }
    }
}

================================================================================
4. 実装例：主要な糖衣構文の変換
================================================================================

// 1. 暗黙変数
"list /: {$_*2}"
↓ expand
"list.map(fn(item) { return item * 2 })"

// 2. パイプライン
"input |> trim |> upper"
↓ expand
"upper(trim(input))"

// 3. null安全
"user?.profile?.name ?? 'Anonymous'"
↓ expand
"peek user {
    null => 'Anonymous'
    else => peek user.profile {
        null => 'Anonymous'
        else => peek user.profile.name {
            null => 'Anonymous'
            else => user.profile.name
        }
    }
}"

// 4. キーワード短縮
"l x = 42; ^ x*2"
↓ expand
"local x = 42
return x * 2"

// 5. 演算子セクション
"nums /: (+1)"
↓ expand
"nums.map(fn(x) { return x + 1 })"

// 6. リスト内包
"[x*x for x in nums if x%2==0]"
↓ expand (Standard)
"nums.filter(fn(x) { return x % 2 == 0 })
     .map(fn(x) { return x * x })"
↓ expand (Verbose)
"local result = new ArrayBox()
for x in nums {
    if x % 2 == 0 {
        result.push(x * x)
    }
}
result"

================================================================================
5. 使用例：コマンドラインツール
================================================================================

// nyashfmt.hako - フォーマッターCLI
static box Main {
    main(args) {
        local formatter = new NyashFormatter()
        local mode = args[1] ?? "standard"
        local file = args[2]
        
        peek mode {
            "expand" => {
                local code = FileBox.read(file)
                local expanded = formatter.expand(code)
                print(expanded)
            }
            "compact" => {
                local code = FileBox.read(file)
                local compacted = formatter.compact(code)
                print(compacted)
            }
            "check" => {
                // 可逆性チェック
                local original = FileBox.read(file)
                local round = original |> formatter.compact
                                      |> formatter.expand
                                      |> formatter.compact
                
                if round == formatter.compact(original) {
                    print("✅ 可逆変換OK")
                } else {
                    print("❌ 変換エラー：情報が失われています")
                }
            }
            else => {
                print("Usage: nyashfmt [expand|compact|check] <file>")
            }
        }
    }
}

================================================================================
6. エディタ統合
================================================================================

// VSCode/エディタ向けのフォーマッター統合
box EditorFormatter {
    // 選択範囲の展開/圧縮
    formatSelection(text, mode) {
        local formatter = new NyashFormatter()
        
        peek mode {
            "toggle" => {
                // 自動判定：短縮記法が含まれていれば展開、なければ圧縮
                if me.hasShortSyntax(text) {
                    formatter.expand(text)
                } else {
                    formatter.compact(text)
                }
            }
            "expand" => formatter.expand(text)
            "compact" => formatter.compact(text)
            else => text
        }
    }
    
    // ホバー時のツールチップ表示
    showExpanded(position) {
        local ast = me.getAstAt(position)
        local expanded = SugarRules.expandNode(ast)
        
        // ツールチップに展開形を表示
        return "展開形: " + expanded.toString()
    }
}

================================================================================
7. 学習モード（初心者支援）
================================================================================

box LearningMode {
    // 段階的に糖衣構文を導入
    suggestSugar(code) {
        local suggestions = new ArrayBox()
        
        // パターンマッチで改善可能な箇所を検出
        if code.contains("list.map(fn(x) { return") {
            suggestions.push({
                original: "list.map(fn(x) { return x * 2 })",
                sugar: "list /: {$_*2}",
                explanation: "/: は map の短縮記法です"
            })
        }
        
        if code.contains("if x != null") {
            suggestions.push({
                original: "if x != null { x.method() } else { null }",
                sugar: "x?.method()",
                explanation: "?. でnullチェックを簡潔に"
            })
        }
        
        return suggestions
    }
}

================================================================================
8. 設定ファイル
================================================================================

// .hakofmt.json - プロジェクト別設定
{
    "mode": "standard",
    "rules": {
        "implicit_variable": true,      // $_ を許可
        "short_keywords": true,         // l, ^, fn を許可
        "unicode_operators": false,     // λ, → は使わない
        "pipeline": true,              // |> を許可
        "list_comprehension": true,    // [...for...] を許可
        "operator_sections": true      // (+1) を許可
    },
    "expand_on_save": false,           // 保存時に展開
    "check_reversibility": true        // 可逆性チェック
}

================================================================================