wip(joinir): Phase 188-Impl-2 Pattern1Context host variable integration
Work in progress - ValueId mismatch issue needs resolution. Changes: - Add Pattern1Context struct with loop_var and value_allocator - Extract loop variable from condition in cf_loop_pattern1_minimal - Pass host's ValueId to Pattern 1 lowerer Problem discovered: - merge_joinir_mir_blocks() remaps ALL ValueIds - Host's i (ValueId(2)) gets remapped to ValueId(5) - ValueId(5) has no initialization → undefined value error Options under consideration: - Option A: Pinned Values (don't remap host ValueIds) - Option B: Inline Block Generation (no JoinModule) - Option C: Continuation Passing - Option D: SSA Copy Injection 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -375,18 +375,28 @@ impl super::MirBuilder {
|
||||
/// This bypasses the LoopFrontendBinding JSON path and directly calls
|
||||
/// the Pattern 1 minimal lowerer for apps/tests/loop_min_while.hako
|
||||
///
|
||||
/// # Phase 188-Impl-2: Host Variable Integration
|
||||
///
|
||||
/// Extracts the loop variable from the host function (e.g., `i` from `i < 3`)
|
||||
/// and passes it to the Pattern 1 lowerer along with a ValueId allocator.
|
||||
///
|
||||
/// # 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
|
||||
/// 1. Extract loop variable name from condition
|
||||
/// 2. Look up ValueId in host variable_map
|
||||
/// 3. Create Pattern1Context with host variable + allocator
|
||||
/// 4. Call simple_while_minimal::lower_simple_while_minimal() → JoinModule
|
||||
/// 5. convert_join_module_to_mir_with_meta() → MirModule
|
||||
/// 6. Merge MIR blocks into current_function
|
||||
fn cf_loop_pattern1_minimal(
|
||||
&mut self,
|
||||
_condition: &ASTNode,
|
||||
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::lowering::simple_while_minimal::{
|
||||
lower_simple_while_minimal, Pattern1Context,
|
||||
};
|
||||
use crate::mir::join_ir_vm_bridge::convert_join_module_to_mir_with_meta;
|
||||
use crate::mir::BasicBlockId;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
@ -395,6 +405,27 @@ impl super::MirBuilder {
|
||||
eprintln!("[cf_loop/joinir/pattern1] Calling Pattern 1 minimal lowerer");
|
||||
}
|
||||
|
||||
// Phase 188-Impl-2: Extract loop variable from condition
|
||||
// For `i < 3`, extract `i` and look up its ValueId in variable_map
|
||||
let loop_var_name = self.extract_loop_variable_from_condition(condition)?;
|
||||
let loop_var_id = self
|
||||
.variable_map
|
||||
.get(&loop_var_name)
|
||||
.copied()
|
||||
.ok_or_else(|| {
|
||||
format!(
|
||||
"[cf_loop/pattern1] Loop variable '{}' not found in variable_map",
|
||||
loop_var_name
|
||||
)
|
||||
})?;
|
||||
|
||||
if debug {
|
||||
eprintln!(
|
||||
"[cf_loop/joinir/pattern1] Loop variable '{}' → {:?}",
|
||||
loop_var_name, loop_var_id
|
||||
);
|
||||
}
|
||||
|
||||
// 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;
|
||||
@ -411,8 +442,16 @@ impl super::MirBuilder {
|
||||
variable_definitions: BTreeMap::new(),
|
||||
};
|
||||
|
||||
// Call Pattern 1 lowerer
|
||||
let join_module = match lower_simple_while_minimal(scope) {
|
||||
// Phase 188-Impl-2: Create Pattern1Context with host variable + allocator
|
||||
// Clone value_gen to move into closure
|
||||
let mut value_gen_clone = self.value_gen.clone();
|
||||
let ctx = Pattern1Context {
|
||||
loop_var: loop_var_id,
|
||||
value_allocator: Box::new(move || value_gen_clone.next()),
|
||||
};
|
||||
|
||||
// Call Pattern 1 lowerer with host context
|
||||
let join_module = match lower_simple_while_minimal(scope, Some(ctx)) {
|
||||
Some(module) => module,
|
||||
None => {
|
||||
if debug {
|
||||
@ -1174,6 +1213,42 @@ impl super::MirBuilder {
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Phase 188-Impl-2: Extract loop variable name from condition
|
||||
///
|
||||
/// For `i < 3`, extracts `i`.
|
||||
/// For `arr.length() > 0`, extracts `arr`.
|
||||
///
|
||||
/// This is a minimal implementation that handles simple comparison patterns.
|
||||
fn extract_loop_variable_from_condition(&self, condition: &ASTNode) -> Result<String, String> {
|
||||
use crate::ast::BinaryOperator;
|
||||
|
||||
match condition {
|
||||
ASTNode::BinaryOp {
|
||||
operator, left, ..
|
||||
} if matches!(
|
||||
operator,
|
||||
BinaryOperator::Less
|
||||
| BinaryOperator::Greater
|
||||
| BinaryOperator::LessEqual
|
||||
| BinaryOperator::GreaterEqual
|
||||
) =>
|
||||
{
|
||||
// Binary comparison: extract variable from left side
|
||||
match &**left {
|
||||
ASTNode::Variable { name, .. } => Ok(name.clone()),
|
||||
_ => Err(format!(
|
||||
"[cf_loop/pattern1] Cannot extract loop variable from condition: {:?}",
|
||||
condition
|
||||
)),
|
||||
}
|
||||
}
|
||||
_ => Err(format!(
|
||||
"[cf_loop/pattern1] Unsupported loop condition pattern: {:?}",
|
||||
condition
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Control-flow: throw
|
||||
pub(super) fn cf_throw(&mut self, expression: ASTNode) -> Result<ValueId, String> {
|
||||
if self.in_cleanup_block && !self.cleanup_allow_throw {
|
||||
|
||||
Reference in New Issue
Block a user