chore: Phase 25.1 完了 - LoopForm v2/Stage1 CLI/環境変数削減 + Phase 26-D からの変更
Phase 25.1 完了成果: - ✅ LoopForm v2 テスト・ドキュメント・コメント完備 - 4ケース(A/B/C/D)完全テストカバレッジ - 最小再現ケース作成(SSAバグ調査用) - SSOT文書作成(loopform_ssot.md) - 全ソースに [LoopForm] コメントタグ追加 - ✅ Stage-1 CLI デバッグ環境構築 - stage1_cli.hako 実装 - stage1_bridge.rs ブリッジ実装 - デバッグツール作成(stage1_debug.sh/stage1_minimal.sh) - アーキテクチャ改善提案文書 - ✅ 環境変数削減計画策定 - 25変数の完全調査・分類 - 6段階削減ロードマップ(25→5、80%削減) - 即時削除可能変数特定(NYASH_CONFIG/NYASH_DEBUG) Phase 26-D からの累積変更: - PHI実装改善(ExitPhiBuilder/HeaderPhiBuilder等) - MIRビルダーリファクタリング - 型伝播・最適化パス改善 - その他約300ファイルの累積変更 🎯 技術的成果: - SSAバグ根本原因特定(条件分岐内loop変数変更) - Region+next_iパターン適用完了(UsingCollectorBox等) - LoopFormパターン文書化・テスト化完了 - セルフホスティング基盤強化 Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: ChatGPT <noreply@openai.com> Co-Authored-By: Task Assistant <task@anthropic.com>
This commit is contained in:
@ -1,7 +1,7 @@
|
||||
use super::{Effect, EffectMask, MirInstruction, ValueId};
|
||||
use crate::ast::{ASTNode, CallExpr};
|
||||
use crate::mir::TypeOpKind;
|
||||
use crate::mir::utils::is_current_block_terminated;
|
||||
use crate::mir::TypeOpKind;
|
||||
|
||||
impl super::MirBuilder {
|
||||
// Print statement: env.console.log(value) with early TypeOp handling
|
||||
@ -10,15 +10,34 @@ impl super::MirBuilder {
|
||||
// Prefer wrapper for simple function-call pattern (non-breaking refactor)
|
||||
if let Ok(call) = CallExpr::try_from(expression.clone()) {
|
||||
if (call.name == "isType" || call.name == "asType") && call.arguments.len() == 2 {
|
||||
super::utils::builder_debug_log("pattern: print(FunctionCall isType|asType) [via wrapper]");
|
||||
if let Some(type_name) = super::MirBuilder::extract_string_literal(&call.arguments[1]) {
|
||||
super::utils::builder_debug_log(&format!("extract_string_literal OK: {}", type_name));
|
||||
super::utils::builder_debug_log(
|
||||
"pattern: print(FunctionCall isType|asType) [via wrapper]",
|
||||
);
|
||||
if let Some(type_name) =
|
||||
super::MirBuilder::extract_string_literal(&call.arguments[1])
|
||||
{
|
||||
super::utils::builder_debug_log(&format!(
|
||||
"extract_string_literal OK: {}",
|
||||
type_name
|
||||
));
|
||||
let val = self.build_expression(call.arguments[0].clone())?;
|
||||
let ty = super::MirBuilder::parse_type_name_to_mir(&type_name);
|
||||
let dst = self.next_value_id();
|
||||
let op = if call.name == "isType" { TypeOpKind::Check } else { TypeOpKind::Cast };
|
||||
super::utils::builder_debug_log(&format!("emit TypeOp {:?} value={} dst= {}", op, val, dst));
|
||||
self.emit_instruction(MirInstruction::TypeOp { dst, op, value: val, ty })?;
|
||||
let op = if call.name == "isType" {
|
||||
TypeOpKind::Check
|
||||
} else {
|
||||
TypeOpKind::Cast
|
||||
};
|
||||
super::utils::builder_debug_log(&format!(
|
||||
"emit TypeOp {:?} value={} dst= {}",
|
||||
op, val, dst
|
||||
));
|
||||
self.emit_instruction(MirInstruction::TypeOp {
|
||||
dst,
|
||||
op,
|
||||
value: val,
|
||||
ty,
|
||||
})?;
|
||||
self.emit_instruction(MirInstruction::ExternCall {
|
||||
dst: None,
|
||||
iface_name: "env.console".to_string(),
|
||||
@ -129,7 +148,7 @@ impl super::MirBuilder {
|
||||
if use_unified {
|
||||
// New unified path - treat print as global function
|
||||
self.emit_unified_call(
|
||||
None, // print returns nothing
|
||||
None, // print returns nothing
|
||||
super::builder_calls::CallTarget::Global("print".to_string()),
|
||||
vec![value],
|
||||
)?;
|
||||
@ -155,14 +174,24 @@ impl super::MirBuilder {
|
||||
let total = statements.len();
|
||||
eprintln!("[DEBUG/build_block] Processing {} statements", total);
|
||||
for (idx, statement) in statements.into_iter().enumerate() {
|
||||
eprintln!("[DEBUG/build_block] Statement {}/{} current_block={:?} current_function={}",
|
||||
idx+1, total, self.current_block,
|
||||
self.current_function.as_ref().map(|f| f.signature.name.as_str()).unwrap_or("none"));
|
||||
eprintln!(
|
||||
"[DEBUG/build_block] Statement {}/{} current_block={:?} current_function={}",
|
||||
idx + 1,
|
||||
total,
|
||||
self.current_block,
|
||||
self.current_function
|
||||
.as_ref()
|
||||
.map(|f| f.signature.name.as_str())
|
||||
.unwrap_or("none")
|
||||
);
|
||||
last_value = Some(self.build_statement(statement)?);
|
||||
// If the current block was terminated by this statement (e.g., return/throw),
|
||||
// do not emit any further instructions for this block.
|
||||
if is_current_block_terminated(self)? {
|
||||
eprintln!("[DEBUG/build_block] Block terminated after statement {}", idx+1);
|
||||
eprintln!(
|
||||
"[DEBUG/build_block] Block terminated after statement {}",
|
||||
idx + 1
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -190,7 +219,6 @@ impl super::MirBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Local declarations with optional initializers
|
||||
pub(super) fn build_local_statement(
|
||||
&mut self,
|
||||
@ -198,7 +226,11 @@ impl super::MirBuilder {
|
||||
initial_values: Vec<Option<Box<ASTNode>>>,
|
||||
) -> Result<ValueId, String> {
|
||||
if std::env::var("NYASH_LOOPFORM_DEBUG").is_ok() {
|
||||
eprintln!("[build_local_statement] ENTRY: variables={:?}, initial_values.len()={}", variables, initial_values.len());
|
||||
eprintln!(
|
||||
"[build_local_statement] ENTRY: variables={:?}, initial_values.len()={}",
|
||||
variables,
|
||||
initial_values.len()
|
||||
);
|
||||
}
|
||||
let mut last_value = None;
|
||||
for (i, var_name) in variables.iter().enumerate() {
|
||||
@ -212,12 +244,15 @@ impl super::MirBuilder {
|
||||
let var_id = self.next_value_id();
|
||||
|
||||
if std::env::var("NYASH_LOOPFORM_DEBUG").is_ok() {
|
||||
eprintln!("[build_local_statement] '{}': init_val={:?}, allocated var_id={:?}", var_name, init_val, var_id);
|
||||
eprintln!(
|
||||
"[build_local_statement] '{}': init_val={:?}, allocated var_id={:?}",
|
||||
var_name, init_val, var_id
|
||||
);
|
||||
}
|
||||
|
||||
self.emit_instruction(crate::mir::MirInstruction::Copy {
|
||||
dst: var_id,
|
||||
src: init_val
|
||||
src: init_val,
|
||||
})?;
|
||||
|
||||
// Propagate metadata (type/origin) from initializer to variable
|
||||
@ -228,13 +263,19 @@ impl super::MirBuilder {
|
||||
// Create a concrete register for uninitialized locals (Void)
|
||||
let void_id = crate::mir::builder::emission::constant::emit_void(self);
|
||||
if std::env::var("NYASH_LOOPFORM_DEBUG").is_ok() {
|
||||
eprintln!("[build_local_statement] '{}': uninitialized, void_id={:?}", var_name, void_id);
|
||||
eprintln!(
|
||||
"[build_local_statement] '{}': uninitialized, void_id={:?}",
|
||||
var_name, void_id
|
||||
);
|
||||
}
|
||||
void_id
|
||||
};
|
||||
|
||||
if std::env::var("NYASH_LOOPFORM_DEBUG").is_ok() {
|
||||
eprintln!("[build_local_statement] Inserting '{}' -> {:?} into variable_map", var_name, var_id);
|
||||
eprintln!(
|
||||
"[build_local_statement] Inserting '{}' -> {:?} into variable_map",
|
||||
var_name, var_id
|
||||
);
|
||||
}
|
||||
self.variable_map.insert(var_name.clone(), var_id);
|
||||
// SlotRegistry にもローカル変数スロットを登録しておくよ(観測専用)
|
||||
@ -267,7 +308,10 @@ impl super::MirBuilder {
|
||||
// Defer: copy into slot and jump to target
|
||||
if let (Some(slot), Some(target)) = (self.return_defer_slot, self.return_defer_target) {
|
||||
self.return_deferred_emitted = true;
|
||||
self.emit_instruction(MirInstruction::Copy { dst: slot, src: return_value })?;
|
||||
self.emit_instruction(MirInstruction::Copy {
|
||||
dst: slot,
|
||||
src: return_value,
|
||||
})?;
|
||||
crate::mir::builder::metadata::propagate::propagate(self, return_value, slot);
|
||||
if !self.is_current_block_terminated() {
|
||||
crate::mir::builder::emission::branch::emit_jump(self, target)?;
|
||||
@ -275,12 +319,16 @@ impl super::MirBuilder {
|
||||
Ok(return_value)
|
||||
} else {
|
||||
// Fallback: no configured slot/target; emit a real return
|
||||
self.emit_instruction(MirInstruction::Return { value: Some(return_value) })?;
|
||||
self.emit_instruction(MirInstruction::Return {
|
||||
value: Some(return_value),
|
||||
})?;
|
||||
Ok(return_value)
|
||||
}
|
||||
} else {
|
||||
// Normal return
|
||||
self.emit_instruction(MirInstruction::Return { value: Some(return_value) })?;
|
||||
self.emit_instruction(MirInstruction::Return {
|
||||
value: Some(return_value),
|
||||
})?;
|
||||
Ok(return_value)
|
||||
}
|
||||
}
|
||||
@ -299,7 +347,8 @@ impl super::MirBuilder {
|
||||
} = expression.clone()
|
||||
{
|
||||
let recv_val = self.build_expression(*object)?;
|
||||
let mname_id = crate::mir::builder::emission::constant::emit_string(self, method.clone());
|
||||
let mname_id =
|
||||
crate::mir::builder::emission::constant::emit_string(self, method.clone());
|
||||
let mut arg_vals: Vec<ValueId> = Vec::with_capacity(2 + arguments.len());
|
||||
arg_vals.push(recv_val);
|
||||
arg_vals.push(mname_id);
|
||||
|
||||
Reference in New Issue
Block a user