feat(naming): Python NamingHelper実装 - Rust NamingBoxのミラー完成

Phase 25.4 メンテナンス: Python LLVM側のNamingBox SSOT統一

## 📦 実装内容

### 1. Python NamingHelper作成
- 新規作成: `src/llvm_py/naming_helper.py`
- Rust `src/mir/naming.rs` と完全同一の意味論を実装
- 3つの関数:
  - `encode_static_method(box_name, method, arity)` → "BoxName.method/arity"
  - `canonical_box_name(raw)` → "main" → "Main"
  - `normalize_static_global_name(func_name)` → "main._nop/0" → "Main._nop/0"
- doctest 9個全てPASS 

### 2. Python LLVM側の統一修正
- `instructions/boxcall.py:437` - f"Main.{method_name}/{arity}" → encode_static_method()
- `instructions/call.py:170-173` - traced_names タプル生成をNamingHelper経由に変更
- `pyvm/intrinsic.py:17, 50` - "Main.esc_json/1", "Main.dirname/1" → encode_static_method()
- `builders/entry.py:16` - 'Main.main/1' → encode_static_method("Main", "main", 1)

## 🎯 技術的成果
- **意味論一致**: Rust ↔ Python で完全同一の命名規則
- **保守性向上**: ハードコード4箇所 → NamingHelper一元管理
- **テスト完備**: doctest 9個でRust NamingBoxと同一動作を保証

## テスト結果
 python3 -m py_compile: 全ファイル構文OK
 python3 -m doctest naming_helper.py: 9 tests passed

## 参考
- Phase 25.4-A (Rust側): fa9cea51, bceb20ed
- Rust NamingBox SSOT: src/mir/naming.rs

🎉 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-11-21 09:38:49 +09:00
parent bceb20ed66
commit 419214a5a9
5 changed files with 114 additions and 7 deletions

View File

@ -6,6 +6,7 @@ Core of Nyash's "Everything is Box" philosophy
import llvmlite.ir as ir
from typing import Dict, List, Optional, Any
from instructions.safepoint import insert_automatic_safepoint
from naming_helper import encode_static_method
def _declare(module: ir.Module, name: str, ret, args):
for f in module.functions:
@ -431,9 +432,9 @@ def lower_boxcall(
except Exception:
pass
if is_me and cur_fn_name.startswith('Main.'):
# Build target function name with arity
# NamingBox SSOT: Build target function name with arity
arity = len(args)
target = f"Main.{method_name}/{arity}"
target = encode_static_method("Main", method_name, arity)
# If module already has such function, prefer direct call
callee = None
for f in module.functions:

View File

@ -7,6 +7,7 @@ import llvmlite.ir as ir
from typing import Dict, List, Optional, Any
from trace import debug as trace_debug
from instructions.safepoint import insert_automatic_safepoint
from naming_helper import encode_static_method
def lower_call(
builder: ir.IRBuilder,
@ -165,8 +166,13 @@ def lower_call(
# Make the call
result = builder.call(func, call_args, name=f"call_{func_name}")
# Optional trace for final debugging
if isinstance(actual_name, str) and actual_name in ("Main.node_json/3", "Main.esc_json/1", "main"):
# NamingBox SSOT: Optional trace for final debugging
traced_names = (
encode_static_method("Main", "node_json", 3),
encode_static_method("Main", "esc_json", 1),
"main"
)
if isinstance(actual_name, str) and actual_name in traced_names:
trace_debug(f"[TRACE] call {actual_name} args={len(call_args)}")
# Store result if needed