use crate::{decl_engine::*, monomorphize::priv_prelude::*, namespace, Engines, TypeEngine};
pub(crate) struct InstructContext<'a, 'b: 'a> {
pub(crate) namespace: &'a mut InstructNamespace<'b>,
pub(crate) type_engine: &'a TypeEngine,
pub(crate) decl_engine: &'a DeclEngine,
instructions: &'a [Instruction],
}
impl<'a, 'b> InstructContext<'a, 'b> {
pub(crate) fn from_root(
root_namespace: &'a mut InstructNamespace<'b>,
engines: Engines<'a>,
instructions: &'a [Instruction],
) -> Self {
Self::from_module_namespace(root_namespace, engines, instructions)
}
fn from_module_namespace(
namespace: &'a mut InstructNamespace<'b>,
engines: Engines<'a>,
instructions: &'a [Instruction],
) -> Self {
let (type_engine, decl_engine) = engines.unwrap();
Self {
namespace,
type_engine,
decl_engine,
instructions,
}
}
pub(crate) fn by_ref(&mut self) -> InstructContext<'_, 'b> {
InstructContext {
namespace: self.namespace,
type_engine: self.type_engine,
decl_engine: self.decl_engine,
instructions: self.instructions,
}
}
pub(crate) fn scoped(
self,
namespace: &'a mut InstructNamespace<'b>,
) -> InstructContext<'a, 'b> {
InstructContext {
namespace,
type_engine: self.type_engine,
decl_engine: self.decl_engine,
instructions: self.instructions,
}
}
}
pub(crate) struct InstructNamespace<'a> {
pub(crate) mod_path: PathBuf,
pub(crate) root: &'a mut namespace::Module,
}
impl<'a> InstructNamespace<'a> {
pub(crate) fn init_root(root: &'a mut namespace::Module) -> Self {
let mod_path = vec![];
Self { root, mod_path }
}
pub(crate) fn new_with_module(
&mut self,
module: &mut namespace::Module,
) -> InstructNamespace<'_> {
let mut mod_path = self.mod_path.clone();
if let Some(name) = &module.name {
mod_path.push(name.clone());
}
InstructNamespace {
root: self.root,
mod_path,
}
}
pub(crate) fn module(&self) -> &namespace::Module {
&self.root[&self.mod_path]
}
pub(crate) fn module_mut(&mut self) -> &mut namespace::Module {
&mut self.root[&self.mod_path]
}
}
impl<'a> std::ops::Deref for InstructNamespace<'a> {
type Target = namespace::Module;
fn deref(&self) -> &Self::Target {
self.module()
}
}
impl<'a> std::ops::DerefMut for InstructNamespace<'a> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.module_mut()
}
}