{
let mut indices = default_index_store!(wam.indices.atom_tbl.clone());
let wam_indices = &mut wam.indices;
-
+
compiler.process_decl(decl, wam_indices, &mut indices)?;
Ok(indices)
}
}
- fn use_module(&mut self, submodule: &Module, indices: &mut IndexStore)
+ fn use_module(&mut self, submodule: ClauseName, wam_indices: &mut IndexStore, indices: &mut IndexStore)
-> Result<(), SessionError>
{
let mod_name = self.get_module_name();
- indices.use_module(submodule)?;
+ if let Some(submodule) = wam_indices.take_module(submodule) {
+ indices.use_module(&submodule)?;
- if let &mut Some(ref mut module) = &mut self.module {
- module.remove_module(mod_name, submodule);
- module.use_module(submodule)?;
- }
+ if let &mut Some(ref mut module) = &mut self.module {
+ module.remove_module(mod_name, &submodule);
+ module.use_module(&submodule)?;
+ } else {
+ wam_indices.remove_module(clause_name!("user"), &submodule);
+ }
- Ok(())
+ Ok(wam_indices.insert_module(submodule))
+ } else {
+ Err(SessionError::ModuleNotFound)
+ }
}
- fn use_qualified_module(&mut self, submodule: &Module, exports: &Vec<PredicateKey>,
- indices: &mut IndexStore)
+ fn use_qualified_module(&mut self, submodule: ClauseName, exports: &Vec<PredicateKey>,
+ wam_indices: &mut IndexStore, indices: &mut IndexStore)
-> Result<(), SessionError>
{
let mod_name = self.get_module_name();
- indices.use_qualified_module(submodule, exports)?;
+ if let Some(submodule) = wam_indices.take_module(submodule) {
+ indices.use_qualified_module(&submodule, exports)?;
- if let &mut Some(ref mut module) = &mut self.module {
- module.remove_module(mod_name, submodule);
- module.use_qualified_module(submodule, exports)?;
- }
+ if let &mut Some(ref mut module) = &mut self.module {
+ module.remove_module(mod_name, &submodule);
+ module.use_qualified_module(&submodule, exports)?;
+ } else {
+ wam_indices.remove_module(clause_name!("user"), &submodule);
+ }
- Ok(())
+ Ok(wam_indices.insert_module(submodule))
+ } else {
+ Err(SessionError::ModuleNotFound)
+ }
}
#[inline]
self.non_counted_bt_preds.insert((name, arity));
}
- fn process_decl(&mut self, decl: Declaration, wam_indices: &IndexStore, indices: &mut IndexStore)
+ fn process_decl(&mut self, decl: Declaration, wam_indices: &mut IndexStore, indices: &mut IndexStore)
-> Result<(), SessionError>
{
match decl {
Declaration::Op(op_decl) =>
op_decl.submit(self.get_module_name(), &mut indices.op_dir),
Declaration::UseModule(name) =>
- if let Some(ref submodule) = wam_indices.modules.get(&name) {
- self.use_module(submodule, indices)
- } else {
- Err(SessionError::ModuleNotFound)
- },
+ self.use_module(name, wam_indices, indices),
Declaration::UseQualifiedModule(name, exports) =>
- if let Some(ref submodule) = wam_indices.modules.get(&name) {
- self.use_qualified_module(submodule, &exports, indices)
- } else {
- Err(SessionError::ModuleNotFound)
- },
+ self.use_qualified_module(name, &exports, wam_indices, indices),
Declaration::Module(module_decl) =>
if self.module.is_none() {
let module_name = module_decl.name.clone();
}
}
-impl IndexStore {
+impl IndexStore {
+ #[inline]
+ pub fn take_module(&mut self, name: ClauseName) -> Option<Module> {
+ self.modules.remove(&name)
+ }
+
+ #[inline]
+ pub fn insert_module(&mut self, module: Module) {
+ self.modules.insert(module.module_decl.name.clone(), module);
+ }
+
#[inline]
pub(super) fn new() -> Self {
IndexStore {
static QUEUES: &str = include_str!("../lib/queues.pl");
static ERROR: &str = include_str!("../lib/error.pl");
static TERMS: &str = include_str!("../lib/terms.pl");
+static DCGS: &str = include_str!("../lib/dcgs.pl");
impl Machine {
pub fn new() -> Self {
compile_user_module(&mut wam, QUEUES.as_bytes());
compile_user_module(&mut wam, ERROR.as_bytes());
compile_user_module(&mut wam, TERMS.as_bytes());
+ compile_user_module(&mut wam, DCGS.as_bytes());
wam
}
pub fn machine_flags(&self) -> MachineFlags {
self.machine_st.flags
}
-
- #[inline]
- pub fn failed(&self) -> bool {
- self.machine_st.fail
- }
-
+
pub fn add_batched_code(&mut self, code: Code, code_dir: CodeDir) -> Result<(), SessionError>
{
for (ref key, ref idx) in code_dir.iter() {
self.indices.op_dir.extend(op_dir.into_iter());
}
- #[inline]
- pub fn remove_module(&mut self, module: &Module) {
- self.indices.remove_module(clause_name!("user"), module);
- }
-
- #[inline]
- pub fn take_module(&mut self, name: ClauseName) -> Option<Module> {
- self.indices.modules.remove(&name)
- }
-
- #[inline]
- pub fn insert_module(&mut self, module: Module) {
- self.indices.modules.insert(module.module_decl.name.clone(), module);
- }
-
#[inline]
pub fn add_module(&mut self, module: Module, code: Code) {
self.indices.modules.insert(module.module_decl.name.clone(), module);
self.code_repo.code.len()
}
- fn cached_query_size(&self) -> usize {
- match &self.code_repo.cached_query {
- &Some(ref query) => query.len(),
- _ => 0
- }
- }
-
#[inline]
pub(super)
fn add_term_expansion_clause(&mut self, clause: PredicateClause) -> Result<(), ParserError>
assert_prolog_success!(&mut wam, "?- my_lists_2:local_member(1, [1,2,3]).");
assert_prolog_success!(&mut wam, "?- catch(local_member(X, Xs), error(E, _), true).",
[["X = _1", "E = existence_error(procedure, local_member/2)", "Xs = _2"]]);
+
+ submit(&mut wam, ":- use_module(library(lists), [reverse/2]).");
+
+ assert_prolog_success!(&mut wam, "?- catch(member(_, _), error(existence_error(procedure, P), _), true).",
+ [["P = member/2"]]);
+ assert_prolog_success!(&mut wam, "?- reverse(_, _).");
+
+ submit(&mut wam, ":- use_module(library(lists), []).");
+
+ assert_prolog_success!(&mut wam, "?- catch(reverse(_, _), error(existence_error(procedure, P), _), true).",
+ [["P = reverse/2"]]);
}
#[test]