Phase 33 NORM canon test: enforce normalized dev route for P1/P2/JP mini

This commit is contained in:
nyash-codex
2025-12-11 20:54:33 +09:00
parent 59a985b7fa
commit af6f95cd4b
170 changed files with 4423 additions and 1897 deletions

View File

@ -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),
}
}