From a623061a1af068e2a60ce536c0d8189578c1a65b Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Wed, 2 Oct 2019 15:51:48 -0600 Subject: [PATCH] correct handling of ! in phrase/{2,3}, get rid of extraneous choice points in put_atts/2 and get_atts/2, allow loading of non-module files from the command line and use_module/{2,3} --- src/prolog/lib/atts.pl | 4 +-- src/prolog/lib/dcgs.pl | 4 +++ src/prolog/machine/compile.rs | 61 +++++++++++++++++++------------- src/prolog/machine/mod.rs | 65 ++++++++++++++++++++--------------- 4 files changed, 81 insertions(+), 53 deletions(-) diff --git a/src/prolog/lib/atts.pl b/src/prolog/lib/atts.pl index 868ef4ae..2bad592e 100644 --- a/src/prolog/lib/atts.pl +++ b/src/prolog/lib/atts.pl @@ -33,7 +33,7 @@ '$add_to_list'(Ls, V, Attr) :- ( var(Ls) -> Ls = [Attr | _], '$enqueue_attr_var'(V) - ; Ls = [_ | Ls0] -> '$add_to_list'(Ls0, V, Attr) + ; Ls = [_ | Ls0], '$add_to_list'(Ls0, V, Attr) ). '$del_attr'(Ls0, _, _) :- @@ -89,7 +89,7 @@ get_attrs_var_check --> put_attrs(Name/Arity) --> put_attr(Name, Arity), { numbervars([Var, Attr], 0, _) }, - [(put_atts(Var, Attr) :- lists:maplist(put_atts(Var), Attr))]. + [(put_atts(Var, Attr) :- lists:maplist(put_atts(Var), Attr), !)]. put_attrs((Name/Arity, Atts)) --> { nonvar(Atts) }, put_attr(Name, Arity), diff --git a/src/prolog/lib/dcgs.pl b/src/prolog/lib/dcgs.pl index 9050f480..1805dc80 100644 --- a/src/prolog/lib/dcgs.pl +++ b/src/prolog/lib/dcgs.pl @@ -9,6 +9,8 @@ phrase(G, G) :- nonvar(G), G = [_|_], !. phrase(G, Ls0) :- nonvar(G), G = (G1, G2), !, phrase(G1, Ls0, Ls1), phrase(G2, Ls1, []). +phrase(G, Ls0) :- + nonvar(G), G == !, !, Ls0 = []. phrase(G, Ls0) :- call(G, Ls0, []). @@ -17,6 +19,8 @@ phrase(G, Ls0, Ls1) :- phrase(G, Ls0, Ls2) :- nonvar(G), G = (G1, G2), !, phrase(G1, Ls0, Ls1), phrase(G2, Ls1, Ls2). +phrase(G, Ls0, Ls1) :- + nonvar(G), G == !, !, Ls0 = [], Ls1 = []. phrase(G, Ls0, Ls1) :- call(G, Ls0, Ls1). diff --git a/src/prolog/machine/compile.rs b/src/prolog/machine/compile.rs index 2df48229..079f7c12 100644 --- a/src/prolog/machine/compile.rs +++ b/src/prolog/machine/compile.rs @@ -56,8 +56,8 @@ fn fix_filename(atom_tbl: TabledData, filename: &str) -> Result(wam: &mut Machine, name: &str, stream: ParsingStream) - -> Result +fn load_module(wam: &mut Machine, stream: ParsingStream) + -> Result, SessionError> { // follow the operation of compile_user_module, but before // compiling, check that a module is declared in the file. if not, @@ -69,10 +69,9 @@ fn load_module(wam: &mut Machine, name: &str, stream: ParsingStream) let results = compiler.gather_items(wam, stream, &mut indices)?; let module_name = if let Some(ref module) = &compiler.module { - module.module_decl.name.clone() + Some(module.module_decl.name.clone()) } else { - let module_name = clause_name!(name.to_string(), wam.indices.atom_tbl); - return Err(SessionError::NoModuleDeclaration(module_name)); + None }; match compile_work_impl(&mut compiler, wam, indices, results) { @@ -82,7 +81,8 @@ fn load_module(wam: &mut Machine, name: &str, stream: ParsingStream) } pub(super) -fn load_module_from_file(wam: &mut Machine, filename: &str) -> Result +fn load_module_from_file(wam: &mut Machine, filename: &str) + -> Result, SessionError> { let path = fix_filename(wam.indices.atom_tbl.clone(), filename)?; @@ -91,8 +91,7 @@ fn load_module_from_file(wam: &mut Machine, filename: &str) -> Result); @@ -468,9 +467,13 @@ fn add_non_module_code( } pub(super) -fn load_library(wam: &mut Machine, name: ClauseName) -> Result { +fn load_library(wam: &mut Machine, name: ClauseName) -> Result +{ match LIBRARIES.borrow().get(name.as_str()) { - Some(code) => load_module(wam, name.as_str(), parsing_stream(code.as_bytes())), + Some(code) => { + let module_name = load_module(wam, parsing_stream(code.as_bytes()))?; + module_name.ok_or(SessionError::NoModuleDeclaration(name)) + } None => Err(SessionError::ModuleNotFound) } } @@ -767,25 +770,35 @@ impl ListingCompiler { } Declaration::UseModule(ModuleSource::File(filename)) => { let name = load_module_from_file(wam, filename.as_str())?; - self.use_module(name, &mut wam.code_repo, flags, &mut wam.indices, indices) + + if let Some(name) = name { + self.use_module(name, &mut wam.code_repo, flags, &mut wam.indices, indices) + } else { + Ok(()) + } } Declaration::UseQualifiedModule(ModuleSource::File(filename), exports) => { let name = load_module_from_file(wam, filename.as_str())?; - self.use_qualified_module( - name, - &mut wam.code_repo, - flags, - &exports, - &mut wam.indices, - indices, - ) + + if let Some(name) = name { + self.use_qualified_module( + name, + &mut wam.code_repo, + flags, + &exports, + &mut wam.indices, + indices, + ) + } else { + Ok(()) + } } Declaration::ModuleInitialization(query_terms, queue) => { self.initialization_goals.0.extend(query_terms.into_iter()); self.initialization_goals.1.extend(queue.into_iter()); - + Ok(()) - } + } Declaration::Dynamic(..) => Ok(()), } } @@ -886,7 +899,7 @@ fn compile_work_impl( wam: &mut Machine, mut indices: IndexStore, mut results: GatherResult, -) -> EvalSession { +) -> EvalSession { let module_code = try_eval_session!(compiler.generate_code( results.worker_results, wam, @@ -939,11 +952,11 @@ fn compile_work_impl( let init_goal_code = try_eval_session!(compiler.generate_init_goal_code( wam.machine_flags() )); - + if init_goal_code.len() > 0 { wam.run_init_code(init_goal_code); } - + EvalSession::EntrySuccess } diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index a5770c62..74ac93ba 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -430,22 +430,28 @@ impl Machine { let load_result = match to_src(name) { ModuleSource::Library(name) => if !self.indices.modules.contains_key(&name) { - load_library(self, name) + load_library(self, name).map(Some) } else { - Ok(name) + Ok(Some(name)) }, - ModuleSource::File(name) => load_module_from_file(self, name.as_str()) + ModuleSource::File(name) => + load_module_from_file(self, name.as_str()) }; - let result = load_result.and_then(|name| { - let module = self.indices.take_module(name).unwrap(); - - // remove previous exports. - self.indices.remove_module(clause_name!("user"), &module); - self.indices.use_module(&mut self.code_repo, self.machine_st.flags, &module)?; - - Ok(self.indices.insert_module(module)) - }); + let result = load_result.and_then(|name| + if let Some(name) = name { + let module = self.indices.take_module(name).unwrap(); + + // remove previous exports. + self.indices.remove_module(clause_name!("user"), &module); + self.indices.use_module(&mut self.code_repo, self.machine_st.flags, + &module)?; + + Ok(self.indices.insert_module(module)) + } else { + Ok(()) + } + ); self.code_repo.cached_query = cached_query; @@ -471,25 +477,30 @@ impl Machine { let load_result = match to_src(name) { ModuleSource::Library(name) => if !self.indices.modules.contains_key(&name) { - load_library(self, name) + load_library(self, name).map(Some) } else { - Ok(name) + Ok(Some(name)) }, - ModuleSource::File(name) => load_module_from_file(self, name.as_str()) + ModuleSource::File(name) => + load_module_from_file(self, name.as_str()) }; - let result = load_result.and_then(|name| { - let module = self.indices.take_module(name).unwrap(); - - // remove previous exports. - self.indices.remove_module(clause_name!("user"), &module); - self.indices.use_qualified_module(&mut self.code_repo, - self.machine_st.flags, - &module, - &exports)?; - - Ok(self.indices.insert_module(module)) - }); + let result = load_result.and_then(|name| + if let Some(name) = name { + let module = self.indices.take_module(name).unwrap(); + + // remove previous exports. + self.indices.remove_module(clause_name!("user"), &module); + self.indices.use_qualified_module(&mut self.code_repo, + self.machine_st.flags, + &module, + &exports)?; + + Ok(self.indices.insert_module(module)) + } else { + Ok(()) + } + ); self.code_repo.cached_query = cached_query; -- 2.54.0