diff --git a/build.rs b/build.rs index 4cc5930b..a9ec444e 100644 --- a/build.rs +++ b/build.rs @@ -1,74 +1,55 @@ extern crate indexmap; -use crate::indexmap::IndexSet; - use std::env; -use std::fs::{File, copy, create_dir_all, read_dir}; +use std::fs; +use std::fs::File; use std::io::Write; use std::path::Path; -fn main() -{ +fn find_prolog_files(libraries: &mut File, prefix: &str, current_dir: &Path) { + let entries = match current_dir.read_dir() { + Ok(entries) => entries, + Err(_) => return, + }; + for entry in entries.filter_map(Result::ok).map(|e| e.path()) { + if entry.is_dir() { + if let Some(file_name) = entry.file_name() { + let new_prefix = + prefix.to_owned() + file_name.to_str().unwrap() + "/"; + find_prolog_files(libraries, &new_prefix, &entry); + } + } else if entry.is_file() { + let ext = std::ffi::OsStr::new("pl"); + if entry.extension() == Some(ext) { + let contain = + String::from_utf8(fs::read(&entry).unwrap()).unwrap(); + let name = entry.file_stem().unwrap().to_str().unwrap(); + let line = format!( + " m.insert(\"{}\",\n{:?});\n", + prefix.to_owned() + name, + contain + ); + + libraries.write_all(line.as_bytes()).unwrap(); + } + } + } +} + +fn main() { let out_dir = env::var("OUT_DIR").unwrap(); let dest_path = Path::new(&out_dir).join("libraries.rs"); let mut libraries = File::create(&dest_path).unwrap(); - let mut library_index = IndexSet::new(); + let lib_path = Path::new("src/lib"); - let mut paths: Vec<_> = read_dir("./src/lib").unwrap() - .map(|e| e.unwrap().path()).collect(); - - while let Some(item) = paths.pop() { - if item.is_file() { - let file_name = item.strip_prefix(".").unwrap(); - - if let Some(ext) = item.extension() { - if ext == "pl" { - let file_stem = item.file_stem().unwrap(); - let file_str = file_stem.to_string_lossy().to_uppercase(); - let dest = Path::new(&out_dir).join(file_name); - let dir_name = dest.parent().unwrap(); - - if !dir_name.exists() { - create_dir_all(dir_name).unwrap(); - } - - match copy(&item, dest) { - Ok(_) => { - } - Err(e) => { - panic!("die: {:?}", e) - } - }; - - let include_line = format!("static {}: &str = include_str!({:?});\n", - file_str, file_name); //file_stem.to_string_lossy()); - - libraries.write_all(include_line.as_bytes()).unwrap(); - library_index.insert(file_stem.to_string_lossy().to_string()); - } - } - } else if item.is_dir() { - for entry in read_dir(item).unwrap() { - let path = entry.unwrap().path(); - paths.push(path); - } - } - } - - libraries.write_all(b"\nref_thread_local! { + libraries + .write_all( + b"ref_thread_local! { pub static managed LIBRARIES: IndexMap<&'static str, &'static str> = { - let mut m = IndexMap::new();\n").unwrap(); - - for item in library_index { - let line = format!("\n m.insert(\"{}\", {});", item, item.to_uppercase()); - libraries.write_all(line.as_bytes()).unwrap(); - } - - libraries.write_all(b"\n\n m\n }; -}\n").unwrap(); - - libraries.write_all(b"\npub static PROJECT_DIR: &'static str = \"").unwrap(); - libraries.write_all(env::var("CARGO_MANIFEST_DIR").unwrap().as_bytes()).unwrap(); - libraries.write_all(b"\";\n").unwrap(); + let mut m = IndexMap::new();\n", + ) + .unwrap(); + find_prolog_files(&mut libraries, "", &lib_path); + libraries.write_all(b"\n m\n };\n}\n").unwrap(); } diff --git a/src/lib/tabling.pl b/src/lib/tabling.pl index 8f2b79d2..703da8e3 100644 --- a/src/lib/tabling.pl +++ b/src/lib/tabling.pl @@ -8,12 +8,12 @@ op(1150, fx, table) ]). -:- use_module('tabling/double_linked_list'). -:- use_module('tabling/table_data_structure'). -:- use_module('tabling/batched_worklist'). -:- use_module('tabling/wrapper'). -:- use_module('tabling/global_worklist'). -:- use_module('tabling/table_link_manager'). +:- use_module(library(tabling/double_linked_list)). +:- use_module(library(tabling/table_data_structure)). +:- use_module(library(tabling/batched_worklist)). +:- use_module(library(tabling/wrapper)). +:- use_module(library(tabling/global_worklist)). +:- use_module(library(tabling/table_link_manager)). :- use_module(library(cont)). :- use_module(library(lists)). diff --git a/src/lib/tabling/batched_worklist.pl b/src/lib/tabling/batched_worklist.pl index 36a67c16..f39f8422 100644 --- a/src/lib/tabling/batched_worklist.pl +++ b/src/lib/tabling/batched_worklist.pl @@ -45,8 +45,8 @@ wkl_worklist_work_done/1 % +WorkList ]). -:- use_module(global_worklist). -:- use_module(double_linked_list). +:- use_module(library(tabling/global_worklist)). +:- use_module(library(tabling/double_linked_list)). :- use_module(library(atts)). :- use_module(library(lists)). diff --git a/src/lib/tabling/table_data_structure.pl b/src/lib/tabling/table_data_structure.pl index b4fc6121..0ce989da 100644 --- a/src/lib/tabling/table_data_structure.pl +++ b/src/lib/tabling/table_data_structure.pl @@ -15,8 +15,8 @@ get_nb_identifiers/3 % +Table, -NbWorklistID, -NbAnswerTreeID ]). -:- use_module(table_link_manager). -:- use_module(trie). +:- use_module(library(tabling/table_link_manager)). +:- use_module(library(tabling/trie)). /* Part of SWI-Prolog @@ -53,7 +53,7 @@ POSSIBILITY OF SUCH DAMAGE. */ -:- use_module(batched_worklist). +:- use_module(library(tabling/batched_worklist)). :- use_module(library(atts)). :- use_module(library(gensym)). diff --git a/src/lib/tabling/table_link_manager.pl b/src/lib/tabling/table_link_manager.pl index c688d0cd..ec88f105 100644 --- a/src/lib/tabling/table_link_manager.pl +++ b/src/lib/tabling/table_link_manager.pl @@ -47,7 +47,7 @@ :- use_module(library(iso_ext)). :- use_module(library(terms)). -:- use_module(trie). +:- use_module(library(tabling/trie)). :- attribute trie_table_link/1. diff --git a/src/machine/compile.rs b/src/machine/compile.rs index 32ed3ee3..36544eba 100644 --- a/src/machine/compile.rs +++ b/src/machine/compile.rs @@ -600,44 +600,25 @@ fn load_library( name: ClauseName, suppress_warnings: bool, ) -> Result { - let mut lib_path = current_dir(); + match LIBRARIES.borrow().get(name.as_str()) { + Some(code) => { + let listing_src = ListingSource::User; - lib_path.pop(); - lib_path.push("lib"); + load_module( + wam, + Stream::from(*code), + suppress_warnings, + &listing_src, + ) + } + None => { + let err = ExistenceError::ModuleSource(ModuleSource::Library( + name.clone() + )); - let (stream, listing_src) = - match LIBRARIES.borrow().get(name.as_str()) { - Some(code) => { - let listing_src = ListingSource::from_file_and_path(name, lib_path); - (Stream::from(*code), listing_src) - } - None => { - // assume that name is a path. - lib_path.push(name.as_str()); - lib_path.set_extension("pl"); - - let file = - match File::open(&lib_path) { - Ok(file) => { - file - } - Err(_) => { - let err = ExistenceError::ModuleSource(ModuleSource::Library(name)); - return Err(SessionError::ExistenceError(err)); - } - }; - - let listing_src = ListingSource::from_file_and_path(name.clone(), lib_path); - (Stream::from_file_as_input(name, file), listing_src) - } - }; - - load_module( - wam, - stream, - suppress_warnings, - &listing_src, - ) + Err(SessionError::ExistenceError(err)) + } + } } impl ListingCompiler { diff --git a/src/machine/mod.rs b/src/machine/mod.rs index 6b8496ca..365b201e 100644 --- a/src/machine/mod.rs +++ b/src/machine/mod.rs @@ -212,17 +212,6 @@ impl SubModuleUser for IndexStore { } } -#[inline] -fn current_dir() -> std::path::PathBuf { - let mut path_buf = std::path::PathBuf::from(PROJECT_DIR); - - // file!() always produces a path relative to PROJECT_DIR. - path_buf = path_buf.join(std::path::PathBuf::from(file!())); - - path_buf.pop(); - path_buf -} - include!(concat!(env!("OUT_DIR"), "/libraries.rs")); static TOPLEVEL: &str = include_str!("../toplevel.pl"); @@ -230,12 +219,7 @@ static TOPLEVEL: &str = include_str!("../toplevel.pl"); impl Machine { fn compile_special_forms(&mut self) { - let current_dir = current_dir(); - - let verify_attrs_src = ListingSource::from_file_and_path( - clause_name!("attributed_variables.pl"), - current_dir.clone(), - ); + let verify_attrs_src = ListingSource::User; match compile_special_form( self, @@ -250,10 +234,7 @@ impl Machine { panic!("Machine::compile_special_forms() failed at VERIFY_ATTRS"), } - let project_attrs_src = ListingSource::from_file_and_path( - clause_name!("project_attributes.pl"), - current_dir, - ); + let project_attrs_src = ListingSource::User; match compile_special_form( self, @@ -273,13 +254,7 @@ impl Machine { { self.toplevel_idx = self.code_repo.code.len(); - let mut current_dir = current_dir(); - current_dir.pop(); - - let top_lvl_src = ListingSource::from_file_and_path( - clause_name!("toplevel.pl"), - current_dir, - ); + let top_lvl_src = ListingSource::User; compile_user_module( self, @@ -371,6 +346,8 @@ impl Machine { pub fn new(current_input_stream: Stream, current_output_stream: Stream) -> Self { + use crate::ref_thread_local::RefThreadLocal; + let mut wam = Machine { machine_st: MachineState::new(), inner_heap: Heap::new(), @@ -383,78 +360,59 @@ impl Machine { }; let atom_tbl = wam.indices.atom_tbl.clone(); - let mut lib_path = current_dir(); - - lib_path.pop(); - lib_path.push("lib"); wam.indices.add_term_and_goal_expansion_indices(); compile_listing( &mut wam, - Stream::from(BUILTINS), + Stream::from(LIBRARIES.borrow()["builtins"]), default_index_store!(atom_tbl.clone()), true, - ListingSource::from_file_and_path( - clause_name!("builtins.pl"), - lib_path.clone(), - ), + ListingSource::User, ); wam.compile_special_forms(); - compile_user_module(&mut wam, - Stream::from(ERROR), - true, - ListingSource::from_file_and_path( - clause_name!("error"), - lib_path.clone(), - ) + compile_user_module( + &mut wam, + Stream::from(LIBRARIES.borrow()["error"]), + true, + ListingSource::User, ); - compile_user_module(&mut wam, - Stream::from(PAIRS), - true, - ListingSource::from_file_and_path( - clause_name!("pairs"), - lib_path.clone(), - ) + compile_user_module( + &mut wam, + Stream::from(LIBRARIES.borrow()["pairs"]), + true, + ListingSource::User, ); - compile_user_module(&mut wam, - Stream::from(LISTS), - true, - ListingSource::from_file_and_path( - clause_name!("lists"), - lib_path.clone(), - ), + compile_user_module( + &mut wam, + Stream::from(LIBRARIES.borrow()["lists"]), + true, + ListingSource::User, ); - compile_user_module(&mut wam, - Stream::from(ISO_EXT), - true, - ListingSource::from_file_and_path( - clause_name!("iso_ext"), - lib_path.clone(), - ) + compile_user_module( + &mut wam, + Stream::from(LIBRARIES.borrow()["iso_ext"]), + true, + ListingSource::User, ); - compile_user_module(&mut wam, - Stream::from(SI), - true, - ListingSource::from_file_and_path( - clause_name!("si"), - lib_path.clone(), - ) + compile_user_module( + &mut wam, + Stream::from(LIBRARIES.borrow()["si"]), + true, + ListingSource::User, ); - compile_user_module(&mut wam, - Stream::from(CHARSIO), - true, - ListingSource::from_file_and_path( - clause_name!("charsio"), - lib_path.clone(), - ) + compile_user_module( + &mut wam, + Stream::from(LIBRARIES.borrow()["charsio"]), + true, + ListingSource::User, ); if wam.compile_top_level().is_err() { @@ -666,46 +624,43 @@ impl Machine { Ok(exports) } - fn use_module(&mut self, to_src: impl Fn(ClauseName) -> ModuleSource) + fn use_module(&mut self, to_src: ToSource) + where ToSource: Fn(ClauseName) -> ModuleSource { // the term expander will overwrite the cached query, so save it here. let cached_query = mem::replace(&mut self.code_repo.cached_query, vec![]); let module_spec = self.machine_st[temp_v!(1)].clone(); - let (name, is_path) = { + let name = { let addr = self.machine_st.store(self.machine_st.deref(module_spec)); match self.machine_st.heap.index_addr(&addr).as_ref() { HeapCellValue::Atom(name, _) => - (name.clone(), name.as_str().contains('/')), + name.clone(), HeapCellValue::Addr(Addr::Char(c)) => - (clause_name!(c.to_string(), self.indices.atom_tbl), false), + clause_name!(c.to_string(), self.indices.atom_tbl), HeapCellValue::Addr(addr @ Addr::PStrLocation(..)) => { - let mut heap_pstr_iter = self.machine_st.heap_pstr_iter(*addr); - let filename = heap_pstr_iter.to_string(); - let is_path = filename.contains('/'); - - (clause_name!(filename, self.indices.atom_tbl), is_path) + let mut heap_pstr_iter = + self.machine_st.heap_pstr_iter(*addr); + clause_name!( + heap_pstr_iter.to_string(), + self.indices.atom_tbl + ) } - _ => - unreachable!(), + _ => unreachable!(), } }; let load_result = match to_src(name) { ModuleSource::Library(name) => - if is_path { - load_library(self, name, false) - } else { - if let Some(module) = self.indices.take_module(name.clone()) { - self.indices.remove_module(clause_name!("user"), &module); - self.indices.modules.insert(name.clone(), module); + if let Some(module) = self.indices.take_module(name.clone()) { + self.indices.remove_module(clause_name!("user"), &module); + self.indices.modules.insert(name.clone(), module); - Ok(name) - } else { - load_library(self, name, false) - } - } + Ok(name) + } else { + load_library(self, name, false) + }, ModuleSource::File(name) => load_module_from_file(self, PathBuf::from(name.as_str()), false) }; @@ -727,27 +682,21 @@ impl Machine { } } - fn use_qualified_module(&mut self, to_src: impl Fn(ClauseName) -> ModuleSource) + fn use_qualified_module(&mut self, to_src: ToSource) + where ToSource: Fn(ClauseName) -> ModuleSource { // the term expander will overwrite the cached query, so save it here. let cached_query = mem::replace(&mut self.code_repo.cached_query, vec![]); let module_spec = self.machine_st[temp_v!(1)].clone(); - let (name, is_path) = { + let name = { let addr = self.machine_st.store(self.machine_st.deref(module_spec)); match self.machine_st.heap.index_addr(&addr).as_ref() { HeapCellValue::Atom(name, _) => - (name.clone(), name.as_str().contains('/')), + name.clone(), HeapCellValue::Addr(Addr::Char(c)) => - (clause_name!(c.to_string(), self.indices.atom_tbl), false), - HeapCellValue::Addr(addr @ Addr::PStrLocation(..)) => { - let mut heap_pstr_iter = self.machine_st.heap_pstr_iter(*addr); - let filename = heap_pstr_iter.to_string(); - let is_path = filename.contains('/'); - - (clause_name!(filename, self.indices.atom_tbl), is_path) - } + clause_name!(c.to_string(), self.indices.atom_tbl), _ => unreachable!(), } @@ -763,18 +712,14 @@ impl Machine { let load_result = match to_src(name) { ModuleSource::Library(name) => - if is_path { - load_library(self, name, false) - } else { - if let Some(module) = self.indices.take_module(name.clone()) { - self.indices.remove_module(clause_name!("user"), &module); - self.indices.modules.insert(name.clone(), module); + if let Some(module) = self.indices.take_module(name.clone()) { + self.indices.remove_module(clause_name!("user"), &module); + self.indices.modules.insert(name.clone(), module); - Ok(name) - } else { - load_library(self, name, false) - } - }, + Ok(name) + } else { + load_library(self, name, false) + }, ModuleSource::File(name) => load_module_from_file(self, PathBuf::from(name.as_str()), false) }; diff --git a/src/machine/toplevel.rs b/src/machine/toplevel.rs index 2e553cea..eaa17691 100644 --- a/src/machine/toplevel.rs +++ b/src/machine/toplevel.rs @@ -340,7 +340,10 @@ fn setup_module_decl( } } -fn read_library_path(term: Term, atom_tbl: TabledData) -> Option { +fn read_library_path( + term: Term, + atom_tbl: TabledData, +) -> Option { match term { Term::Constant(_, Constant::Atom(atom, _)) => { Some(atom.defrock_brackets()) @@ -353,9 +356,7 @@ fn read_library_path(term: Term, atom_tbl: TabledData) -> Option { atoms.push(atom.as_str().to_owned()); } - _ => { - return None; - } + _ => return None, } } @@ -364,10 +365,7 @@ fn read_library_path(term: Term, atom_tbl: TabledData) -> Option>, - atom_tbl: TabledData, -) -> Result { +fn setup_use_module_decl(mut terms: Vec>, atom_tbl: TabledData) -> Result { match *terms.pop().unwrap() { Term::Clause(_, ref name, ref mut terms, None) if name.as_str() == "library" && terms.len() == 1 =>