fix(env): improve Environment::set scope resolution (partial)
Fixed:
- Environment::set now properly searches ancestor chain before creating new binding
- Added exists_in_chain_locked() helper for explicit existence checking
- Simple {} blocks now correctly update outer scope variables
Verified Working:
- local x = 10; { x = 42 }; print(x) → prints 42 ✅
Still Broken:
- else blocks don't update outer scope variables
- local x = 10; if flag { x = 99 } else { x = 42 }; print(x) → prints 10 ❌
Root Cause Identified:
- Issue is in MIR Builder (compile-time), not Environment (runtime)
- src/mir/builder/if_form.rs:108 resets variable_map before else block
- PHI generation at merge doesn't use else_var_map_end correctly
- MIR shows: phi [%32, bb1], [%1, bb2] where %1 is original value, not else value
Next: Fix else block variable merging in if_form.rs
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -109,20 +109,32 @@ impl Environment {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// 親スコープで再帰的に検索・設定
|
||||
// 祖先いずれかに既存があれば「既存を更新」、無ければ「現在スコープに新規定義」
|
||||
if let Some(parent) = &self.parent {
|
||||
match parent.lock().unwrap().set(&name, value.clone_or_share()) {
|
||||
Ok(()) => return Ok(()),
|
||||
Err(EnvironmentError::UndefinedVariable { .. }) => {
|
||||
// 親にもない場合は現在のスコープに新規定義
|
||||
}
|
||||
Err(e) => return Err(e),
|
||||
if Self::exists_in_chain_locked(&parent.lock().unwrap(), &name) {
|
||||
// 祖先のどこかに存在 → そこで更新
|
||||
parent.lock().unwrap().set(&name, value)
|
||||
} else {
|
||||
// どこにも存在しない → 現在のスコープで定義
|
||||
self.bindings.lock().unwrap().insert(name, value);
|
||||
Ok(())
|
||||
}
|
||||
} else {
|
||||
// 親がない(グローバル)→ 現在で定義
|
||||
self.bindings.lock().unwrap().insert(name, value);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// 新規定義として現在のスコープに追加
|
||||
self.bindings.lock().unwrap().insert(name, value);
|
||||
Ok(())
|
||||
/// 祖先(自分含む)に名前が存在するか(ロック下で使用)
|
||||
fn exists_in_chain_locked(&self, name: &str) -> bool {
|
||||
if self.bindings.lock().unwrap().contains_key(name) {
|
||||
return true;
|
||||
}
|
||||
if let Some(parent) = &self.parent {
|
||||
return parent.lock().unwrap().exists_in_chain_locked(name);
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// 変数が存在するかチェック
|
||||
|
||||
Reference in New Issue
Block a user