🎉 Phase 11.8/12.7: MIR Core-13 完全実装 + 糖衣構文ドキュメント更新
主要な変更:
- MIR Core-13命令セット確定(Load/Store削除の革命的設計)
- Const, BinOp, Compare(値・計算)
- Jump, Branch, Return, Phi(制御)
- Call, BoxCall, ExternCall(呼び出し)
- TypeOp, Safepoint, Barrier(メタ)
- Phase 12.7糖衣構文ドキュメント整理(超圧縮重視、可逆変換保証)
- MIRビルダーのモジュール分割完了
- vtableテストスイート拡充
- AI協調開発ツール追加(並列リファクタリング支援)
詳細:
- src/mir/instruction_introspection.rs: core13_instruction_names()追加
- MIRビルダー分割: decls.rs, exprs_*.rs, fields.rs
- plugin_loader_v2: errors.rs, host_bridge.rs分離
- 論文用データ: mir13-final.md作成
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-04 11:34:15 +09:00
|
|
|
use super::{BasicBlock, BasicBlockId};
|
2025-09-17 07:43:07 +09:00
|
|
|
use crate::mir::{BarrierOp, TypeOpKind, WeakRefOp};
|
|
|
|
|
use std::fs;
|
2025-09-03 05:04:56 +09:00
|
|
|
|
|
|
|
|
// Resolve include path using nyash.toml include.roots if present
|
|
|
|
|
pub(super) fn resolve_include_path_builder(filename: &str) -> String {
|
|
|
|
|
if filename.starts_with("./") || filename.starts_with("../") {
|
|
|
|
|
return filename.to_string();
|
|
|
|
|
}
|
|
|
|
|
let parts: Vec<&str> = filename.splitn(2, '/').collect();
|
|
|
|
|
if parts.len() == 2 {
|
|
|
|
|
let root = parts[0];
|
|
|
|
|
let rest = parts[1];
|
|
|
|
|
let cfg_path = "nyash.toml";
|
|
|
|
|
if let Ok(toml_str) = fs::read_to_string(cfg_path) {
|
|
|
|
|
if let Ok(toml_val) = toml::from_str::<toml::Value>(&toml_str) {
|
|
|
|
|
if let Some(include) = toml_val.get("include") {
|
|
|
|
|
if let Some(roots) = include.get("roots").and_then(|v| v.as_table()) {
|
|
|
|
|
if let Some(root_path) = roots.get(root).and_then(|v| v.as_str()) {
|
|
|
|
|
let mut base = root_path.to_string();
|
|
|
|
|
if !base.ends_with('/') && !base.ends_with('\\') {
|
|
|
|
|
base.push('/');
|
|
|
|
|
}
|
|
|
|
|
return format!("{}{}", base, rest);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
format!("./{}", filename)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Optional builder debug logging
|
|
|
|
|
pub(super) fn builder_debug_enabled() -> bool {
|
|
|
|
|
std::env::var("NYASH_BUILDER_DEBUG").is_ok()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(super) fn builder_debug_log(msg: &str) {
|
|
|
|
|
if builder_debug_enabled() {
|
|
|
|
|
eprintln!("[BUILDER] {}", msg);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
🎉 Phase 11.8/12.7: MIR Core-13 完全実装 + 糖衣構文ドキュメント更新
主要な変更:
- MIR Core-13命令セット確定(Load/Store削除の革命的設計)
- Const, BinOp, Compare(値・計算)
- Jump, Branch, Return, Phi(制御)
- Call, BoxCall, ExternCall(呼び出し)
- TypeOp, Safepoint, Barrier(メタ)
- Phase 12.7糖衣構文ドキュメント整理(超圧縮重視、可逆変換保証)
- MIRビルダーのモジュール分割完了
- vtableテストスイート拡充
- AI協調開発ツール追加(並列リファクタリング支援)
詳細:
- src/mir/instruction_introspection.rs: core13_instruction_names()追加
- MIRビルダー分割: decls.rs, exprs_*.rs, fields.rs
- plugin_loader_v2: errors.rs, host_bridge.rs分離
- 論文用データ: mir13-final.md作成
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-04 11:34:15 +09:00
|
|
|
// Lightweight helpers moved from builder.rs to reduce file size
|
|
|
|
|
impl super::MirBuilder {
|
|
|
|
|
/// Ensure a basic block exists in the current function
|
|
|
|
|
pub(crate) fn ensure_block_exists(&mut self, block_id: BasicBlockId) -> Result<(), String> {
|
|
|
|
|
if let Some(ref mut function) = self.current_function {
|
|
|
|
|
if !function.blocks.contains_key(&block_id) {
|
|
|
|
|
let block = BasicBlock::new(block_id);
|
|
|
|
|
function.add_block(block);
|
|
|
|
|
}
|
|
|
|
|
Ok(())
|
|
|
|
|
} else {
|
|
|
|
|
Err("No current function".to_string())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Start a new basic block and set as current
|
|
|
|
|
pub(crate) fn start_new_block(&mut self, block_id: BasicBlockId) -> Result<(), String> {
|
|
|
|
|
if let Some(ref mut function) = self.current_function {
|
|
|
|
|
function.add_block(BasicBlock::new(block_id));
|
|
|
|
|
self.current_block = Some(block_id);
|
|
|
|
|
Ok(())
|
|
|
|
|
} else {
|
|
|
|
|
Err("No current function".to_string())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-09-16 03:54:44 +09:00
|
|
|
|
|
|
|
|
// Call/Type/WeakRef emission helpers (moved from builder.rs)
|
|
|
|
|
impl super::MirBuilder {
|
|
|
|
|
/// Emit a Box method call or plugin call (unified BoxCall)
|
|
|
|
|
pub(super) fn emit_box_or_plugin_call(
|
|
|
|
|
&mut self,
|
|
|
|
|
dst: Option<super::ValueId>,
|
|
|
|
|
box_val: super::ValueId,
|
|
|
|
|
method: String,
|
|
|
|
|
method_id: Option<u16>,
|
|
|
|
|
args: Vec<super::ValueId>,
|
|
|
|
|
effects: super::EffectMask,
|
|
|
|
|
) -> Result<(), String> {
|
2025-09-17 07:43:07 +09:00
|
|
|
self.emit_instruction(super::MirInstruction::BoxCall {
|
|
|
|
|
dst,
|
|
|
|
|
box_val,
|
|
|
|
|
method: method.clone(),
|
|
|
|
|
method_id,
|
|
|
|
|
args,
|
|
|
|
|
effects,
|
|
|
|
|
})?;
|
2025-09-16 03:54:44 +09:00
|
|
|
if let Some(d) = dst {
|
|
|
|
|
let mut recv_box: Option<String> = self.value_origin_newbox.get(&box_val).cloned();
|
|
|
|
|
if recv_box.is_none() {
|
|
|
|
|
if let Some(t) = self.value_types.get(&box_val) {
|
2025-09-17 07:43:07 +09:00
|
|
|
match t {
|
|
|
|
|
super::MirType::String => recv_box = Some("StringBox".to_string()),
|
|
|
|
|
super::MirType::Box(name) => recv_box = Some(name.clone()),
|
|
|
|
|
_ => {}
|
|
|
|
|
}
|
2025-09-16 03:54:44 +09:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if let Some(bt) = recv_box {
|
|
|
|
|
if let Some(mt) = self.plugin_method_sigs.get(&(bt.clone(), method.clone())) {
|
|
|
|
|
self.value_types.insert(d, mt.clone());
|
|
|
|
|
} else {
|
|
|
|
|
let inferred: Option<super::MirType> = match (bt.as_str(), method.as_str()) {
|
2025-09-17 07:43:07 +09:00
|
|
|
("StringBox", "length") | ("StringBox", "len") => {
|
|
|
|
|
Some(super::MirType::Integer)
|
|
|
|
|
}
|
2025-09-16 03:54:44 +09:00
|
|
|
("StringBox", "is_empty") => Some(super::MirType::Bool),
|
|
|
|
|
("StringBox", "charCodeAt") => Some(super::MirType::Integer),
|
2025-09-17 07:43:07 +09:00
|
|
|
("StringBox", "substring")
|
|
|
|
|
| ("StringBox", "concat")
|
|
|
|
|
| ("StringBox", "replace")
|
|
|
|
|
| ("StringBox", "trim")
|
|
|
|
|
| ("StringBox", "toUpper")
|
|
|
|
|
| ("StringBox", "toLower") => Some(super::MirType::String),
|
2025-09-16 03:54:44 +09:00
|
|
|
("ArrayBox", "length") => Some(super::MirType::Integer),
|
|
|
|
|
("MapBox", "size") => Some(super::MirType::Integer),
|
|
|
|
|
("MapBox", "has") => Some(super::MirType::Bool),
|
|
|
|
|
("MapBox", "get") => Some(super::MirType::Box("Any".to_string())),
|
|
|
|
|
_ => None,
|
|
|
|
|
};
|
2025-09-17 07:43:07 +09:00
|
|
|
if let Some(mt) = inferred {
|
|
|
|
|
self.value_types.insert(d, mt);
|
|
|
|
|
}
|
2025-09-16 03:54:44 +09:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[allow(dead_code)]
|
2025-09-17 07:43:07 +09:00
|
|
|
pub(super) fn emit_type_check(
|
|
|
|
|
&mut self,
|
|
|
|
|
value: super::ValueId,
|
|
|
|
|
expected_type: String,
|
|
|
|
|
) -> Result<super::ValueId, String> {
|
2025-09-16 03:54:44 +09:00
|
|
|
let dst = self.value_gen.next();
|
2025-09-17 07:43:07 +09:00
|
|
|
self.emit_instruction(super::MirInstruction::TypeOp {
|
|
|
|
|
dst,
|
|
|
|
|
op: TypeOpKind::Check,
|
|
|
|
|
value,
|
|
|
|
|
ty: super::MirType::Box(expected_type),
|
|
|
|
|
})?;
|
2025-09-16 03:54:44 +09:00
|
|
|
Ok(dst)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[allow(dead_code)]
|
2025-09-17 07:43:07 +09:00
|
|
|
pub(super) fn emit_cast(
|
|
|
|
|
&mut self,
|
|
|
|
|
value: super::ValueId,
|
|
|
|
|
target_type: super::MirType,
|
|
|
|
|
) -> Result<super::ValueId, String> {
|
2025-09-16 03:54:44 +09:00
|
|
|
let dst = self.value_gen.next();
|
2025-09-17 07:43:07 +09:00
|
|
|
self.emit_instruction(super::MirInstruction::TypeOp {
|
|
|
|
|
dst,
|
|
|
|
|
op: TypeOpKind::Cast,
|
|
|
|
|
value,
|
|
|
|
|
ty: target_type.clone(),
|
|
|
|
|
})?;
|
2025-09-16 03:54:44 +09:00
|
|
|
Ok(dst)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[allow(dead_code)]
|
2025-09-17 07:43:07 +09:00
|
|
|
pub(super) fn emit_weak_new(
|
|
|
|
|
&mut self,
|
|
|
|
|
box_val: super::ValueId,
|
|
|
|
|
) -> Result<super::ValueId, String> {
|
|
|
|
|
if crate::config::env::mir_core13_pure() {
|
|
|
|
|
return Ok(box_val);
|
|
|
|
|
}
|
2025-09-16 03:54:44 +09:00
|
|
|
let dst = self.value_gen.next();
|
2025-09-17 07:43:07 +09:00
|
|
|
self.emit_instruction(super::MirInstruction::WeakRef {
|
|
|
|
|
dst,
|
|
|
|
|
op: WeakRefOp::New,
|
|
|
|
|
value: box_val,
|
|
|
|
|
})?;
|
2025-09-16 03:54:44 +09:00
|
|
|
Ok(dst)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[allow(dead_code)]
|
2025-09-17 07:43:07 +09:00
|
|
|
pub(super) fn emit_weak_load(
|
|
|
|
|
&mut self,
|
|
|
|
|
weak_ref: super::ValueId,
|
|
|
|
|
) -> Result<super::ValueId, String> {
|
|
|
|
|
if crate::config::env::mir_core13_pure() {
|
|
|
|
|
return Ok(weak_ref);
|
|
|
|
|
}
|
2025-09-16 03:54:44 +09:00
|
|
|
let dst = self.value_gen.next();
|
2025-09-17 07:43:07 +09:00
|
|
|
self.emit_instruction(super::MirInstruction::WeakRef {
|
|
|
|
|
dst,
|
|
|
|
|
op: WeakRefOp::Load,
|
|
|
|
|
value: weak_ref,
|
|
|
|
|
})?;
|
2025-09-16 03:54:44 +09:00
|
|
|
Ok(dst)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
|
pub(super) fn emit_barrier_read(&mut self, ptr: super::ValueId) -> Result<(), String> {
|
2025-09-17 07:43:07 +09:00
|
|
|
self.emit_instruction(super::MirInstruction::Barrier {
|
|
|
|
|
op: BarrierOp::Read,
|
|
|
|
|
ptr,
|
|
|
|
|
})
|
2025-09-16 03:54:44 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
|
pub(super) fn emit_barrier_write(&mut self, ptr: super::ValueId) -> Result<(), String> {
|
2025-09-17 07:43:07 +09:00
|
|
|
self.emit_instruction(super::MirInstruction::Barrier {
|
|
|
|
|
op: BarrierOp::Write,
|
|
|
|
|
ptr,
|
|
|
|
|
})
|
2025-09-16 03:54:44 +09:00
|
|
|
}
|
|
|
|
|
}
|