📚 Phase 15計画を詳細化・更新: Python/llvmlite正式採用とプラグイン全方向ビルド戦略

 主な更新内容:
- Python/llvmlite実装の正式採用を明記(開発速度10倍、~2400行)
- プラグイン全方向ビルド戦略(.so/.o/.a同時生成)で単一EXE生成可能に
- 各実装の予想コード量を具体化(パーサー800行、MIR Builder 2500行、VM 5000行)
- 循環依存問題の解決を明記(nyrtがC ABI経由で提供)
- 現実的なスケジュール調整(2025年9月~2026年3月)

🎉 最新進捗:
- dep_tree_min_string.nyashオブジェクト生成成功(10.4KB)
- LLVM verifier green - dominance違反解決
- Resolver patternでSSA安全性確保

🚀 次のマイルストーン:
- Python/llvmliteでEXE生成パイプライン完成
- nyash-llvm-compiler分離設計
- NyashパーサーMVP実装開始

Everything is Boxの究極形が、ついに実現へ!

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Selfhosting Dev
2025-09-13 15:37:58 +09:00
parent 8e4f6d774d
commit 1d6fab4eda
44 changed files with 1653 additions and 598 deletions

View File

@ -29,60 +29,40 @@ def lower_newbox(
vmap: Value map
resolver: Optional resolver for type handling
"""
# Look up or declare the box creation function
create_func_name = f"ny_create_{box_type}"
create_func = None
# Use NyRT shim: nyash.env.box.new(type_name: i8*) -> i64
i64 = ir.IntType(64)
i8p = ir.IntType(8).as_pointer()
# Prefer variadic shim: nyash.env.box.new_i64x(type_name, argc, a1, a2, a3, a4)
new_i64x = None
for f in module.functions:
if f.name == create_func_name:
create_func = f
if f.name == "nyash.env.box.new_i64x":
new_i64x = f
break
if not create_func:
# Declare box creation function
# Signature depends on box type
i64 = ir.IntType(64)
i8 = ir.IntType(8)
if box_type in ["StringBox", "IntegerBox", "BoolBox"]:
# Built-in boxes - default constructors (no args)
# Real implementation may have optional args
func_type = ir.FunctionType(i64, [])
else:
# Generic box - variable arguments
# For now, assume no args
func_type = ir.FunctionType(i64, [])
create_func = ir.Function(module, func_type, name=create_func_name)
# Prepare arguments
call_args = []
for i, arg_id in enumerate(args):
arg_val = vmap.get(arg_id)
if not arg_val:
# Default based on box type
if box_type == "StringBox":
# Empty string
i8 = ir.IntType(8)
arg_val = ir.Constant(i8.as_pointer(), None)
else:
# Zero
arg_val = ir.Constant(ir.IntType(64), 0)
# Type conversion if needed
if box_type == "StringBox" and hasattr(arg_val, 'type'):
if isinstance(arg_val.type, ir.IntType):
# int to string ptr
i8 = ir.IntType(8)
arg_val = builder.inttoptr(arg_val, i8.as_pointer())
call_args.append(arg_val)
# Create the box
handle = builder.call(create_func, call_args, name=f"new_{box_type}")
# Store handle
if not new_i64x:
new_i64x = ir.Function(module, ir.FunctionType(i64, [i8p, i64, i64, i64, i64, i64]), name="nyash.env.box.new_i64x")
# Build C-string for type name (unique global per function)
sbytes = (box_type + "\0").encode('utf-8')
arr_ty = ir.ArrayType(ir.IntType(8), len(sbytes))
try:
fn = builder.block.parent
fn_name = getattr(fn, 'name', 'fn')
except Exception:
fn_name = 'fn'
base = f".box_ty_{fn_name}_{dst_vid}"
existing = {g.name for g in module.global_values}
name = base
n = 1
while name in existing:
name = f"{base}.{n}"; n += 1
g = ir.GlobalVariable(module, arr_ty, name=name)
g.linkage = 'private'
g.global_constant = True
g.initializer = ir.Constant(arr_ty, bytearray(sbytes))
c0 = ir.Constant(ir.IntType(32), 0)
ptr = builder.gep(g, [c0, c0], inbounds=True)
zero = ir.Constant(i64, 0)
handle = builder.call(new_i64x, [ptr, zero, zero, zero, zero, zero], name=f"new_{box_type}")
vmap[dst_vid] = handle
def lower_newbox_generic(
@ -113,4 +93,4 @@ def lower_newbox_generic(
size = ir.Constant(ir.IntType(64), 64)
handle = builder.call(alloc_func, [size], name="new_box")
vmap[dst_vid] = handle
vmap[dst_vid] = handle