Factor JSON v0 bridge globals/throw into small helpers

This commit is contained in:
nyash-codex
2025-11-24 15:21:49 +09:00
parent da1a5558e5
commit 6885235145
5 changed files with 156 additions and 93 deletions

View File

@ -1,7 +1,9 @@
use super::match_expr;
use super::merge::new_block;
use super::globals::resolve_bridge_global;
use super::ternary;
use super::BridgeEnv;
use super::throw_lower::lower_throw;
use crate::mir::{BasicBlockId, ConstValue, EffectMask, MirFunction, MirInstruction, ValueId};
use crate::ast::Span;
use std::collections::BTreeMap;
@ -50,101 +52,15 @@ impl<'a> VarScope for MapVars<'a> {
if let Some(&vid) = self.vars.get(name) {
return Ok(Some(vid));
}
// Phase 21.8: Check using-imported modules/boxes
if let Some(box_type) = env.imports.get(name) {
let dst = f.next_value_id();
if let Some(bb) = f.get_block_mut(cur_bb) {
// Treat as static box reference - create a const string representing the box type
bb.add_instruction(MirInstruction::Const {
dst,
value: ConstValue::String(box_type.clone()),
});
}
// Cache the resolution for subsequent uses
self.vars.insert(name.to_string(), dst);
return Ok(Some(dst));
}
// Phase 25.1a: Treat `hostbridge` as a well-known global for bridge lowering.
// The actual extern dispatch is handled at runtime; here we only need a stable
// placeholder value so that Program(JSON) containing hostbridge.extern_invoke(...)
// can be lowered without "undefined variable" errors.
if name == "hostbridge" {
let dst = f.next_value_id();
if let Some(bb) = f.get_block_mut(cur_bb) {
bb.add_instruction(MirInstruction::Const {
dst,
value: ConstValue::String("hostbridge".into()),
});
}
self.vars.insert(name.to_string(), dst);
return Ok(Some(dst));
}
// Phase 25.1b: Treat `env` as a well-known global for env.box_introspect.* etc.
// Similar to hostbridge, we need a placeholder value for the nested method pattern.
if name == "env" {
let dst = f.next_value_id();
if let Some(bb) = f.get_block_mut(cur_bb) {
bb.add_instruction(MirInstruction::Const {
dst,
value: ConstValue::String("env".into()),
});
}
self.vars.insert(name.to_string(), dst);
return Ok(Some(dst));
}
if name == "me" {
if env.allow_me_dummy {
let dst = f.next_value_id();
if let Some(bb) = f.get_block_mut(cur_bb) {
bb.add_instruction(MirInstruction::NewBox {
dst,
box_type: env.me_class.clone(),
args: vec![],
});
}
self.vars.insert(name.to_string(), dst);
Ok(Some(dst))
} else {
Err("undefined 'me' outside box context (set NYASH_BRIDGE_ME_DUMMY=1 to inject placeholder)".into())
}
} else {
Ok(None)
}
}
}
fn lower_throw(
env: &BridgeEnv,
f: &mut MirFunction,
cur_bb: BasicBlockId,
exception_value: ValueId,
) -> (ValueId, BasicBlockId) {
// Result-mode try context active: route to current catch via Jump and record incoming
if env.try_result_mode && super::throw_ctx::is_active() {
if crate::config::env::cli_verbose() {
eprintln!("[Bridge] lower_throw: routing to catch (Result-mode)");
// Bridge 固有のグローバル解決imports/hostbridge/env/me dummyは専用モジュールに委譲
if let Some(vid) =
resolve_bridge_global(name, env, f, cur_bb, self.vars)?
{
return Ok(Some(vid));
}
let _ = super::throw_ctx::record_throw(f, cur_bb, exception_value);
return (exception_value, cur_bb);
}
// Legacy path: emit MIR Throw (if enabled) or degrade to const 0
if env.throw_enabled {
if let Some(bb) = f.get_block_mut(cur_bb) {
bb.set_terminator(MirInstruction::Throw {
exception: exception_value,
effects: EffectMask::PANIC,
});
}
(exception_value, cur_bb)
} else {
let dst = f.next_value_id();
if let Some(bb) = f.get_block_mut(cur_bb) {
bb.add_instruction(MirInstruction::Const {
dst,
value: ConstValue::Integer(0),
});
}
(dst, cur_bb)
Ok(None)
}
}