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

@ -5,11 +5,16 @@ from __future__ import annotations
from typing import Any, List, Tuple
import os
import sys
# NamingBox SSOT: Add parent directory to path for naming_helper import
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from naming_helper import encode_static_method
def try_intrinsic(name: str, args: List[Any]) -> Tuple[bool, Any]:
try:
if name == "Main.esc_json/1":
# NamingBox SSOT: Use encode_static_method for name comparison
if name == encode_static_method("Main", "esc_json", 1):
s = "" if not args else ("" if args[0] is None else str(args[0]))
out = []
for ch in s:
@ -41,7 +46,8 @@ def try_intrinsic(name: str, args: List[Any]) -> Tuple[bool, Any]:
start = idx + len(key)
ok, digits = try_intrinsic("MiniVm.read_digits/2", [js, start])
return True, digits
if name == "Main.dirname/1":
# NamingBox SSOT: Use encode_static_method for name comparison
if name == encode_static_method("Main", "dirname", 1):
p = "" if not args else ("" if args[0] is None else str(args[0]))
d = os.path.dirname(p)
if d == "":