📚 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:
@ -5,6 +5,8 @@ Handles +, -, *, /, %, &, |, ^, <<, >>
|
||||
|
||||
import llvmlite.ir as ir
|
||||
from typing import Dict
|
||||
from .compare import lower_compare
|
||||
import llvmlite.ir as ir
|
||||
|
||||
def lower_binop(
|
||||
builder: ir.IRBuilder,
|
||||
@ -14,7 +16,10 @@ def lower_binop(
|
||||
rhs: int,
|
||||
dst: int,
|
||||
vmap: Dict[int, ir.Value],
|
||||
current_block: ir.Block
|
||||
current_block: ir.Block,
|
||||
preds=None,
|
||||
block_end_values=None,
|
||||
bb_map=None
|
||||
) -> None:
|
||||
"""
|
||||
Lower MIR BinOp instruction
|
||||
@ -31,18 +36,72 @@ def lower_binop(
|
||||
"""
|
||||
# Resolve operands as i64 (using resolver when available)
|
||||
# For now, simple vmap lookup
|
||||
lhs_val = vmap.get(lhs, ir.Constant(ir.IntType(64), 0))
|
||||
rhs_val = vmap.get(rhs, ir.Constant(ir.IntType(64), 0))
|
||||
if resolver is not None and preds is not None and block_end_values is not None:
|
||||
lhs_val = resolver.resolve_i64(lhs, current_block, preds, block_end_values, vmap, bb_map)
|
||||
rhs_val = resolver.resolve_i64(rhs, current_block, preds, block_end_values, vmap, bb_map)
|
||||
else:
|
||||
lhs_val = vmap.get(lhs, ir.Constant(ir.IntType(64), 0))
|
||||
rhs_val = vmap.get(rhs, ir.Constant(ir.IntType(64), 0))
|
||||
|
||||
# Relational/equality operators delegate to compare
|
||||
if op in ('==','!=','<','>','<=','>='):
|
||||
lower_compare(builder, op, lhs, rhs, dst, vmap)
|
||||
return
|
||||
|
||||
# String-aware concatenation unified to handles (i64) when any side is pointer string
|
||||
if op == '+':
|
||||
i64 = ir.IntType(64)
|
||||
i8p = ir.IntType(8).as_pointer()
|
||||
lhs_raw = vmap.get(lhs)
|
||||
rhs_raw = vmap.get(rhs)
|
||||
is_str = (hasattr(lhs_raw, 'type') and isinstance(lhs_raw.type, ir.PointerType)) or \
|
||||
(hasattr(rhs_raw, 'type') and isinstance(rhs_raw.type, ir.PointerType))
|
||||
if is_str:
|
||||
# Helper: convert raw or resolved value to string handle
|
||||
def to_handle(raw, val, tag: str):
|
||||
if raw is not None and hasattr(raw, 'type') and isinstance(raw.type, ir.PointerType):
|
||||
# pointer-to-array -> GEP
|
||||
try:
|
||||
if isinstance(raw.type.pointee, ir.ArrayType):
|
||||
c0 = ir.Constant(ir.IntType(32), 0)
|
||||
raw = builder.gep(raw, [c0, c0], name=f"bin_gep_{tag}_{dst}")
|
||||
except Exception:
|
||||
pass
|
||||
cal = None
|
||||
for f in builder.module.functions:
|
||||
if f.name == 'nyash.box.from_i8_string':
|
||||
cal = f; break
|
||||
if cal is None:
|
||||
cal = ir.Function(builder.module, ir.FunctionType(i64, [i8p]), name='nyash.box.from_i8_string')
|
||||
return builder.call(cal, [raw], name=f"str_ptr2h_{tag}_{dst}")
|
||||
# if already i64
|
||||
if val is not None and hasattr(val, 'type') and isinstance(val.type, ir.IntType) and val.type.width == 64:
|
||||
return val
|
||||
return ir.Constant(i64, 0)
|
||||
|
||||
hl = to_handle(lhs_raw, lhs_val, 'l')
|
||||
hr = to_handle(rhs_raw, rhs_val, 'r')
|
||||
# concat_hh(handle, handle) -> handle
|
||||
hh_fnty = ir.FunctionType(i64, [i64, i64])
|
||||
callee = None
|
||||
for f in builder.module.functions:
|
||||
if f.name == 'nyash.string.concat_hh':
|
||||
callee = f; break
|
||||
if callee is None:
|
||||
callee = ir.Function(builder.module, hh_fnty, name='nyash.string.concat_hh')
|
||||
res = builder.call(callee, [hl, hr], name=f"concat_hh_{dst}")
|
||||
vmap[dst] = res
|
||||
return
|
||||
|
||||
# Ensure both are i64
|
||||
i64 = ir.IntType(64)
|
||||
if hasattr(lhs_val, 'type') and lhs_val.type != i64:
|
||||
# Type conversion if needed
|
||||
if lhs_val.type.is_pointer:
|
||||
lhs_val = builder.ptrtoint(lhs_val, i64)
|
||||
lhs_val = builder.ptrtoint(lhs_val, i64, name=f"binop_lhs_p2i_{dst}")
|
||||
if hasattr(rhs_val, 'type') and rhs_val.type != i64:
|
||||
if rhs_val.type.is_pointer:
|
||||
rhs_val = builder.ptrtoint(rhs_val, i64)
|
||||
rhs_val = builder.ptrtoint(rhs_val, i64, name=f"binop_rhs_p2i_{dst}")
|
||||
|
||||
# Perform operation
|
||||
if op == '+':
|
||||
@ -73,4 +132,4 @@ def lower_binop(
|
||||
result = ir.Constant(i64, 0)
|
||||
|
||||
# Store result
|
||||
vmap[dst] = result
|
||||
vmap[dst] = result
|
||||
|
||||
Reference in New Issue
Block a user