feat(joinir): Phase 188 Print instruction + Router integration
- Add MirLikeInst::Print variant for direct output operations - Implement Print instruction in JSON serialization - Update simple_while_minimal.rs to use Print instead of BoxCall - Add Print handling in JoinIR VM bridge and runner - Add router logic to call Pattern 1 lowerer from main pipeline Note: Router integration exposes ValueId mismatch issue between Pattern 1's hardcoded IDs and host function's variables. This architectural issue needs resolution in next phase. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -173,11 +173,18 @@ impl super::MirBuilder {
|
||||
use crate::mir::types::ConstValue;
|
||||
use crate::r#macro::ast_json::ast_to_json;
|
||||
|
||||
// Phase 188-Impl-1-F: Route "main" through Pattern 1 minimal lowerer
|
||||
if func_name == "main" {
|
||||
if debug {
|
||||
eprintln!("[cf_loop/joinir] Routing 'main' through Pattern 1 minimal lowerer");
|
||||
}
|
||||
return self.cf_loop_pattern1_minimal(condition, body, func_name, debug);
|
||||
}
|
||||
|
||||
// Phase 50: Create appropriate binding based on function name
|
||||
let binding = match func_name {
|
||||
"JsonTokenizer.print_tokens/0" => LoopFrontendBinding::for_print_tokens(),
|
||||
"ArrayExtBox.filter/2" => LoopFrontendBinding::for_array_filter(),
|
||||
"main" => LoopFrontendBinding::for_main_simple_while(), // Phase 188-Impl-1
|
||||
_ => {
|
||||
if debug {
|
||||
eprintln!(
|
||||
@ -363,6 +370,103 @@ impl super::MirBuilder {
|
||||
Ok(Some(void_val))
|
||||
}
|
||||
|
||||
/// Phase 188-Impl-1-F: Pattern 1 (Simple While Loop) minimal lowerer
|
||||
///
|
||||
/// This bypasses the LoopFrontendBinding JSON path and directly calls
|
||||
/// the Pattern 1 minimal lowerer for apps/tests/loop_min_while.hako
|
||||
///
|
||||
/// # Pipeline
|
||||
/// 1. Call simple_while_minimal::lower_simple_while_minimal() → JoinModule
|
||||
/// 2. convert_join_module_to_mir_with_meta() → MirModule
|
||||
/// 3. Merge MIR blocks into current_function
|
||||
fn cf_loop_pattern1_minimal(
|
||||
&mut self,
|
||||
_condition: &ASTNode,
|
||||
_body: &[ASTNode],
|
||||
_func_name: &str,
|
||||
debug: bool,
|
||||
) -> Result<Option<ValueId>, String> {
|
||||
use crate::mir::join_ir::lowering::simple_while_minimal::lower_simple_while_minimal;
|
||||
use crate::mir::join_ir_vm_bridge::convert_join_module_to_mir_with_meta;
|
||||
use crate::mir::BasicBlockId;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
|
||||
if debug {
|
||||
eprintln!("[cf_loop/joinir/pattern1] Calling Pattern 1 minimal lowerer");
|
||||
}
|
||||
|
||||
// Create a minimal LoopScopeShape (Phase 188: hardcoded for loop_min_while.hako)
|
||||
// Pattern 1 lowerer ignores the scope anyway, so this is just a placeholder
|
||||
use crate::mir::join_ir::lowering::loop_scope_shape::LoopScopeShape;
|
||||
let scope = LoopScopeShape {
|
||||
header: BasicBlockId(0),
|
||||
body: BasicBlockId(0),
|
||||
latch: BasicBlockId(0),
|
||||
exit: BasicBlockId(0),
|
||||
pinned: BTreeSet::new(),
|
||||
carriers: BTreeSet::new(),
|
||||
body_locals: BTreeSet::new(),
|
||||
exit_live: BTreeSet::new(),
|
||||
progress_carrier: None,
|
||||
variable_definitions: BTreeMap::new(),
|
||||
};
|
||||
|
||||
// Call Pattern 1 lowerer
|
||||
let join_module = match lower_simple_while_minimal(scope) {
|
||||
Some(module) => module,
|
||||
None => {
|
||||
if debug {
|
||||
eprintln!("[cf_loop/joinir/pattern1] Pattern 1 lowerer returned None");
|
||||
}
|
||||
return Ok(None);
|
||||
}
|
||||
};
|
||||
|
||||
if debug {
|
||||
eprintln!(
|
||||
"[cf_loop/joinir/pattern1] JoinModule generated with {} functions",
|
||||
join_module.functions.len()
|
||||
);
|
||||
}
|
||||
|
||||
// Convert JoinModule to MirModule
|
||||
// Phase 188: Pass empty meta map since Pattern 1 lowerer doesn't use metadata
|
||||
use crate::mir::join_ir::frontend::JoinFuncMetaMap;
|
||||
let empty_meta: JoinFuncMetaMap = BTreeMap::new();
|
||||
|
||||
let mir_module = convert_join_module_to_mir_with_meta(&join_module, &empty_meta)
|
||||
.map_err(|e| format!("[cf_loop/joinir/pattern1] MIR conversion failed: {:?}", e))?;
|
||||
|
||||
if debug {
|
||||
eprintln!(
|
||||
"[cf_loop/joinir/pattern1] MirModule generated with {} functions",
|
||||
mir_module.functions.len()
|
||||
);
|
||||
}
|
||||
|
||||
// Merge JoinIR blocks into current function
|
||||
self.merge_joinir_mir_blocks(&mir_module, debug)?;
|
||||
|
||||
// Return void/0 as loop result (Pattern 1 loops return 0)
|
||||
// Use the current block to emit the constant
|
||||
let zero_val = self.value_gen.next();
|
||||
use crate::mir::types::ConstValue;
|
||||
let current_block = self.current_block.ok_or_else(|| {
|
||||
"[cf_loop/joinir/pattern1] No current block available".to_string()
|
||||
})?;
|
||||
|
||||
if let Some(ref mut func) = self.current_function {
|
||||
if let Some(block) = func.get_block_mut(current_block) {
|
||||
block.instructions.push(crate::mir::MirInstruction::Const {
|
||||
dst: zero_val,
|
||||
value: ConstValue::Integer(0),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Some(zero_val))
|
||||
}
|
||||
|
||||
/// Phase 49-3.2: Merge JoinIR-generated MIR blocks into current_function
|
||||
///
|
||||
/// # Phase 189: Multi-Function MIR Merge
|
||||
|
||||
Reference in New Issue
Block a user