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}

This commit is contained in:
Mark Thom
2019-10-02 15:51:48 -06:00
parent ccd3dfb436
commit a623061a1a
4 changed files with 79 additions and 51 deletions

View File

@@ -33,7 +33,7 @@
'$add_to_list'(Ls, V, Attr) :- '$add_to_list'(Ls, V, Attr) :-
( var(Ls) -> Ls = [Attr | _], '$enqueue_attr_var'(V) ( 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, _, _) :- '$del_attr'(Ls0, _, _) :-
@@ -89,7 +89,7 @@ get_attrs_var_check -->
put_attrs(Name/Arity) --> put_attrs(Name/Arity) -->
put_attr(Name, Arity), put_attr(Name, Arity),
{ numbervars([Var, Attr], 0, _) }, { 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)) --> put_attrs((Name/Arity, Atts)) -->
{ nonvar(Atts) }, { nonvar(Atts) },
put_attr(Name, Arity), put_attr(Name, Arity),

View File

@@ -9,6 +9,8 @@ phrase(G, G) :-
nonvar(G), G = [_|_], !. nonvar(G), G = [_|_], !.
phrase(G, Ls0) :- phrase(G, Ls0) :-
nonvar(G), G = (G1, G2), !, phrase(G1, Ls0, Ls1), phrase(G2, Ls1, []). nonvar(G), G = (G1, G2), !, phrase(G1, Ls0, Ls1), phrase(G2, Ls1, []).
phrase(G, Ls0) :-
nonvar(G), G == !, !, Ls0 = [].
phrase(G, Ls0) :- phrase(G, Ls0) :-
call(G, Ls0, []). call(G, Ls0, []).
@@ -17,6 +19,8 @@ phrase(G, Ls0, Ls1) :-
phrase(G, Ls0, Ls2) :- phrase(G, Ls0, Ls2) :-
nonvar(G), G = (G1, G2), !, nonvar(G), G = (G1, G2), !,
phrase(G1, Ls0, Ls1), phrase(G2, Ls1, Ls2). phrase(G1, Ls0, Ls1), phrase(G2, Ls1, Ls2).
phrase(G, Ls0, Ls1) :-
nonvar(G), G == !, !, Ls0 = [], Ls1 = [].
phrase(G, Ls0, Ls1) :- phrase(G, Ls0, Ls1) :-
call(G, Ls0, Ls1). call(G, Ls0, Ls1).

View File

@@ -56,8 +56,8 @@ fn fix_filename(atom_tbl: TabledData<Atom>, filename: &str) -> Result<PathBuf, S
Ok(path) Ok(path)
} }
fn load_module<R: Read>(wam: &mut Machine, name: &str, stream: ParsingStream<R>) fn load_module<R: Read>(wam: &mut Machine, stream: ParsingStream<R>)
-> Result<ClauseName, SessionError> -> Result<Option<ClauseName>, SessionError>
{ {
// follow the operation of compile_user_module, but before // follow the operation of compile_user_module, but before
// compiling, check that a module is declared in the file. if not, // 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 results = compiler.gather_items(wam, stream, &mut indices)?;
let module_name = if let Some(ref module) = &compiler.module { let module_name = if let Some(ref module) = &compiler.module {
module.module_decl.name.clone() Some(module.module_decl.name.clone())
} else { } else {
let module_name = clause_name!(name.to_string(), wam.indices.atom_tbl); None
return Err(SessionError::NoModuleDeclaration(module_name));
}; };
match compile_work_impl(&mut compiler, wam, indices, results) { 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) 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)?; 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)) Err(SessionError::InvalidFileName(filename))
})?; })?;
let file_stem = path.file_stem().unwrap().to_string_lossy(); load_module(wam, parsing_stream(file_handle))
load_module(wam, &file_stem, parsing_stream(file_handle))
} }
pub type PredicateCompileQueue = (Predicate, VecDeque<TopLevel>); pub type PredicateCompileQueue = (Predicate, VecDeque<TopLevel>);
@@ -468,9 +467,13 @@ fn add_non_module_code(
} }
pub(super) 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()) { 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) None => Err(SessionError::ModuleNotFound)
} }
} }
@@ -767,25 +770,35 @@ impl ListingCompiler {
} }
Declaration::UseModule(ModuleSource::File(filename)) => { Declaration::UseModule(ModuleSource::File(filename)) => {
let name = load_module_from_file(wam, filename.as_str())?; 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) => { Declaration::UseQualifiedModule(ModuleSource::File(filename), exports) => {
let name = load_module_from_file(wam, filename.as_str())?; let name = load_module_from_file(wam, filename.as_str())?;
self.use_qualified_module(
name, if let Some(name) = name {
&mut wam.code_repo, self.use_qualified_module(
flags, name,
&exports, &mut wam.code_repo,
&mut wam.indices, flags,
indices, &exports,
) &mut wam.indices,
indices,
)
} else {
Ok(())
}
} }
Declaration::ModuleInitialization(query_terms, queue) => { Declaration::ModuleInitialization(query_terms, queue) => {
self.initialization_goals.0.extend(query_terms.into_iter()); self.initialization_goals.0.extend(query_terms.into_iter());
self.initialization_goals.1.extend(queue.into_iter()); self.initialization_goals.1.extend(queue.into_iter());
Ok(()) Ok(())
} }
Declaration::Dynamic(..) => Ok(()), Declaration::Dynamic(..) => Ok(()),
} }
} }
@@ -886,7 +899,7 @@ fn compile_work_impl(
wam: &mut Machine, wam: &mut Machine,
mut indices: IndexStore, mut indices: IndexStore,
mut results: GatherResult, mut results: GatherResult,
) -> EvalSession { ) -> EvalSession {
let module_code = try_eval_session!(compiler.generate_code( let module_code = try_eval_session!(compiler.generate_code(
results.worker_results, results.worker_results,
wam, wam,
@@ -939,11 +952,11 @@ fn compile_work_impl(
let init_goal_code = try_eval_session!(compiler.generate_init_goal_code( let init_goal_code = try_eval_session!(compiler.generate_init_goal_code(
wam.machine_flags() wam.machine_flags()
)); ));
if init_goal_code.len() > 0 { if init_goal_code.len() > 0 {
wam.run_init_code(init_goal_code); wam.run_init_code(init_goal_code);
} }
EvalSession::EntrySuccess EvalSession::EntrySuccess
} }

View File

@@ -430,22 +430,28 @@ impl Machine {
let load_result = match to_src(name) { let load_result = match to_src(name) {
ModuleSource::Library(name) => ModuleSource::Library(name) =>
if !self.indices.modules.contains_key(&name) { if !self.indices.modules.contains_key(&name) {
load_library(self, name) load_library(self, name).map(Some)
} else { } 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 result = load_result.and_then(|name|
let module = self.indices.take_module(name).unwrap(); if let Some(name) = name {
let module = self.indices.take_module(name).unwrap();
// remove previous exports. // remove previous exports.
self.indices.remove_module(clause_name!("user"), &module); self.indices.remove_module(clause_name!("user"), &module);
self.indices.use_module(&mut self.code_repo, self.machine_st.flags, &module)?; self.indices.use_module(&mut self.code_repo, self.machine_st.flags,
&module)?;
Ok(self.indices.insert_module(module))
}); Ok(self.indices.insert_module(module))
} else {
Ok(())
}
);
self.code_repo.cached_query = cached_query; self.code_repo.cached_query = cached_query;
@@ -471,25 +477,30 @@ impl Machine {
let load_result = match to_src(name) { let load_result = match to_src(name) {
ModuleSource::Library(name) => ModuleSource::Library(name) =>
if !self.indices.modules.contains_key(&name) { if !self.indices.modules.contains_key(&name) {
load_library(self, name) load_library(self, name).map(Some)
} else { } 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 result = load_result.and_then(|name|
let module = self.indices.take_module(name).unwrap(); if let Some(name) = name {
let module = self.indices.take_module(name).unwrap();
// remove previous exports. // remove previous exports.
self.indices.remove_module(clause_name!("user"), &module); self.indices.remove_module(clause_name!("user"), &module);
self.indices.use_qualified_module(&mut self.code_repo, self.indices.use_qualified_module(&mut self.code_repo,
self.machine_st.flags, self.machine_st.flags,
&module, &module,
&exports)?; &exports)?;
Ok(self.indices.insert_module(module)) Ok(self.indices.insert_module(module))
}); } else {
Ok(())
}
);
self.code_repo.cached_query = cached_query; self.code_repo.cached_query = cached_query;