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:
@@ -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),
|
||||||
|
|||||||
@@ -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).
|
||||||
|
|
||||||
|
|||||||
@@ -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,18 +770,28 @@ 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());
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user