feat(joinir): Phase 240-EX - Pattern2 header condition ExprLowerer integration
Implementation: - Add make_pattern2_scope_manager() helper for DRY - Header conditions use ExprLowerer for supported patterns - Legacy fallback for unsupported patterns - Fail-Fast on supported patterns that fail Tests: - 4 new tests (all pass) - test_expr_lowerer_supports_simple_header_condition_i_less_literal - test_expr_lowerer_supports_header_condition_var_less_var - test_expr_lowerer_header_condition_generates_expected_instructions - test_pattern2_header_condition_via_exprlowerer Also: Archive old phase documentation (34k lines removed) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -268,7 +268,8 @@ impl<'env, 'builder, S: ScopeManager> ExprLowerer<'env, 'builder, S> {
|
||||
/// Check if an AST node is supported in condition context
|
||||
///
|
||||
/// Phase 231: Conservative whitelist. We only support patterns we know work.
|
||||
fn is_supported_condition(ast: &ASTNode) -> bool {
|
||||
/// Phase 240-EX: Made public to allow callers to check before attempting lowering.
|
||||
pub fn is_supported_condition(ast: &ASTNode) -> bool {
|
||||
match ast {
|
||||
// Literals: Integer, Bool
|
||||
ASTNode::Literal { .. } => true,
|
||||
@ -727,4 +728,69 @@ mod tests {
|
||||
"MethodCall should fail-fast with UnsupportedNode"
|
||||
);
|
||||
}
|
||||
|
||||
// Phase 240-EX: Header condition patterns
|
||||
|
||||
#[test]
|
||||
fn test_expr_lowerer_supports_simple_header_condition_i_less_literal() {
|
||||
// header pattern: i < 10
|
||||
let ast = bin(BinaryOperator::Less, var("i"), lit_i(10));
|
||||
assert!(
|
||||
ExprLowerer::<Pattern2ScopeManager>::is_supported_condition(&ast),
|
||||
"i < 10 should be supported for Pattern2 header condition"
|
||||
);
|
||||
|
||||
// lower and verify success
|
||||
let scope = make_basic_scope();
|
||||
let mut builder = create_test_builder();
|
||||
let mut lowerer = ExprLowerer::new(&scope, ExprContext::Condition, &mut builder);
|
||||
|
||||
let result = lowerer.lower(&ast);
|
||||
assert!(result.is_ok(), "i < 10 should lower successfully");
|
||||
|
||||
// Compare instruction should be present
|
||||
let instructions = lowerer.take_last_instructions();
|
||||
assert_has_compare(&instructions);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_expr_lowerer_supports_header_condition_var_less_var() {
|
||||
// header pattern: i < n (variable vs variable)
|
||||
let ast = bin(BinaryOperator::Less, var("i"), var("j"));
|
||||
assert!(
|
||||
ExprLowerer::<Pattern2ScopeManager>::is_supported_condition(&ast),
|
||||
"i < n should be supported for Pattern2 header condition"
|
||||
);
|
||||
|
||||
// lower and verify success
|
||||
let scope = make_basic_scope();
|
||||
let mut builder = create_test_builder();
|
||||
let mut lowerer = ExprLowerer::new(&scope, ExprContext::Condition, &mut builder);
|
||||
|
||||
let result = lowerer.lower(&ast);
|
||||
assert!(result.is_ok(), "i < n should lower successfully");
|
||||
|
||||
// Compare instruction should be present
|
||||
let instructions = lowerer.take_last_instructions();
|
||||
assert_has_compare(&instructions);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_expr_lowerer_header_condition_generates_expected_instructions() {
|
||||
// Test that header condition i < 10 generates proper Compare instruction
|
||||
let scope = make_basic_scope();
|
||||
let mut builder = create_test_builder();
|
||||
|
||||
let ast = bin(BinaryOperator::Less, var("i"), lit_i(10));
|
||||
let mut lowerer = ExprLowerer::new(&scope, ExprContext::Condition, &mut builder);
|
||||
|
||||
let result = lowerer.lower(&ast);
|
||||
assert!(result.is_ok());
|
||||
|
||||
let instructions = lowerer.take_last_instructions();
|
||||
assert!(!instructions.is_empty(), "Should generate instructions");
|
||||
|
||||
// Should have Compare instruction
|
||||
assert_has_compare(&instructions);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user