Phase 33 NORM canon test: enforce normalized dev route for P1/P2/JP mini
This commit is contained in:
@ -43,6 +43,56 @@ mod tests;
|
||||
pub(crate) use context::ExtractCtx;
|
||||
pub(crate) use stmt_handlers::StatementEffect;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum FunctionRoute {
|
||||
IfReturn,
|
||||
LoopFrontend,
|
||||
NestedIf,
|
||||
ReadQuoted,
|
||||
}
|
||||
|
||||
fn resolve_function_route(func_name: &str) -> Result<FunctionRoute, String> {
|
||||
const IF_RETURN_NAMES: &[&str] = &["test", "local", "_read_value_from_pair"];
|
||||
const LOOP_NAMES: &[&str] = &["simple", "filter", "print_tokens", "map", "reduce", "fold", "jsonparser_skip_ws_mini"];
|
||||
|
||||
if IF_RETURN_NAMES.contains(&func_name) {
|
||||
return Ok(FunctionRoute::IfReturn);
|
||||
}
|
||||
|
||||
if LOOP_NAMES.contains(&func_name) {
|
||||
return Ok(FunctionRoute::LoopFrontend);
|
||||
}
|
||||
|
||||
if func_name == "parse_loop" {
|
||||
if crate::config::env::joinir_dev_enabled()
|
||||
&& std::env::var("HAKO_JOINIR_NESTED_IF").ok().as_deref() == Some("1")
|
||||
{
|
||||
return Ok(FunctionRoute::NestedIf);
|
||||
}
|
||||
return Err(
|
||||
"[joinir/frontend] 'parse_loop' requires HAKO_JOINIR_NESTED_IF=1 (dev only)"
|
||||
.to_string(),
|
||||
);
|
||||
}
|
||||
|
||||
if func_name == "read_quoted_from" {
|
||||
if crate::config::env::joinir_dev_enabled()
|
||||
&& std::env::var("HAKO_JOINIR_READ_QUOTED").ok().as_deref() == Some("1")
|
||||
{
|
||||
return Ok(FunctionRoute::ReadQuoted);
|
||||
}
|
||||
return Err(
|
||||
"[joinir/frontend] 'read_quoted_from' requires HAKO_JOINIR_READ_QUOTED=1 (dev only)"
|
||||
.to_string(),
|
||||
);
|
||||
}
|
||||
|
||||
Err(format!(
|
||||
"[joinir/frontend] unsupported function '{}' (dev fixture not registered)",
|
||||
func_name
|
||||
))
|
||||
}
|
||||
|
||||
/// AST/CFG → JoinIR 変換器
|
||||
///
|
||||
/// Phase 34-2: Program(JSON v0) から tiny IfSelect ケースを JoinIR に変換
|
||||
@ -85,51 +135,17 @@ impl AstToJoinIrLowerer {
|
||||
.as_str()
|
||||
.expect("Function must have 'name'");
|
||||
|
||||
// 3. 関数名で分岐(Phase P3: LoopFrontendBinding 層導入)
|
||||
//
|
||||
// パターン分類:
|
||||
// - If Return pattern: test/local/_read_value_from_pair
|
||||
// - Loop pattern: simple 等 → LoopFrontendBinding 経由
|
||||
// - NestedIfMerge pattern: parse_loop (dev flag gated)
|
||||
// - ReadQuoted pattern: read_quoted_from (dev flag gated)
|
||||
match func_name {
|
||||
"test" | "local" | "_read_value_from_pair" => {
|
||||
self.lower_if_return_pattern(program_json)
|
||||
}
|
||||
"simple" | "filter" | "print_tokens" | "map" | "reduce" | "fold" => {
|
||||
// Phase P3: LoopFrontendBinding 層経由でディスパッチ
|
||||
loop_frontend_binding::lower_loop_by_function_name(self, program_json)
|
||||
}
|
||||
"parse_loop" => {
|
||||
// Phase 41-4: NestedIfMerge pattern (dev flag gated)
|
||||
// Guard: JoinIR dev + HAKO_JOINIR_NESTED_IF=1 を要求
|
||||
if crate::config::env::joinir_dev_enabled()
|
||||
&& std::env::var("HAKO_JOINIR_NESTED_IF").ok().as_deref() == Some("1")
|
||||
{
|
||||
self.lower_nested_if_pattern(program_json)
|
||||
} else {
|
||||
// Dev flag が OFF の場合は panic(旧ルートにフォールバックするため)
|
||||
panic!(
|
||||
"parse_loop NestedIfMerge requires HAKO_JOINIR_NESTED_IF=1. \
|
||||
Set env var to enable Phase 41-4 route."
|
||||
);
|
||||
}
|
||||
}
|
||||
"read_quoted_from" => {
|
||||
// Phase 45: read_quoted_from pattern (dev flag gated)
|
||||
// Guard if + Loop with break + accumulator
|
||||
if crate::config::env::joinir_dev_enabled()
|
||||
&& std::env::var("HAKO_JOINIR_READ_QUOTED").ok().as_deref() == Some("1")
|
||||
{
|
||||
self.lower_read_quoted_pattern(program_json)
|
||||
} else {
|
||||
panic!(
|
||||
"read_quoted_from JoinIR requires HAKO_JOINIR_READ_QUOTED=1. \
|
||||
Set env var to enable Phase 45 route."
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => panic!("Unsupported function: {}", func_name),
|
||||
let route = resolve_function_route(func_name)
|
||||
.unwrap_or_else(|msg| panic!("{msg}"));
|
||||
|
||||
match route {
|
||||
FunctionRoute::IfReturn => self.lower_if_return_pattern(program_json),
|
||||
FunctionRoute::LoopFrontend => loop_frontend_binding::lower_loop_by_function_name(
|
||||
self,
|
||||
program_json,
|
||||
),
|
||||
FunctionRoute::NestedIf => self.lower_nested_if_pattern(program_json),
|
||||
FunctionRoute::ReadQuoted => self.lower_read_quoted_pattern(program_json),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user