feat(mir): Phase 25.1f完了 - Conservative PHI + ControlForm観測レイヤー
🎉 Conservative PHI Box理論による完全SSA構築 **Phase 7-B: Conservative PHI実装** - 片方branchのみ定義変数に対応(emit_void使用) - 全変数にPHI生成(Conservative Box理論) - Stage-1 resolver全テスト緑化(3/3 PASS) **Phase 25.1f: ControlForm観測レイヤー** - LoopShape/IfShape/ControlForm構造定義 - Loop/If統一インターフェース実装 - debug_dump/debug_validate機能追加 - NYASH_CONTROL_FORM_TRACE環境変数対応 **主な変更**: - src/mir/builder/phi.rs: Conservative PHI実装 - src/mir/control_form.rs: ControlForm構造(NEW) - src/mir/loop_builder.rs: LoopForm v2デフォルト化 **テスト結果**: ✅ mir_stage1_using_resolver_min_fragment_verifies ✅ mir_stage1_using_resolver_full_collect_entries_verifies ✅ mir_parserbox_parse_program2_harness_parses_minimal_source 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: ChatGPT <chatgpt@openai.com>
This commit is contained in:
@ -36,9 +36,6 @@ impl MirInterpreter {
|
||||
let saved_fn = self.cur_fn.clone();
|
||||
self.cur_fn = Some(func.signature.name.clone());
|
||||
|
||||
// Check if this is a static box method call
|
||||
let static_box_name = self.is_static_box_method(&func.signature.name);
|
||||
|
||||
match arg_vals {
|
||||
Some(args) => {
|
||||
// Regular parameter binding: params and args are 1:1
|
||||
|
||||
@ -278,6 +278,7 @@ impl MirInterpreter {
|
||||
}
|
||||
|
||||
// moved: try_handle_map_box → handlers/boxes_map.rs
|
||||
#[allow(dead_code)]
|
||||
fn try_handle_map_box(
|
||||
&mut self,
|
||||
dst: Option<ValueId>,
|
||||
@ -289,6 +290,7 @@ impl MirInterpreter {
|
||||
}
|
||||
|
||||
// moved: try_handle_string_box → handlers/boxes_string.rs
|
||||
#[allow(dead_code)]
|
||||
fn try_handle_string_box(
|
||||
&mut self,
|
||||
dst: Option<ValueId>,
|
||||
@ -300,6 +302,7 @@ impl MirInterpreter {
|
||||
}
|
||||
|
||||
// moved: try_handle_array_box → handlers/boxes_array.rs
|
||||
#[allow(dead_code)]
|
||||
fn try_handle_array_box(
|
||||
&mut self,
|
||||
dst: Option<ValueId>,
|
||||
|
||||
@ -102,7 +102,7 @@ pub(super) fn try_handle_instance_box(
|
||||
} else {
|
||||
// Conservative fallback: search unique function by name tail ".method/arity"
|
||||
let tail = format!(".{}{}", method, format!("/{}", args.len()));
|
||||
let mut cands: Vec<String> = this
|
||||
let cands: Vec<String> = this
|
||||
.functions
|
||||
.keys()
|
||||
.filter(|k| k.ends_with(&tail))
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
use super::*;
|
||||
use crate::box_trait::NyashBox;
|
||||
|
||||
pub(super) fn try_handle_object_fields(
|
||||
this: &mut MirInterpreter,
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
use super::*;
|
||||
use crate::box_trait::NyashBox;
|
||||
|
||||
pub(super) fn try_handle_string_box(
|
||||
this: &mut MirInterpreter,
|
||||
|
||||
@ -3,6 +3,7 @@ use serde_json::Value as JsonValue;
|
||||
|
||||
impl MirInterpreter {
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
fn ensure_mir_json_version_field(s: &str) -> String {
|
||||
match serde_json::from_str::<JsonValue>(s) {
|
||||
Ok(mut v) => {
|
||||
@ -28,6 +29,12 @@ impl MirInterpreter {
|
||||
let mbase = super::super::utils::normalize_arity_suffix(method);
|
||||
match (iface, mbase) {
|
||||
("env", "get") => {
|
||||
// Prefer provider-based resolution when available, fall back to process env.
|
||||
if let Some(provider_res) = self.extern_provider_dispatch("env.get", args) {
|
||||
let result = provider_res?;
|
||||
self.write_result(dst, result);
|
||||
return Ok(());
|
||||
}
|
||||
if let Some(a0) = args.get(0) {
|
||||
let key = self.reg_load(*a0)?.to_string();
|
||||
let val = std::env::var(&key).ok();
|
||||
@ -135,14 +142,6 @@ impl MirInterpreter {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
("env", "get") => {
|
||||
// Delegate to provider
|
||||
let ret = self
|
||||
.extern_provider_dispatch("env.get", args)
|
||||
.unwrap_or(Ok(VMValue::Void))?;
|
||||
self.write_result(dst, ret);
|
||||
Ok(())
|
||||
}
|
||||
("env", "set") => {
|
||||
// Delegate to provider
|
||||
let ret = self
|
||||
|
||||
@ -110,6 +110,7 @@ impl MirInterpreter {
|
||||
|
||||
/// Check if a function name represents a static box method
|
||||
/// Format: "BoxName.method/Arity"
|
||||
#[allow(dead_code)]
|
||||
fn is_static_box_method(&self, func_name: &str) -> Option<String> {
|
||||
if let Some((box_name, _rest)) = func_name.split_once('.') {
|
||||
if self.static_box_decls.contains_key(box_name) {
|
||||
|
||||
@ -44,6 +44,7 @@ impl MirInterpreter {
|
||||
/// # Returns
|
||||
/// 引数数が範囲内の場合はOk(())、そうでない場合はエラー
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn validate_args_range(
|
||||
&self,
|
||||
method: &str,
|
||||
@ -71,6 +72,7 @@ impl MirInterpreter {
|
||||
/// # Returns
|
||||
/// 引数数が最小値以上の場合はOk(())、そうでない場合はエラー
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn validate_args_min(
|
||||
&self,
|
||||
method: &str,
|
||||
|
||||
@ -42,6 +42,7 @@ impl MirInterpreter {
|
||||
/// # Errors
|
||||
/// * 値が整数でない場合はエラー
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn load_as_int(&mut self, vid: ValueId) -> Result<i64, VMError> {
|
||||
match self.reg_load(vid)? {
|
||||
VMValue::Integer(i) => Ok(i),
|
||||
@ -71,6 +72,7 @@ impl MirInterpreter {
|
||||
/// # Errors
|
||||
/// * 値がboolでない場合はエラー
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn load_as_bool(&mut self, vid: ValueId) -> Result<bool, VMError> {
|
||||
match self.reg_load(vid)? {
|
||||
VMValue::Bool(b) => Ok(b),
|
||||
@ -112,6 +114,7 @@ impl MirInterpreter {
|
||||
/// # Returns
|
||||
/// * `Result<Vec<VMValue>, VMError>` - 読み込んだVMValueのVec
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn load_args_as_values(
|
||||
&mut self,
|
||||
vids: &[ValueId],
|
||||
|
||||
@ -13,6 +13,7 @@ impl MirInterpreter {
|
||||
/// * `dst` - 書き込み先のValueId (Noneの場合は何もしない)
|
||||
/// * `result` - 書き込むBox
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn write_box_result(
|
||||
&mut self,
|
||||
dst: Option<ValueId>,
|
||||
|
||||
@ -40,6 +40,7 @@ impl ErrorBuilder {
|
||||
/// // => "get expects Integer type, got String"
|
||||
/// ```
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
pub fn type_mismatch(method: &str, expected: &str, actual: &str) -> VMError {
|
||||
VMError::InvalidInstruction(format!("{} expects {} type, got {}", method, expected, actual))
|
||||
}
|
||||
@ -57,6 +58,7 @@ impl ErrorBuilder {
|
||||
/// // => "get index out of bounds: 5 >= 3"
|
||||
/// ```
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
pub fn out_of_bounds(method: &str, index: usize, len: usize) -> VMError {
|
||||
VMError::InvalidInstruction(format!("{} index out of bounds: {} >= {}", method, index, len))
|
||||
}
|
||||
@ -93,6 +95,7 @@ impl ErrorBuilder {
|
||||
/// // => "receiver must be ArrayBox"
|
||||
/// ```
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
pub fn receiver_type_error(expected: &str) -> VMError {
|
||||
VMError::InvalidInstruction(format!("receiver must be {}", expected))
|
||||
}
|
||||
@ -123,6 +126,7 @@ impl ErrorBuilder {
|
||||
/// // => "link_object expects at least 1 arg, got 0"
|
||||
/// ```
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
pub fn arg_count_min(method: &str, min: usize, actual: usize) -> VMError {
|
||||
VMError::InvalidInstruction(format!(
|
||||
"{} expects at least {} arg{}, got {}",
|
||||
@ -153,6 +157,7 @@ impl ErrorBuilder {
|
||||
/// // => "link_object: <error message>"
|
||||
/// ```
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
pub fn from_error(operation: &str, error: &dyn std::error::Error) -> VMError {
|
||||
VMError::InvalidInstruction(format!("{}: {}", operation, error))
|
||||
}
|
||||
@ -178,6 +183,7 @@ impl super::super::MirInterpreter {
|
||||
/// return Err(self.err_type_mismatch("get", "Integer", actual_type));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn err_type_mismatch(&self, method: &str, expected: &str, actual: &str) -> VMError {
|
||||
ErrorBuilder::type_mismatch(method, expected, actual)
|
||||
}
|
||||
@ -189,6 +195,7 @@ impl super::super::MirInterpreter {
|
||||
/// return Err(self.err_out_of_bounds("get", idx, len));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn err_out_of_bounds(&self, method: &str, index: usize, len: usize) -> VMError {
|
||||
ErrorBuilder::out_of_bounds(method, index, len)
|
||||
}
|
||||
|
||||
@ -15,6 +15,7 @@ impl MirInterpreter {
|
||||
/// # Returns
|
||||
/// 変換成功時はBox、失敗時はエラー
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn convert_to_box(
|
||||
&mut self,
|
||||
receiver: ValueId,
|
||||
|
||||
Reference in New Issue
Block a user