fix(stage-b): Add sh_core using + Stage-1 JSON support

## Fixed Issues

1. compiler_stageb.hako: Added 'using sh_core as StringHelpers'
   - Resolved: call unresolved ParserStringUtilsBox.skip_ws/2
   - Root cause: using chain resolution not implemented
   - Workaround: explicit using in parent file

2. stageb_helpers.sh: Accept Stage-1 JSON format
   - Modified awk pattern to accept both formats:
     - MIR JSON v0: "version":0, "kind":"Program"
     - Stage-1 JSON: "type":"Program"

## Remaining Issues

ParserBox VM crash: Invalid value: use of undefined value ValueId(5839)
- Cause: Complex nested loops in parse_program2()
- Workaround: Minimal Stage-B (without ParserBox) works
- Fallback: Rust compiler path available

## Verification

 Minimal Stage-B outputs JSON correctly
 ParserBox execution crashes VM (SSA bug)

Co-Authored-By: Task先生 (AI Agent)
This commit is contained in:
nyash-codex
2025-11-02 08:23:43 +09:00
parent 91f3d82deb
commit 3aa0c3c875
15 changed files with 326 additions and 119 deletions

View File

@ -311,10 +311,16 @@ impl<'a> LoopBuilder<'a> {
let count = CALL_COUNT.fetch_add(1, Ordering::SeqCst);
let current_vars = self.get_current_variable_map();
// Debug: print current_vars before prepare
eprintln!("[DEBUG] prepare_loop_variables call #{}", count);
eprintln!("[DEBUG] current_vars = {:?}", current_vars);
eprintln!("[DEBUG] preheader_id = {:?}, header_id = {:?}", preheader_id, header_id);
// Debug: print current_vars before prepare (guarded by env)
let dbg = std::env::var("NYASH_BUILDER_DEBUG").ok().as_deref() == Some("1");
if dbg {
eprintln!("[DEBUG] prepare_loop_variables call #{}", count);
eprintln!("[DEBUG] current_vars = {:?}", current_vars);
eprintln!(
"[DEBUG] preheader_id = {:?}, header_id = {:?}",
preheader_id, header_id
);
}
crate::mir::phi_core::loop_phi::save_block_snapshot(
&mut self.block_var_maps,
preheader_id,
@ -417,34 +423,66 @@ impl<'a> LoopBuilder<'a> {
dst: ValueId,
inputs: Vec<(BasicBlockId, ValueId)>,
) -> Result<(), String> {
eprintln!("[DEBUG] LoopBuilder::emit_phi_at_block_start: block={}, dst=%{}, inputs={:?}", block_id, dst.0, inputs);
let dbg = std::env::var("NYASH_BUILDER_DEBUG").ok().as_deref() == Some("1");
if dbg {
eprintln!(
"[DEBUG] LoopBuilder::emit_phi_at_block_start: block={}, dst=%{}, inputs={:?}",
block_id, dst.0, inputs
);
}
// Phi nodeをブロックの先頭に挿入
if let Some(ref mut function) = self.parent_builder.current_function {
if let Some(block) = function.get_block_mut(block_id) {
eprintln!("[DEBUG] Block {} current instructions count: {}", block_id, block.instructions.len());
if dbg {
eprintln!(
"[DEBUG] Block {} current instructions count: {}",
block_id,
block.instructions.len()
);
}
// Phi命令は必ずブロックの先頭に配置
let phi_inst = MirInstruction::Phi { dst, inputs: inputs.clone() };
block.instructions.insert(0, phi_inst);
eprintln!("[DEBUG] ✅ PHI instruction inserted at position 0");
eprintln!("[DEBUG] Block {} after insert instructions count: {}", block_id, block.instructions.len());
if dbg {
eprintln!("[DEBUG] ✅ PHI instruction inserted at position 0");
eprintln!(
"[DEBUG] Block {} after insert instructions count: {}",
block_id,
block.instructions.len()
);
}
// Verify PHI is still there
if let Some(first_inst) = block.instructions.get(0) {
match first_inst {
MirInstruction::Phi { dst: phi_dst, .. } => {
eprintln!("[DEBUG] Verified: First instruction is PHI dst=%{}", phi_dst.0);
if dbg {
eprintln!(
"[DEBUG] Verified: First instruction is PHI dst=%{}",
phi_dst.0
);
}
}
other => {
eprintln!("[DEBUG] ⚠️ WARNING: First instruction is NOT PHI! It's {:?}", other);
if dbg {
eprintln!(
"[DEBUG] ⚠️ WARNING: First instruction is NOT PHI! It's {:?}",
other
);
}
}
}
}
Ok(())
} else {
eprintln!("[DEBUG] ❌ Block {} not found!", block_id);
if dbg {
eprintln!("[DEBUG] ❌ Block {} not found!", block_id);
}
Err(format!("Block {} not found", block_id))
}
} else {
eprintln!("[DEBUG] ❌ No current function!");
if dbg {
eprintln!("[DEBUG] ❌ No current function!");
}
Err("No current function".to_string())
}
}
@ -490,7 +528,12 @@ impl<'a> LoopBuilder<'a> {
}
fn update_variable(&mut self, name: String, value: ValueId) {
eprintln!("[DEBUG] LoopBuilder::update_variable: name={}, value=%{}", name, value.0);
if std::env::var("NYASH_BUILDER_DEBUG").ok().as_deref() == Some("1") {
eprintln!(
"[DEBUG] LoopBuilder::update_variable: name={}, value=%{}",
name, value.0
);
}
self.parent_builder.variable_map.insert(name, value);
}
@ -749,18 +792,30 @@ impl crate::mir::phi_core::loop_phi::LoopPhiOps for LoopBuilder<'_> {
dst: ValueId,
src: ValueId,
) -> Result<(), String> {
eprintln!("[DEBUG] emit_copy_at_preheader: preheader={}, dst=%{}, src=%{}", preheader_id, dst.0, src.0);
let dbg = std::env::var("NYASH_BUILDER_DEBUG").ok().as_deref() == Some("1");
if dbg {
eprintln!(
"[DEBUG] emit_copy_at_preheader: preheader={}, dst=%{}, src=%{}",
preheader_id, dst.0, src.0
);
}
if let Some(ref mut function) = self.parent_builder.current_function {
if let Some(block) = function.get_block_mut(preheader_id) {
eprintln!("[DEBUG] Adding Copy instruction to block {}", preheader_id);
if dbg {
eprintln!("[DEBUG] Adding Copy instruction to block {}", preheader_id);
}
block.add_instruction(MirInstruction::Copy { dst, src });
Ok(())
} else {
eprintln!("[DEBUG] ❌ Preheader block {} not found!", preheader_id);
if dbg {
eprintln!("[DEBUG] ❌ Preheader block {} not found!", preheader_id);
}
Err(format!("Preheader block {} not found", preheader_id))
}
} else {
eprintln!("[DEBUG] ❌ No current function!");
if dbg {
eprintln!("[DEBUG] ❌ No current function!");
}
Err("No current function".to_string())
}
}