]> Repositorios git - scryer-prolog.git/commitdiff
correct handling of ! in phrase/{2,3}, get rid of extraneous choice points in put_att...
authorMark Thom <[email protected]>
Wed, 2 Oct 2019 21:51:48 +0000 (15:51 -0600)
committerMark Thom <[email protected]>
Wed, 2 Oct 2019 21:51:48 +0000 (15:51 -0600)
src/prolog/lib/atts.pl
src/prolog/lib/dcgs.pl
src/prolog/machine/compile.rs
src/prolog/machine/mod.rs

index 868ef4aed78d0e51c2e0cbf347849529e484725c..2bad592ecda09836a3e1d43a61c5701d0c157124 100644 (file)
@@ -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),
index 9050f4802838d704ef37cdb719b3916d17716919..1805dc802cd77e8b7767c59b907eb1bc712fb6ad 100644 (file)
@@ -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).
 
index 2df48229c617367de66dba3766da0e40d6f837e2..079f7c12502daf6baa080423ae4ad1b882c1900d 100644 (file)
@@ -56,8 +56,8 @@ fn fix_filename(atom_tbl: TabledData<Atom>, filename: &str) -> Result<PathBuf, S
     Ok(path)
 }
 
-fn load_module<R: Read>(wam: &mut Machine, name: &str, stream: ParsingStream<R>)
-                        -> Result<ClauseName, SessionError>
+fn load_module<R: Read>(wam: &mut Machine, stream: ParsingStream<R>)
+                        -> Result<Option<ClauseName>, 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<R: Read>(wam: &mut Machine, name: &str, stream: ParsingStream<R>)
     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<R: Read>(wam: &mut Machine, name: &str, stream: ParsingStream<R>)
 }
 
 pub(super)
-fn load_module_from_file(wam: &mut Machine, filename: &str) -> Result<ClauseName, SessionError>
+fn load_module_from_file(wam: &mut Machine, filename: &str)
+                         -> Result<Option<ClauseName>, 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<ClauseName
         Err(SessionError::InvalidFileName(filename))
     })?;
 
-    let file_stem = path.file_stem().unwrap().to_string_lossy();
-    load_module(wam, &file_stem, parsing_stream(file_handle))
+    load_module(wam, parsing_stream(file_handle))
 }
 
 pub type PredicateCompileQueue = (Predicate, VecDeque<TopLevel>);
@@ -468,9 +467,13 @@ fn add_non_module_code(
 }
 
 pub(super)
-fn load_library(wam: &mut Machine, name: ClauseName) -> Result<ClauseName, SessionError> {
+fn load_library(wam: &mut Machine, name: ClauseName) -> Result<ClauseName, SessionError>
+{
     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
 }
 
index a5770c62ebe3336d0f754e5bc553a602dfecedac..74ac93ba3390ac7eed15498bba932bc34993b0ed 100644 (file)
@@ -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;