feat(joinir): Phase 64-1/2 P2型ヒント実装 & 削減条件準備
Phase 64-1: P2/P3 対象関数分類完了 - P2 対象リスト作成: read_quoted_from, IfMerge Simple/Multiple - P3 将来拡張: MethodCall戻り値型, Box コンストラクタ - 実装戦略確立: P2から1関数ずつ段階的拡大 Phase 64-2: P2 型ヒント供給実装完了 - read_quoted.rs: ループカウンタ i (Integer), 文字列 ch (String) 型確定 - if_merge.rs: infer_type_from_mir_pattern() 追加 (Const命令から型推論) - A/B テスト追加: test_p2_if_merge_type_hint() で型ヒント伝播検証 ✅ 技術的成果: - JoinIR MergePair の type_hint 自動推論システム完成 - Phase 63 P1実装パターンを P2 に拡大適用 - 次ステップ: Phase 64-3 lifecycle.rs で P2 hint経路統合 修正ファイル: - phase-63-joinir-type-info/README.md: Phase 64-1/2 セクション追加 - read_quoted.rs: MergePair 型ヒント追加 (Integer/String) - if_merge.rs: infer_type_from_mir_pattern() + 型ヒント推論 - mir_joinir_if_select.rs: test_p2_if_merge_type_hint() 追加 🎯 削除条件 4/5 維持 (P1完了), Phase 64-3で P2拡大へ 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -36,15 +36,37 @@ pub static OPERATORS_DIV_RULES: &[(&str, &str, &str, &str)] = &[
|
|||||||
];
|
];
|
||||||
pub fn lookup_keyword(word: &str) -> Option<&'static str> {
|
pub fn lookup_keyword(word: &str) -> Option<&'static str> {
|
||||||
for (k, t) in KEYWORDS {
|
for (k, t) in KEYWORDS {
|
||||||
if *k == word {
|
if *k == word { return Some(*t); }
|
||||||
return Some(*t);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static SYNTAX_ALLOWED_STATEMENTS: &[&str] = &[
|
pub static SYNTAX_ALLOWED_STATEMENTS: &[&str] = &[
|
||||||
"box", "global", "function", "static", "if", "loop", "break", "return", "print", "nowait",
|
"box",
|
||||||
"include", "local", "outbox", "try", "throw", "using", "from",
|
"global",
|
||||||
|
"function",
|
||||||
|
"static",
|
||||||
|
"if",
|
||||||
|
"loop",
|
||||||
|
"break",
|
||||||
|
"return",
|
||||||
|
"print",
|
||||||
|
"nowait",
|
||||||
|
"include",
|
||||||
|
"local",
|
||||||
|
"outbox",
|
||||||
|
"try",
|
||||||
|
"throw",
|
||||||
|
"using",
|
||||||
|
"from",
|
||||||
];
|
];
|
||||||
pub static SYNTAX_ALLOWED_BINOPS: &[&str] = &["add", "sub", "mul", "div", "and", "or", "eq", "ne"];
|
pub static SYNTAX_ALLOWED_BINOPS: &[&str] = &[
|
||||||
|
"add",
|
||||||
|
"sub",
|
||||||
|
"mul",
|
||||||
|
"div",
|
||||||
|
"and",
|
||||||
|
"or",
|
||||||
|
"eq",
|
||||||
|
"ne",
|
||||||
|
];
|
||||||
@ -401,15 +401,15 @@ impl AstToJoinIrLowerer {
|
|||||||
merges: vec![
|
merges: vec![
|
||||||
MergePair {
|
MergePair {
|
||||||
dst: i_after_esc,
|
dst: i_after_esc,
|
||||||
then_val: i_esc,
|
then_val: i_esc, // i + 1 (BinOp::Add, Integer)
|
||||||
else_val: step_i,
|
else_val: step_i, // i (Integer param)
|
||||||
type_hint: None, // Phase 63-3
|
type_hint: Some(crate::mir::MirType::Integer), // Phase 64-2: ループカウンタ型確定
|
||||||
},
|
},
|
||||||
MergePair {
|
MergePair {
|
||||||
dst: ch_merged,
|
dst: ch_merged,
|
||||||
then_val: ch_esc,
|
then_val: ch_esc, // substring 結果 (String)
|
||||||
else_val: step_ch,
|
else_val: step_ch, // substring 結果 (String)
|
||||||
type_hint: None, // Phase 63-3
|
type_hint: Some(crate::mir::MirType::String), // Phase 64-2: 文字列型確定
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
k_next: None,
|
k_next: None,
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
//! - Loop の PHI には触らない(Loop lowering の責務)
|
//! - Loop の PHI には触らない(Loop lowering の責務)
|
||||||
|
|
||||||
use crate::mir::join_ir::{JoinInst, MergePair};
|
use crate::mir::join_ir::{JoinInst, MergePair};
|
||||||
use crate::mir::{BasicBlockId, MirFunction, MirInstruction, ValueId};
|
use crate::mir::{BasicBlockId, MirFunction, MirInstruction, MirType, ValueId};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
// Phase 61-1: If-in-loop context support
|
// Phase 61-1: If-in-loop context support
|
||||||
@ -198,11 +198,15 @@ impl IfMergeLowerer {
|
|||||||
// else ブロックで dst に書き込まれる値を探す
|
// else ブロックで dst に書き込まれる値を探す
|
||||||
let else_val = self.find_written_value(&else_block.instructions, dst)?;
|
let else_val = self.find_written_value(&else_block.instructions, dst)?;
|
||||||
|
|
||||||
|
// Phase 64-2: then_val / else_val から型ヒント推論
|
||||||
|
let type_hint = infer_type_from_mir_pattern(func, then_val)
|
||||||
|
.or_else(|| infer_type_from_mir_pattern(func, else_val));
|
||||||
|
|
||||||
merge_pairs.push(MergePair {
|
merge_pairs.push(MergePair {
|
||||||
dst,
|
dst,
|
||||||
then_val,
|
then_val,
|
||||||
else_val,
|
else_val,
|
||||||
type_hint: None, // Phase 63-3: 現時点では型ヒントなし
|
type_hint, // Phase 64-2: Const 命令から型推論
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,6 +276,34 @@ impl IfMergeLowerer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Phase 64-2: MIR から ValueId の型を推論
|
||||||
|
///
|
||||||
|
/// Const 命令を探して、ValueId に対応する MirType を返す。
|
||||||
|
/// IfMerge の then_val / else_val から型ヒントを埋めるために使用。
|
||||||
|
fn infer_type_from_mir_pattern(func: &MirFunction, val_id: ValueId) -> Option<MirType> {
|
||||||
|
use crate::mir::{ConstValue, MirInstruction, MirType};
|
||||||
|
|
||||||
|
// 全ブロックの全命令を走査して Const 命令を探す
|
||||||
|
for block in func.blocks.values() {
|
||||||
|
for inst in &block.instructions {
|
||||||
|
if let MirInstruction::Const { dst, value } = inst {
|
||||||
|
if *dst == val_id {
|
||||||
|
return Some(match value {
|
||||||
|
ConstValue::Integer(_) => MirType::Integer,
|
||||||
|
ConstValue::Bool(_) => MirType::Bool,
|
||||||
|
ConstValue::String(_) => MirType::String,
|
||||||
|
ConstValue::Void => MirType::Void,
|
||||||
|
ConstValue::Null => MirType::Unknown, // Null は Unknown として扱う
|
||||||
|
// Float は現状未サポート
|
||||||
|
_ => return None,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
@ -719,4 +719,59 @@ mod tests {
|
|||||||
|
|
||||||
std::env::remove_var("NYASH_JOINIR_IF_SELECT");
|
std::env::remove_var("NYASH_JOINIR_IF_SELECT");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Phase 64-2-2: A/B テスト - P2 IfMerge Simple 型ヒント検証
|
||||||
|
///
|
||||||
|
/// IfMerge Simple パターンで MergePair の type_hint が正しく設定されることを確認。
|
||||||
|
/// Phase 64-2 で追加した `infer_type_from_mir_pattern()` の動作確認。
|
||||||
|
#[test]
|
||||||
|
fn test_p2_if_merge_type_hint() {
|
||||||
|
use crate::mir::join_ir::lowering::if_merge::IfMergeLowerer;
|
||||||
|
use crate::mir::MirType;
|
||||||
|
|
||||||
|
std::env::set_var("NYASH_JOINIR_IF_MERGE", "1");
|
||||||
|
|
||||||
|
// P2 IfMerge Simple pattern で IfMerge 生成
|
||||||
|
let func = create_if_merge_simple_pattern_mir();
|
||||||
|
let entry_block = func.entry_block;
|
||||||
|
|
||||||
|
let lowerer = IfMergeLowerer::new(2); // debug_level=2
|
||||||
|
let join_inst = lowerer
|
||||||
|
.lower_if_to_if_merge(&func, entry_block)
|
||||||
|
.expect("P2 IfMerge Simple should lower to IfMerge");
|
||||||
|
|
||||||
|
// IfMerge instruction から merge_pairs を取り出す
|
||||||
|
use crate::mir::join_ir::JoinInst;
|
||||||
|
if let JoinInst::IfMerge { merges, .. } = join_inst {
|
||||||
|
eprintln!("✅ Phase 64-2-2 Step 1: IfMerge instruction found");
|
||||||
|
|
||||||
|
// MergePair の型ヒント確認(Const 命令から Integer を推論)
|
||||||
|
assert!(
|
||||||
|
!merges.is_empty(),
|
||||||
|
"IfMerge should have at least one MergePair"
|
||||||
|
);
|
||||||
|
|
||||||
|
// 最初の MergePair の型ヒントを確認(x に Integer 代入)
|
||||||
|
let first_pair = &merges[0];
|
||||||
|
if let Some(type_hint) = &first_pair.type_hint {
|
||||||
|
eprintln!(
|
||||||
|
"✅ Phase 64-2-2 Step 2: MergePair[0] type_hint = Some({:?})",
|
||||||
|
type_hint
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
*type_hint,
|
||||||
|
MirType::Integer,
|
||||||
|
"P2 IfMerge Simple should infer Integer type from Const"
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
panic!("P2 IfMerge Simple should have type_hint=Some(Integer), got None");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
panic!("Expected IfMerge instruction, got: {:?}", join_inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
eprintln!("✅ Phase 64-2-2: P2 IfMerge type hint test passed - infer_type_from_mir_pattern() works!");
|
||||||
|
|
||||||
|
std::env::remove_var("NYASH_JOINIR_IF_MERGE");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user