From: Mark Thom Date: Sun, 7 Oct 2018 01:51:38 +0000 (-0600) Subject: remove modules properly. X-Git-Tag: v0.8.110~344 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=e7717d4f61b9b6c17faabfba1d92b10bcde1aaa7;p=scryer-prolog.git remove modules properly. --- diff --git a/src/prolog/compile.rs b/src/prolog/compile.rs index ecbb1b8c..c931aa32 100644 --- a/src/prolog/compile.rs +++ b/src/prolog/compile.rs @@ -102,7 +102,7 @@ fn compile_decl(wam: &mut Machine, compiler: &mut ListingCompiler, decl: Declara { 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) @@ -149,35 +149,47 @@ impl ListingCompiler { } } - 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, - indices: &mut IndexStore) + fn use_qualified_module(&mut self, submodule: ClauseName, exports: &Vec, + 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] @@ -239,7 +251,7 @@ impl ListingCompiler { 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 { @@ -251,17 +263,9 @@ impl ListingCompiler { 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(); diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index e192b4fc..8f0f85db 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -44,7 +44,17 @@ impl<'a, T> RefOrOwned<'a, T> { } } -impl IndexStore { +impl IndexStore { + #[inline] + pub fn take_module(&mut self, name: ClauseName) -> Option { + 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 { @@ -237,6 +247,7 @@ static CONTROL: &str = include_str!("../lib/control.pl"); 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 { @@ -258,6 +269,7 @@ impl Machine { 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 } @@ -266,12 +278,7 @@ impl Machine { 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() { @@ -325,21 +332,6 @@ impl Machine { 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 { - 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); @@ -350,13 +342,6 @@ impl Machine { 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> diff --git a/src/prolog/toplevel.rs b/src/prolog/toplevel.rs index 8ea97ec0..908f6e8e 100644 --- a/src/prolog/toplevel.rs +++ b/src/prolog/toplevel.rs @@ -702,6 +702,7 @@ impl RelationWorker { queue.push_back(clauses); } + Ok(queue) } diff --git a/src/tests.rs b/src/tests.rs index d5b8eb88..16a31b06 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1374,6 +1374,17 @@ reverse(Xs, Ys) :- lists:reverse(Xs, Ys). 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]