name: ClauseName,
suppress_warnings: bool,
) -> Result<ClauseName, SessionError> {
- let mut lib_path = current_dir();
+ match LIBRARIES.borrow().get(name.as_str()) {
+ Some(code) => {
+ let mut lib_path = current_dir();
- lib_path.pop();
- lib_path.push("lib");
+ lib_path.pop();
+ lib_path.push("lib");
- 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, lib_path);
- 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::from(*code),
+ suppress_warnings,
+ &listing_src,
+ )
+ }
+ None => {
+ let err = ExistenceError::ModuleSource(ModuleSource::Library(
+ name.clone()
+ ));
- load_module(
- wam,
- stream,
- suppress_warnings,
- &listing_src,
- )
+ Err(SessionError::ExistenceError(err))
+ }
+ }
}
impl ListingCompiler {
Ok(exports)
}
- fn use_module(&mut self, to_src: impl Fn(ClauseName) -> ModuleSource)
+ fn use_module<ToSource>(&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!(),
}
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);
-
- Ok(name)
- } else {
- load_library(self, name, false)
- }
- }
+ 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)
+ },
ModuleSource::File(name) =>
load_module_from_file(self, PathBuf::from(name.as_str()), false)
};
}
}
- fn use_qualified_module(&mut self, to_src: impl Fn(ClauseName) -> ModuleSource)
+ fn use_qualified_module<ToSource>(&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!(),
}
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);
-
- Ok(name)
- } else {
- load_library(self, name, false)
- }
- },
+ 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)
+ },
ModuleSource::File(name) =>
load_module_from_file(self, PathBuf::from(name.as_str()), false)
};
}
}
-fn read_library_path(term: Term, atom_tbl: TabledData<Atom>) -> Option<ClauseName> {
- match term {
- Term::Constant(_, Constant::Atom(atom, _)) => {
- Some(atom.defrock_brackets())
- }
- _ => {
- let mut atoms = vec![];
-
- for term in unfold_by_str(term, "/") {
- match term {
- Term::Constant(_, Constant::Atom(atom, _)) => {
- atoms.push(atom.as_str().to_owned());
- }
- _ => {
- return None;
- }
- }
- }
-
- Some(clause_name!(atoms.join("/"), atom_tbl))
- }
- }
-}
-
-fn setup_use_module_decl(
- mut terms: Vec<Box<Term>>,
- atom_tbl: TabledData<Atom>,
-) -> Result<ModuleSource, ParserError> {
+fn setup_use_module_decl(mut terms: Vec<Box<Term>>) -> Result<ModuleSource, ParserError> {
match *terms.pop().unwrap() {
Term::Clause(_, ref name, ref mut terms, None)
if name.as_str() == "library" && terms.len() == 1 =>
{
- read_library_path(*terms.pop().unwrap(), atom_tbl)
+ terms
+ .pop()
+ .unwrap()
+ .to_constant()
+ .and_then(|c| c.to_atom())
.map(|c| ModuleSource::Library(c))
.ok_or(ParserError::InvalidUseModuleDecl)
}
Term::Clause(_, ref name, ref mut terms, None)
if name.as_str() == "library" && terms.len() == 1 =>
{
- read_library_path(*terms.pop().unwrap(), atom_tbl.clone())
+ terms
+ .pop()
+ .unwrap()
+ .to_constant()
+ .and_then(|c| c.to_atom())
.map(|c| ModuleSource::Library(c))
.ok_or(ParserError::InvalidUseModuleDecl)
}
}
}
("use_module", 1) => {
- Ok(Declaration::UseModule(setup_use_module_decl(terms, indices.atom_tbl())?))
+ Ok(Declaration::UseModule(setup_use_module_decl(terms)?))
}
("use_module", 2) => {
let (name, exports) = setup_qualified_import(terms, indices.atom_tbl())?;
use_module(Module) :-
( nonvar(Module) ->
- ( Module = library(Filename) ->
- write_term_to_chars(Filename, [], FilenameString),
- '$use_module'(FilenameString)
- ; atom(Module) ->
- '$use_module_from_file'(Module)
+ ( Module = library(Filename) -> '$use_module'(Filename)
+ ; atom(Module) -> '$use_module_from_file'(Module)
; throw(error(invalid_module_specifier, use_module/1))
)
; throw(error(instantiation_error, use_module/1))
( list_si(QualifiedExports) ->
maplist('$module_export'(use_module/2), QualifiedExports) ->
( Module = library(Filename) ->
- write_term_to_chars(Filename, [], FilenameString),
- '$use_qualified_module'(FilenameString, QualifiedExports)
+ '$use_qualified_module'(Filename, QualifiedExports)
; atom(Module) ->
'$use_qualified_module_from_file'(Module, QualifiedExports)
; throw(error(invalid_module_specifier, use_module/2))