Files
hakorune/docs/development/roadmap/phases/phase-12.7/ancp-specs/sugar-formatter-tool.txt

303 lines
9.1 KiB
Plaintext
Raw Normal View History

================================================================================
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.nyash - フォーマッター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. 設定ファイル
================================================================================
// .nyashfmt.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 // 可逆性チェック
}
================================================================================