merge latest commit
This commit is contained in:
@@ -32,9 +32,9 @@ impl AttrVarInitializer {
|
||||
|
||||
#[inline]
|
||||
pub(super) fn reset(&mut self) {
|
||||
self.attribute_goals.clear();
|
||||
self.attr_var_queue.clear();
|
||||
self.bindings.clear();
|
||||
self.attribute_goals.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -448,7 +448,8 @@ fn add_toplevel_code(wam: &mut Machine, code: Code, indices: IndexStore) {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn add_module_code(wam: &mut Machine, mut module: Module, code: Code, indices: IndexStore) {
|
||||
fn add_module_code(wam: &mut Machine, mut module: Module, code: Code, indices: IndexStore)
|
||||
{
|
||||
module.code_dir.extend(indices.code_dir);
|
||||
module.op_dir.extend(indices.op_dir.into_iter());
|
||||
|
||||
@@ -573,7 +574,7 @@ impl ListingCompiler {
|
||||
submodule: ClauseName,
|
||||
code_repo: &mut CodeRepo,
|
||||
flags: MachineFlags,
|
||||
exports: &Vec<PredicateKey>,
|
||||
exports: &Vec<ModuleExport>,
|
||||
wam_indices: &mut IndexStore,
|
||||
indices: &mut IndexStore,
|
||||
) -> Result<(), SessionError> {
|
||||
@@ -683,7 +684,8 @@ impl ListingCompiler {
|
||||
.or_insert((Predicate::new(), VecDeque::from(vec![])));
|
||||
|
||||
if let Some(ref mut module) = &mut self.module {
|
||||
module.add_module_expansion_record(hook, clause.clone(), queue.clone());
|
||||
module.add_expansion_record(hook, clause.clone(), queue.clone());
|
||||
module.add_local_expansion(hook, clause.clone(), queue.clone());
|
||||
}
|
||||
|
||||
(module_preds.0).0.push(clause);
|
||||
@@ -710,6 +712,24 @@ impl ListingCompiler {
|
||||
(len, queue_len)
|
||||
}
|
||||
|
||||
fn submit_op(
|
||||
&mut self,
|
||||
wam: &Machine,
|
||||
indices: &mut IndexStore,
|
||||
op_decl: &OpDecl,
|
||||
) -> Result<(), SessionError> {
|
||||
let spec = get_desc(
|
||||
op_decl.name(),
|
||||
composite_op!(
|
||||
self.module.is_some(),
|
||||
&wam.indices.op_dir,
|
||||
&mut indices.op_dir
|
||||
),
|
||||
);
|
||||
|
||||
op_decl.submit(self.get_module_name(), spec, &mut indices.op_dir)
|
||||
}
|
||||
|
||||
fn process_decl(
|
||||
&mut self,
|
||||
decl: Declaration,
|
||||
@@ -728,6 +748,7 @@ impl ListingCompiler {
|
||||
.code_repo
|
||||
.compile_hook(hook, flags)
|
||||
.map_err(SessionError::from);
|
||||
|
||||
wam.code_repo.truncate_terms(key, len, queue_len);
|
||||
|
||||
result
|
||||
@@ -736,16 +757,7 @@ impl ListingCompiler {
|
||||
Ok(self.add_non_counted_bt_flag(name, arity))
|
||||
}
|
||||
Declaration::Op(op_decl) => {
|
||||
let spec = get_desc(
|
||||
op_decl.name(),
|
||||
composite_op!(
|
||||
self.module.is_some(),
|
||||
&wam.indices.op_dir,
|
||||
&mut indices.op_dir
|
||||
),
|
||||
);
|
||||
|
||||
op_decl.submit(self.get_module_name(), spec, &mut indices.op_dir)
|
||||
self.submit_op(wam, indices, &op_decl)
|
||||
}
|
||||
Declaration::UseModule(ModuleSource::Library(name)) => {
|
||||
let name = if !wam.indices.modules.contains_key(&name) {
|
||||
@@ -777,6 +789,12 @@ impl ListingCompiler {
|
||||
let module_name = module_decl.name.clone();
|
||||
let atom_tbl = TabledData::new(module_name.to_rc());
|
||||
|
||||
for export in module_decl.exports.iter() {
|
||||
if let ModuleExport::OpDecl(ref op_decl) = export {
|
||||
self.submit_op(wam, indices, op_decl)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(self.module = Some(Module::new(module_decl, atom_tbl)))
|
||||
} else {
|
||||
Err(SessionError::from(ParserError::InvalidModuleDecl))
|
||||
@@ -824,8 +842,9 @@ impl ListingCompiler {
|
||||
.entry((name.clone(), arity))
|
||||
.or_insert(vec![]);
|
||||
|
||||
indices.code_dir.insert((name.clone(), arity),
|
||||
CodeIndex::dynamic_undefined(self.get_module_name()));
|
||||
indices.code_dir
|
||||
.entry((name.clone(), arity))
|
||||
.or_insert(CodeIndex::dynamic_undefined(self.get_module_name()));
|
||||
}
|
||||
&Declaration::Hook(hook, _, ref queue) if self.module.is_none() => worker
|
||||
.term_stream
|
||||
@@ -917,6 +936,16 @@ fn compile_work_impl(
|
||||
mut indices: IndexStore,
|
||||
mut results: GatherResult,
|
||||
) -> Result<(), SessionError> {
|
||||
if let Some(ref mut module) = &mut compiler.module {
|
||||
// compile the module-level goal and term expansions and store
|
||||
// their locations to the module's code_dir.
|
||||
let decls = module.take_local_expansions();
|
||||
|
||||
if !decls.is_empty() {
|
||||
results.worker_results.extend(decls.into_iter());
|
||||
}
|
||||
}
|
||||
|
||||
let module_code = compiler.generate_code(
|
||||
results.worker_results,
|
||||
wam,
|
||||
@@ -946,8 +975,9 @@ fn compile_work_impl(
|
||||
if let Some(mut module) = compiler.module.take() {
|
||||
if module.is_impromptu_module {
|
||||
module.module_decl.exports = indices.code_dir.keys().cloned()
|
||||
.filter(|(name, _)| name.owning_module().as_str() != "builtins")
|
||||
.collect();
|
||||
.filter(|(name, _)| name.owning_module().as_str() != "builtins")
|
||||
.map(ModuleExport::PredicateKey)
|
||||
.collect();
|
||||
}
|
||||
|
||||
let mut clause_code_generator =
|
||||
@@ -968,7 +998,7 @@ fn compile_work_impl(
|
||||
|
||||
wam.indices.use_module(&mut wam.code_repo, wam.machine_st.flags, &module)?;
|
||||
wam.indices.insert_module(module);
|
||||
} else {
|
||||
} else {
|
||||
add_module_code(wam, module, module_code, indices);
|
||||
}
|
||||
|
||||
|
||||
@@ -863,13 +863,7 @@ pub(crate) trait CallPolicy: Any {
|
||||
if let Some(idx) = indices.get_code_index((name.clone(), arity), module) {
|
||||
self.context_call(machine_st, name, arity, idx, indices)?;
|
||||
} else {
|
||||
let h = machine_st.heap.h;
|
||||
let stub = MachineError::functor_stub(clause_name!("call"), arity + 1);
|
||||
let key = ExistenceError::Procedure(name, arity);
|
||||
|
||||
return Err(
|
||||
machine_st.error_form(MachineError::existence_error(h, key), stub)
|
||||
);
|
||||
try_in_situ(machine_st, name, arity, indices, machine_st.last_call)?;
|
||||
}
|
||||
}
|
||||
ClauseType::Hook(_) | ClauseType::System(_) => {
|
||||
|
||||
@@ -3051,14 +3051,15 @@ impl MachineState {
|
||||
| (
|
||||
HeapCellValue::Addr(v1 @ Addr::StackCell(..)),
|
||||
HeapCellValue::Addr(v2 @ Addr::HeapCell(_)),
|
||||
) => match (var_pairs.get(&v1).cloned(), var_pairs.get(&v2).cloned()) {
|
||||
(Some(ref v2_p), Some(ref v1_p)) if *v1_p == v1 && *v2_p == v2 => continue,
|
||||
(Some(_), _) | (_, Some(_)) => return true,
|
||||
(None, None) => {
|
||||
var_pairs.insert(v1.clone(), v2.clone());
|
||||
var_pairs.insert(v2, v1);
|
||||
}
|
||||
},
|
||||
) =>
|
||||
match (var_pairs.get(&v1).cloned(), var_pairs.get(&v2).cloned()) {
|
||||
(Some(ref v2_p), Some(ref v1_p)) if *v1_p == v1 && *v2_p == v2 => continue,
|
||||
(Some(_), _) | (_, Some(_)) => return true,
|
||||
(None, None) => {
|
||||
var_pairs.insert(v1.clone(), v2.clone());
|
||||
var_pairs.insert(v2, v1);
|
||||
}
|
||||
},
|
||||
(HeapCellValue::Addr(a1), HeapCellValue::Addr(a2)) => {
|
||||
if a1 != a2 {
|
||||
return true;
|
||||
@@ -3079,6 +3080,7 @@ impl MachineState {
|
||||
match v {
|
||||
HeapCellValue::Addr(Addr::HeapCell(..)) => return true,
|
||||
HeapCellValue::Addr(Addr::StackCell(..)) => return true,
|
||||
HeapCellValue::Addr(Addr::AttrVar(..)) => return true,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ use crate::prolog::machine::machine_errors::*;
|
||||
use crate::prolog::machine::machine_indices::*;
|
||||
use crate::prolog::machine::machine_state::*;
|
||||
use crate::prolog::machine::modules::*;
|
||||
use crate::prolog::machine::toplevel::*;
|
||||
use crate::prolog::read::PrologStream;
|
||||
|
||||
use indexmap::IndexMap;
|
||||
@@ -105,13 +106,13 @@ impl SubModuleUser for IndexStore {
|
||||
&mut self.op_dir
|
||||
}
|
||||
|
||||
fn get_code_index(&self, key: PredicateKey, module: ClauseName) -> Option<CodeIndex> {
|
||||
match module.as_str() {
|
||||
fn get_code_index(&self, key: PredicateKey, module_name: ClauseName) -> Option<CodeIndex> {
|
||||
match module_name.as_str() {
|
||||
"user" | "builtin" => self.code_dir.get(&key).cloned(),
|
||||
_ => self
|
||||
.modules
|
||||
.get(&module)
|
||||
.and_then(|ref module| module.code_dir.get(&key).cloned().map(CodeIndex::from)),
|
||||
.modules
|
||||
.get(&module_name)
|
||||
.and_then(|ref module| module.code_dir.get(&key).cloned().map(CodeIndex::from))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +131,7 @@ impl SubModuleUser for IndexStore {
|
||||
return;
|
||||
}
|
||||
|
||||
self.code_dir.insert((name, arity), idx);
|
||||
self.code_dir.insert((name.clone(), arity), idx.clone());
|
||||
}
|
||||
|
||||
fn use_qualified_module(
|
||||
@@ -138,7 +139,7 @@ impl SubModuleUser for IndexStore {
|
||||
code_repo: &mut CodeRepo,
|
||||
flags: MachineFlags,
|
||||
submodule: &Module,
|
||||
exports: &Vec<PredicateKey>,
|
||||
exports: &Vec<ModuleExport>,
|
||||
) -> Result<(), SessionError> {
|
||||
use_qualified_module(self, submodule, exports)?;
|
||||
submodule
|
||||
@@ -239,7 +240,7 @@ impl Machine {
|
||||
|
||||
pub fn run_init_code(&mut self, code: Code) -> bool {
|
||||
let old_machine_st = self.sink_to_snapshot();
|
||||
self.machine_st.reset();
|
||||
self.machine_st.reset();
|
||||
|
||||
self.code_repo.cached_query = code;
|
||||
self.run_query();
|
||||
@@ -399,30 +400,64 @@ impl Machine {
|
||||
return;
|
||||
}
|
||||
|
||||
fn extract_predicate_indicator_list(&mut self) -> Vec<PredicateKey>
|
||||
fn extract_module_export_list(&mut self) -> Result<Vec<ModuleExport>, ParserError>
|
||||
{
|
||||
let export_list = self.machine_st[temp_v!(2)].clone();
|
||||
let mut export_list = self.machine_st.store(self.machine_st.deref(export_list));
|
||||
let mut export_list = self.machine_st[temp_v!(2)].clone();
|
||||
let mut exports = vec![];
|
||||
|
||||
while let Addr::Lis(l) = export_list {
|
||||
while let Addr::Lis(l) = self.machine_st.store(self.machine_st.deref(export_list)) {
|
||||
match &self.machine_st.heap[l] {
|
||||
&HeapCellValue::Addr(Addr::Str(s)) => {
|
||||
let name = match &self.machine_st.heap[s+1] {
|
||||
&HeapCellValue::Addr(Addr::Con(Constant::Atom(ref name, _))) =>
|
||||
name.clone(),
|
||||
_ =>
|
||||
unreachable!()
|
||||
};
|
||||
match &self.machine_st.heap[s] {
|
||||
HeapCellValue::NamedStr(arity, ref name, _)
|
||||
if *arity == 2 && name.as_str() == "/" => {
|
||||
let name = match &self.machine_st.heap[s+1] {
|
||||
&HeapCellValue::Addr(Addr::Con(Constant::Atom(ref name, _))) =>
|
||||
name.clone(),
|
||||
_ =>
|
||||
unreachable!()
|
||||
};
|
||||
|
||||
let arity = match &self.machine_st.heap[s+2] {
|
||||
&HeapCellValue::Addr(Addr::Con(Constant::Integer(ref arity))) =>
|
||||
arity.to_usize().unwrap(),
|
||||
_ =>
|
||||
unreachable!()
|
||||
};
|
||||
let arity = match &self.machine_st.heap[s+2] {
|
||||
&HeapCellValue::Addr(Addr::Con(Constant::Integer(ref arity))) =>
|
||||
arity.to_usize().unwrap(),
|
||||
_ =>
|
||||
unreachable!()
|
||||
};
|
||||
|
||||
exports.push((name, arity));
|
||||
exports.push(ModuleExport::PredicateKey((name, arity)));
|
||||
}
|
||||
HeapCellValue::NamedStr(arity, ref name, _)
|
||||
if *arity == 3 && name.as_str() == "op" => {
|
||||
let name = match &self.machine_st.heap[s+3] {
|
||||
&HeapCellValue::Addr(Addr::Con(Constant::Atom(ref name, _))) =>
|
||||
name.clone(),
|
||||
_ =>
|
||||
unreachable!()
|
||||
};
|
||||
|
||||
let spec = match &self.machine_st.heap[s+2] {
|
||||
&HeapCellValue::Addr(Addr::Con(Constant::Atom(ref name, _))) =>
|
||||
name.clone(),
|
||||
_ =>
|
||||
unreachable!()
|
||||
};
|
||||
|
||||
let prec = match &self.machine_st.heap[s+1] {
|
||||
&HeapCellValue::Addr(Addr::Con(Constant::Integer(ref arity))) =>
|
||||
arity.to_usize().unwrap(),
|
||||
_ =>
|
||||
unreachable!()
|
||||
};
|
||||
|
||||
exports.push(ModuleExport::OpDecl(to_op_decl(
|
||||
prec,
|
||||
spec.as_str(),
|
||||
name,
|
||||
)?));
|
||||
}
|
||||
_ => unreachable!()
|
||||
}
|
||||
}
|
||||
_ => unreachable!()
|
||||
}
|
||||
@@ -430,7 +465,7 @@ impl Machine {
|
||||
export_list = self.machine_st.heap[l+1].as_addr(l+1);
|
||||
}
|
||||
|
||||
exports
|
||||
Ok(exports)
|
||||
}
|
||||
|
||||
fn use_module<ToSource>(&mut self, to_src: ToSource)
|
||||
@@ -488,7 +523,13 @@ impl Machine {
|
||||
_ => unreachable!()
|
||||
};
|
||||
|
||||
let exports = self.extract_predicate_indicator_list();
|
||||
let exports = match self.extract_module_export_list() {
|
||||
Ok(exports) => exports,
|
||||
Err(e) => {
|
||||
self.throw_session_error(SessionError::from(e), (clause_name!("use_module"), 2));
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let load_result = match to_src(name) {
|
||||
ModuleSource::Library(name) =>
|
||||
@@ -520,7 +561,7 @@ impl Machine {
|
||||
self.code_repo.cached_query = cached_query;
|
||||
|
||||
if let Err(e) = result {
|
||||
self.throw_session_error(e, (clause_name!("use_module"), 1));
|
||||
self.throw_session_error(e, (clause_name!("use_module"), 2));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -551,7 +592,7 @@ impl Machine {
|
||||
|
||||
fn sink_to_snapshot(&mut self) -> MachineState {
|
||||
let mut snapshot = MachineState::with_capacity(0);
|
||||
|
||||
|
||||
snapshot.hb = self.machine_st.hb;
|
||||
snapshot.e = self.machine_st.e;
|
||||
snapshot.b = self.machine_st.b;
|
||||
@@ -576,7 +617,7 @@ impl Machine {
|
||||
snapshot
|
||||
}
|
||||
|
||||
fn absorb_snapshot(&mut self, mut snapshot: MachineState) {
|
||||
fn absorb_snapshot(&mut self, mut snapshot: MachineState) {
|
||||
self.machine_st.hb = snapshot.hb;
|
||||
self.machine_st.e = snapshot.e;
|
||||
self.machine_st.b = snapshot.b;
|
||||
@@ -623,37 +664,19 @@ impl Machine {
|
||||
// so hold onto it locally and restore it after the compiler has finished.
|
||||
self.machine_st.fail = false;
|
||||
let cached_query = mem::replace(&mut self.code_repo.cached_query, vec![]);
|
||||
|
||||
self.dynamic_transaction(trans_type, p);
|
||||
self.code_repo.cached_query = cached_query;
|
||||
|
||||
if let CodePtr::Local(LocalCodePtr::TopLevel(_, 0)) = self.machine_st.p {
|
||||
self.code_repo.cached_query = cached_query;
|
||||
break;
|
||||
}
|
||||
|
||||
self.code_repo.cached_query = cached_query;
|
||||
}
|
||||
_ =>
|
||||
break
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub fn test_heap_view<Outputter>(&self, mut output: Outputter) -> Outputter
|
||||
where
|
||||
Outputter: HCValueOutputter,
|
||||
{
|
||||
for (var, addr) in self.machine_st.heap_locs.iter() {
|
||||
output = self.machine_st.print_var_eq(
|
||||
var.clone(),
|
||||
addr.clone(),
|
||||
&self.indices.op_dir,
|
||||
output,
|
||||
);
|
||||
}
|
||||
|
||||
output
|
||||
}
|
||||
}
|
||||
|
||||
impl MachineState {
|
||||
|
||||
@@ -7,6 +7,7 @@ use crate::prolog::machine::machine_errors::*;
|
||||
use crate::prolog::machine::machine_indices::*;
|
||||
|
||||
use std::collections::VecDeque;
|
||||
use std::mem;
|
||||
|
||||
// Module's and related types are defined in forms.
|
||||
impl Module {
|
||||
@@ -19,6 +20,8 @@ impl Module {
|
||||
user_goal_expansions: (Predicate::new(), VecDeque::from(vec![])),
|
||||
term_expansions: (Predicate::new(), VecDeque::from(vec![])),
|
||||
goal_expansions: (Predicate::new(), VecDeque::from(vec![])),
|
||||
local_term_expansions: (Predicate::new(), VecDeque::from(vec![])),
|
||||
local_goal_expansions: (Predicate::new(), VecDeque::from(vec![])),
|
||||
code_dir: CodeDir::new(),
|
||||
op_dir: default_op_dir(),
|
||||
inserted_expansions: false,
|
||||
@@ -61,7 +64,7 @@ impl Module {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn add_module_expansion_record(
|
||||
pub fn add_expansion_record(
|
||||
&mut self,
|
||||
hook: CompileTimeHook,
|
||||
clause: PredicateClause,
|
||||
@@ -78,6 +81,45 @@ impl Module {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_local_expansion(
|
||||
&mut self,
|
||||
hook: CompileTimeHook,
|
||||
clause: PredicateClause,
|
||||
queue: VecDeque<TopLevel>,
|
||||
) {
|
||||
match hook {
|
||||
CompileTimeHook::TermExpansion => {
|
||||
(self.local_term_expansions.0).0.push(clause);
|
||||
self.local_term_expansions.1.extend(queue.into_iter());
|
||||
}
|
||||
CompileTimeHook::GoalExpansion => {
|
||||
(self.local_goal_expansions.0).0.push(clause);
|
||||
self.local_goal_expansions.1.extend(queue.into_iter());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn take_local_expansions(&mut self) -> Vec<(Predicate, VecDeque<TopLevel>)>
|
||||
{
|
||||
let term_expansions =
|
||||
mem::replace(&mut self.local_term_expansions, (Predicate::new(), VecDeque::new()));
|
||||
let goal_expansions =
|
||||
mem::replace(&mut self.local_goal_expansions, (Predicate::new(), VecDeque::new()));
|
||||
|
||||
let mut result = vec![];
|
||||
|
||||
if !(term_expansions.0).0.is_empty() {
|
||||
result.push(term_expansions);
|
||||
}
|
||||
|
||||
if !(goal_expansions.0).0.is_empty() {
|
||||
result.push(goal_expansions);
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
pub trait SubModuleUser {
|
||||
@@ -95,64 +137,55 @@ pub trait SubModuleUser {
|
||||
}
|
||||
|
||||
fn remove_module(&mut self, mod_name: ClauseName, module: &Module) {
|
||||
for (name, arity) in module.module_decl.exports.iter().cloned() {
|
||||
let name = name.defrock_brackets();
|
||||
for export in module.module_decl.exports.iter().cloned() {
|
||||
match export {
|
||||
ModuleExport::PredicateKey((name, arity)) => {
|
||||
let name = name.defrock_brackets();
|
||||
|
||||
match self.get_code_index((name.clone(), arity), mod_name.clone()) {
|
||||
Some(CodeIndex(ref code_idx)) => {
|
||||
if &code_idx.borrow().1 != &module.module_decl.name {
|
||||
continue;
|
||||
}
|
||||
|
||||
self.remove_code_index((name.clone(), arity));
|
||||
|
||||
// remove or respecify ops.
|
||||
if arity == 2 {
|
||||
if let Some(mod_name) = self.get_op_module_name(name.clone(), Fixity::In) {
|
||||
if mod_name == module.module_decl.name {
|
||||
self.op_dir().remove(&(name.clone(), Fixity::In));
|
||||
match self.get_code_index((name.clone(), arity), mod_name.clone()) {
|
||||
Some(CodeIndex(ref code_idx)) => {
|
||||
if &code_idx.borrow().1 != &module.module_decl.name {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} else if arity == 1 {
|
||||
if let Some(mod_name) = self.get_op_module_name(name.clone(), Fixity::Pre) {
|
||||
if mod_name == module.module_decl.name {
|
||||
self.op_dir().remove(&(name.clone(), Fixity::Pre));
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(mod_name) = self.get_op_module_name(name.clone(), Fixity::Post)
|
||||
{
|
||||
if mod_name == module.module_decl.name {
|
||||
self.op_dir().remove(&(name.clone(), Fixity::Post));
|
||||
self.remove_code_index((name.clone(), arity));
|
||||
|
||||
// remove or respecify ops.
|
||||
if arity == 2 {
|
||||
if let Some(mod_name) = self.get_op_module_name(name.clone(), Fixity::In) {
|
||||
if mod_name == module.module_decl.name {
|
||||
self.op_dir().remove(&(name.clone(), Fixity::In));
|
||||
}
|
||||
}
|
||||
} else if arity == 1 {
|
||||
if let Some(mod_name) = self.get_op_module_name(name.clone(), Fixity::Pre) {
|
||||
if mod_name == module.module_decl.name {
|
||||
self.op_dir().remove(&(name.clone(), Fixity::Pre));
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(mod_name) = self.get_op_module_name(name.clone(), Fixity::Post)
|
||||
{
|
||||
if mod_name == module.module_decl.name {
|
||||
self.op_dir().remove(&(name.clone(), Fixity::Post));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
},
|
||||
ModuleExport::OpDecl(op_decl) => {
|
||||
let op_dir = self.op_dir();
|
||||
op_dir.remove(&(op_decl.name(), op_decl.fixity()));
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// returns true on successful import.
|
||||
fn import_decl(&mut self, name: ClauseName, arity: usize, submodule: &Module) -> bool {
|
||||
let name = name.defrock_brackets();
|
||||
let mut found_op = false;
|
||||
|
||||
{
|
||||
let mut insert_op_dir = |fix| {
|
||||
if let Some(op_data) = submodule.op_dir.get(&(name.clone(), fix)) {
|
||||
self.op_dir().insert((name.clone(), fix), op_data.clone());
|
||||
found_op = true;
|
||||
}
|
||||
};
|
||||
|
||||
if arity == 1 {
|
||||
insert_op_dir(Fixity::Pre);
|
||||
insert_op_dir(Fixity::Post);
|
||||
} else if arity == 2 {
|
||||
insert_op_dir(Fixity::In);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(code_data) = submodule.code_dir.get(&(name.clone(), arity)) {
|
||||
let name = name.with_table(submodule.atom_tbl.clone());
|
||||
@@ -163,7 +196,7 @@ pub trait SubModuleUser {
|
||||
self.insert_dir_entry(name, arity, code_data.clone());
|
||||
true
|
||||
} else {
|
||||
found_op || submodule.is_impromptu_module
|
||||
submodule.is_impromptu_module
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,30 +205,58 @@ pub trait SubModuleUser {
|
||||
_: &mut CodeRepo,
|
||||
_: MachineFlags,
|
||||
_: &Module,
|
||||
_: &Vec<PredicateKey>,
|
||||
_: &Vec<ModuleExport>,
|
||||
) -> Result<(), SessionError>;
|
||||
|
||||
fn use_module(
|
||||
&mut self,
|
||||
_: &mut CodeRepo,
|
||||
_: MachineFlags,
|
||||
_: &Module
|
||||
) -> Result<(), SessionError>;
|
||||
fn use_module(&mut self, _: &mut CodeRepo, _: MachineFlags, _: &Module) -> Result<(), SessionError>;
|
||||
}
|
||||
|
||||
pub fn use_qualified_module<User>(
|
||||
user: &mut User,
|
||||
submodule: &Module,
|
||||
exports: &Vec<PredicateKey>,
|
||||
exports: &Vec<ModuleExport>,
|
||||
) -> Result<(), SessionError>
|
||||
where
|
||||
User: SubModuleUser,
|
||||
{
|
||||
for (name, arity) in exports.iter().cloned() {
|
||||
if !submodule
|
||||
.module_decl
|
||||
.exports
|
||||
.contains(&(name.clone(), arity))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for export in exports.iter().cloned() {
|
||||
match export {
|
||||
ModuleExport::PredicateKey((name, arity)) => {
|
||||
if !submodule
|
||||
.module_decl
|
||||
.exports
|
||||
.contains(&ModuleExport::PredicateKey((name.clone(), arity)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if !user.import_decl(name, arity, submodule) {
|
||||
return Err(SessionError::ModuleDoesNotContainExport);
|
||||
if !user.import_decl(name, arity, submodule) {
|
||||
return Err(SessionError::ModuleDoesNotContainExport);
|
||||
}
|
||||
},
|
||||
ModuleExport::OpDecl(op_decl) => {
|
||||
if !submodule
|
||||
.module_decl
|
||||
.exports
|
||||
.contains(&ModuleExport::OpDecl(op_decl.clone()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
let op_dir = user.op_dir();
|
||||
let prec = op_decl.0;
|
||||
|
||||
op_decl.insert_into_op_dir(
|
||||
submodule.module_decl.name.clone(),
|
||||
op_dir,
|
||||
prec,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,9 +267,23 @@ pub fn use_module<User: SubModuleUser>(
|
||||
user: &mut User,
|
||||
submodule: &Module,
|
||||
) -> Result<(), SessionError> {
|
||||
for (name, arity) in submodule.module_decl.exports.iter().cloned() {
|
||||
if !user.import_decl(name, arity, submodule) {
|
||||
return Err(SessionError::ModuleDoesNotContainExport);
|
||||
for export in submodule.module_decl.exports.iter().cloned() {
|
||||
match export {
|
||||
ModuleExport::PredicateKey((name, arity)) => {
|
||||
if !user.import_decl(name, arity, submodule) {
|
||||
return Err(SessionError::ModuleDoesNotContainExport);
|
||||
}
|
||||
}
|
||||
ModuleExport::OpDecl(op_decl) => {
|
||||
let op_dir = user.op_dir();
|
||||
let prec = op_decl.0;
|
||||
|
||||
op_decl.insert_into_op_dir(
|
||||
submodule.module_decl.name.clone(),
|
||||
op_dir,
|
||||
prec,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,7 +316,7 @@ impl SubModuleUser for Module {
|
||||
_: &mut CodeRepo,
|
||||
_: MachineFlags,
|
||||
submodule: &Module,
|
||||
exports: &Vec<PredicateKey>,
|
||||
exports: &Vec<ModuleExport>,
|
||||
) -> Result<(), SessionError> {
|
||||
use_qualified_module(self, submodule, exports)?;
|
||||
|
||||
@@ -283,7 +358,7 @@ impl SubModuleUser for Module {
|
||||
self.user_goal_expansions
|
||||
.1
|
||||
.extend(submodule.goal_expansions.1.iter().cloned());
|
||||
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1099,27 +1099,31 @@ impl MachineState {
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
&SystemClauseType::DynamicModuleResolution => {
|
||||
let module_name = self.store(self.deref(self[temp_v!(1)].clone()));
|
||||
&SystemClauseType::DynamicModuleResolution(narity) => {
|
||||
let module_name = self.store(self.deref(self[temp_v!(1 + narity)].clone()));
|
||||
|
||||
if let Addr::Con(Constant::Atom(module_name, _)) = module_name {
|
||||
match self.store(self.deref(self[temp_v!(2)].clone())) {
|
||||
match self.store(self.deref(self[temp_v!(2 + narity)].clone())) {
|
||||
Addr::Str(a) => {
|
||||
if let HeapCellValue::NamedStr(arity, name, _) = self.heap[a].clone() {
|
||||
for i in 1..arity + 1 {
|
||||
for i in (arity + 1 .. arity + narity + 1).rev() {
|
||||
self.registers[i] = self.registers[i - arity].clone();
|
||||
}
|
||||
|
||||
for i in 1 .. arity + 1 {
|
||||
self.registers[i] = self.heap[a + i].as_addr(a + i);
|
||||
}
|
||||
|
||||
return self.module_lookup(
|
||||
indices,
|
||||
(name, arity),
|
||||
(name, arity + narity),
|
||||
module_name,
|
||||
true,
|
||||
);
|
||||
}
|
||||
}
|
||||
Addr::Con(Constant::Atom(name, _)) => {
|
||||
return self.module_lookup(indices, (name, 0), module_name, true)
|
||||
Addr::Con(Constant::Atom(name, _)) => {
|
||||
return self.module_lookup(indices, (name, narity), module_name, true)
|
||||
}
|
||||
addr => {
|
||||
let stub = MachineError::functor_stub(clause_name!("(:)"), 2);
|
||||
@@ -1309,11 +1313,7 @@ impl MachineState {
|
||||
let result = {
|
||||
let mut rand = RANDOM_STATE.borrow_mut();
|
||||
|
||||
if rand.bits(1) == 0 {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
rand.bits(1) == 0
|
||||
};
|
||||
|
||||
self.fail = result;
|
||||
@@ -1689,6 +1689,9 @@ impl MachineState {
|
||||
}
|
||||
};
|
||||
},
|
||||
&SystemClauseType::ResetAttrVarState => {
|
||||
self.attr_var_init.reset();
|
||||
}
|
||||
&SystemClauseType::RemoveCallPolicyCheck => {
|
||||
let restore_default = match call_policy.downcast_mut::<CWILCallPolicy>().ok() {
|
||||
Some(call_policy) => {
|
||||
|
||||
@@ -161,7 +161,7 @@ impl<'a, R: Read> TermStream<'a, R> {
|
||||
pub fn col_num(&self) -> usize {
|
||||
self.parser.col_num()
|
||||
}
|
||||
|
||||
|
||||
#[inline]
|
||||
pub fn update_expansion_lens(&mut self) {
|
||||
let te_key = (clause_name!("term_expansion"), 2);
|
||||
@@ -257,7 +257,6 @@ impl<'a, R: Read> TermStream<'a, R> {
|
||||
self.enqueue_term(term)?
|
||||
}
|
||||
None => {
|
||||
let term = self.run_goal_expanders(&mut machine_st, op_dir, term)?;
|
||||
return Ok(term);
|
||||
}
|
||||
};
|
||||
@@ -267,7 +266,7 @@ impl<'a, R: Read> TermStream<'a, R> {
|
||||
|
||||
let line_num = self.line_num();
|
||||
let col_num = self.col_num();
|
||||
|
||||
|
||||
let term = self.parser.read_term(composite_op!(
|
||||
self.in_module,
|
||||
&self.wam.indices.op_dir,
|
||||
@@ -281,40 +280,6 @@ impl<'a, R: Read> TermStream<'a, R> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn run_goal_expanders(
|
||||
&mut self,
|
||||
machine_st: &mut MachineState,
|
||||
op_dir: &OpDir,
|
||||
term: Term,
|
||||
) -> Result<Term, ParserError> {
|
||||
match term {
|
||||
Term::Clause(cell, name, mut terms, arity) => {
|
||||
let mut new_terms = {
|
||||
let old_terms = match (name.as_str(), terms.len()) {
|
||||
(":-", 2) => {
|
||||
let comma_term = *terms.pop().unwrap();
|
||||
unfold_by_str(comma_term, ",")
|
||||
}
|
||||
("?-", 1) => unfold_by_str(*terms.pop().unwrap(), ","),
|
||||
_ => return Ok(Term::Clause(cell, name, terms, arity)),
|
||||
};
|
||||
|
||||
self.expand_goals(machine_st, op_dir, VecDeque::from(old_terms))?
|
||||
};
|
||||
|
||||
let initial_term = new_terms.pop().unwrap();
|
||||
terms.push(Box::new(fold_by_str(
|
||||
new_terms.into_iter(),
|
||||
initial_term,
|
||||
clause_name!(","),
|
||||
)));
|
||||
|
||||
Ok(Term::Clause(cell, name, terms, arity))
|
||||
}
|
||||
_ => Ok(term),
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn expand_goals(
|
||||
&mut self,
|
||||
@@ -324,7 +289,7 @@ impl<'a, R: Read> TermStream<'a, R> {
|
||||
) -> Result<Vec<Term>, ParserError> {
|
||||
let mut results = vec![];
|
||||
|
||||
while let Some(term) = terms.pop_front() {
|
||||
while let Some(term) = terms.pop_front() {
|
||||
match machine_st.try_expand_term(self.wam, &term, CompileTimeHook::GoalExpansion) {
|
||||
Some(term_string) => {
|
||||
let term = self.parse_expansion_output(term_string.as_str(), op_dir)?;
|
||||
@@ -374,6 +339,15 @@ impl MachineState {
|
||||
output
|
||||
}
|
||||
|
||||
// reset the machine, but keep the heap contents as they were.
|
||||
// this prevents clashes between underscored variable names
|
||||
// in the same query.
|
||||
fn reset_with_heap_preservation(&mut self) {
|
||||
let heap = self.heap.take();
|
||||
self.reset();
|
||||
self.heap = heap;
|
||||
}
|
||||
|
||||
fn try_expand_term(
|
||||
&mut self,
|
||||
wam: &mut Machine,
|
||||
@@ -382,14 +356,14 @@ impl MachineState {
|
||||
) -> Option<String> {
|
||||
let term_write_result = write_term_to_heap(term, self);
|
||||
let h = self.heap.h;
|
||||
|
||||
|
||||
self[temp_v!(1)] = Addr::HeapCell(term_write_result.heap_loc);
|
||||
self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h)));
|
||||
self[temp_v!(2)] = Addr::HeapCell(h);
|
||||
|
||||
let code = vec![call_clause!(ClauseType::Hook(hook), 2, 0, true)];
|
||||
wam.code_repo.cached_query = code;
|
||||
|
||||
|
||||
self.query_stepper(
|
||||
&mut wam.indices,
|
||||
&mut wam.policies,
|
||||
@@ -398,7 +372,7 @@ impl MachineState {
|
||||
);
|
||||
|
||||
if self.fail {
|
||||
self.reset();
|
||||
self.reset_with_heap_preservation();
|
||||
None
|
||||
} else {
|
||||
let TermWriteResult { var_dict, .. } = term_write_result;
|
||||
@@ -406,7 +380,7 @@ impl MachineState {
|
||||
self.heap_locs = var_dict;
|
||||
let output = self.print_with_locs(Addr::HeapCell(h), &wam.indices.op_dir);
|
||||
|
||||
self.reset();
|
||||
self.reset_with_heap_preservation();
|
||||
Some(output.result())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,11 +81,11 @@ impl<'a, 'b, 'c, R: Read> CompositeIndices<'a, 'b, 'c, R> {
|
||||
};
|
||||
|
||||
if let Some(idx) = idx_opt {
|
||||
self.local_code_dir().insert((name, arity), idx.clone());
|
||||
self.local_code_dir().insert((name.clone(), arity), idx.clone());
|
||||
idx
|
||||
} else {
|
||||
let idx = CodeIndex::default();
|
||||
self.local_code_dir().insert((name, arity), idx.clone());
|
||||
self.local_code_dir().insert((name.clone(), arity), idx.clone());
|
||||
idx
|
||||
}
|
||||
}
|
||||
@@ -196,13 +196,13 @@ fn setup_op_decl(
|
||||
to_op_decl(prec, spec.as_str(), name)
|
||||
}
|
||||
|
||||
fn setup_predicate_indicator(mut term: Term) -> Result<PredicateKey, ParserError> {
|
||||
fn setup_predicate_indicator(term: &mut Term) -> Result<PredicateKey, ParserError> {
|
||||
match term {
|
||||
Term::Clause(_, ref name, ref mut terms, Some(_))
|
||||
if name.as_str() == "/" && terms.len() == 2 =>
|
||||
{
|
||||
let arity = *terms.pop().unwrap();
|
||||
let name = *terms.pop().unwrap();
|
||||
let name = *terms.pop().unwrap();
|
||||
|
||||
let arity = arity
|
||||
.to_constant()
|
||||
@@ -210,7 +210,7 @@ fn setup_predicate_indicator(mut term: Term) -> Result<PredicateKey, ParserError
|
||||
.and_then(|n| n.to_usize())
|
||||
.ok_or(ParserError::InvalidModuleExport)?;
|
||||
|
||||
let name = name
|
||||
let name = name
|
||||
.to_constant()
|
||||
.and_then(|c| c.to_atom())
|
||||
.ok_or(ParserError::InvalidModuleExport)?;
|
||||
@@ -221,7 +221,32 @@ fn setup_predicate_indicator(mut term: Term) -> Result<PredicateKey, ParserError
|
||||
}
|
||||
}
|
||||
|
||||
fn setup_module_decl(mut terms: Vec<Box<Term>>) -> Result<ModuleDecl, ParserError> {
|
||||
fn setup_module_export(
|
||||
mut term: Term,
|
||||
atom_tbl: TabledData<Atom>,
|
||||
) -> Result<ModuleExport, ParserError> {
|
||||
setup_predicate_indicator(&mut term)
|
||||
.map(ModuleExport::PredicateKey)
|
||||
.or_else(|_| {
|
||||
if let Term::Clause(_, name, terms, _) = term {
|
||||
if terms.len() == 3 && name.as_str() == "op" {
|
||||
Ok(ModuleExport::OpDecl(setup_op_decl(
|
||||
terms,
|
||||
atom_tbl
|
||||
)?))
|
||||
} else {
|
||||
Err(ParserError::InvalidModuleDecl)
|
||||
}
|
||||
} else {
|
||||
Err(ParserError::InvalidModuleDecl)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn setup_module_decl(
|
||||
mut terms: Vec<Box<Term>>,
|
||||
atom_tbl: TabledData<Atom>,
|
||||
) -> Result<ModuleDecl, ParserError> {
|
||||
let mut export_list = *terms.pop().unwrap();
|
||||
let name = terms
|
||||
.pop()
|
||||
@@ -230,10 +255,12 @@ fn setup_module_decl(mut terms: Vec<Box<Term>>) -> Result<ModuleDecl, ParserErro
|
||||
.and_then(|c| c.to_atom())
|
||||
.ok_or(ParserError::InvalidModuleDecl)?;
|
||||
|
||||
let mut exports = Vec::new();
|
||||
let mut exports = vec![];
|
||||
|
||||
while let Term::Cons(_, t1, t2) = export_list {
|
||||
exports.push(setup_predicate_indicator(*t1)?);
|
||||
let module_export = setup_module_export(*t1, atom_tbl.clone())?;
|
||||
|
||||
exports.push(module_export);
|
||||
export_list = *t2;
|
||||
}
|
||||
|
||||
@@ -257,14 +284,18 @@ fn setup_use_module_decl(mut terms: Vec<Box<Term>>) -> Result<ModuleSource, Pars
|
||||
.map(|c| ModuleSource::Library(c))
|
||||
.ok_or(ParserError::InvalidUseModuleDecl)
|
||||
}
|
||||
Term::Constant(_, Constant::Atom(ref name, _)) => Ok(ModuleSource::File(name.clone())),
|
||||
Term::Constant(_, Constant::Atom(ref name, _)) =>
|
||||
Ok(ModuleSource::File(name.clone())),
|
||||
_ => Err(ParserError::InvalidUseModuleDecl),
|
||||
}
|
||||
}
|
||||
|
||||
type UseModuleExport = (ModuleSource, Vec<PredicateKey>);
|
||||
type UseModuleExport = (ModuleSource, Vec<ModuleExport>);
|
||||
|
||||
fn setup_qualified_import(mut terms: Vec<Box<Term>>) -> Result<UseModuleExport, ParserError> {
|
||||
fn setup_qualified_import(
|
||||
mut terms: Vec<Box<Term>>,
|
||||
atom_tbl: TabledData<Atom>,
|
||||
) -> Result<UseModuleExport, ParserError> {
|
||||
let mut export_list = *terms.pop().unwrap();
|
||||
let module_src = match *terms.pop().unwrap() {
|
||||
Term::Clause(_, ref name, ref mut terms, None)
|
||||
@@ -282,10 +313,10 @@ fn setup_qualified_import(mut terms: Vec<Box<Term>>) -> Result<UseModuleExport,
|
||||
_ => Err(ParserError::InvalidUseModuleDecl),
|
||||
}?;
|
||||
|
||||
let mut exports = Vec::new();
|
||||
let mut exports = vec![];
|
||||
|
||||
while let Term::Cons(_, t1, t2) = export_list {
|
||||
exports.push(setup_predicate_indicator(*t1)?);
|
||||
exports.push(setup_module_export(*t1, atom_tbl.clone())?);
|
||||
export_list = *t2;
|
||||
}
|
||||
|
||||
@@ -296,9 +327,14 @@ fn setup_qualified_import(mut terms: Vec<Box<Term>>) -> Result<UseModuleExport,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_consistent(tl: &TopLevel, clauses: &Vec<PredicateClause>) -> bool {
|
||||
fn is_consistent(
|
||||
name: Option<ClauseName>,
|
||||
arity: usize,
|
||||
clauses: &Vec<PredicateClause>,
|
||||
) -> bool
|
||||
{
|
||||
match clauses.first() {
|
||||
Some(ref cl) => tl.name() == cl.name() && tl.arity() == cl.arity(),
|
||||
Some(ref cl) => name == cl.name() && arity == cl.arity(),
|
||||
None => true,
|
||||
}
|
||||
}
|
||||
@@ -311,18 +347,18 @@ fn merge_clauses(tls: &mut VecDeque<TopLevel>) -> Result<TopLevel, ParserError>
|
||||
TopLevel::Query(_) if clauses.is_empty() && tls.is_empty() => return Ok(tl),
|
||||
TopLevel::Declaration(_) if clauses.is_empty() => return Ok(tl),
|
||||
TopLevel::Query(_) => return Err(ParserError::InconsistentEntry),
|
||||
TopLevel::Fact(..) if is_consistent(&tl, &clauses) =>
|
||||
TopLevel::Fact(..) if is_consistent(tl.name(), tl.arity(), &clauses) =>
|
||||
if let TopLevel::Fact(fact, line_num, col_num) = tl {
|
||||
let clause = PredicateClause::Fact(fact, line_num, col_num);
|
||||
clauses.push(clause);
|
||||
},
|
||||
TopLevel::Rule(..) if is_consistent(&tl, &clauses) => {
|
||||
TopLevel::Rule(..) if is_consistent(tl.name(), tl.arity(), &clauses) => {
|
||||
if let TopLevel::Rule(rule, line_num, col_num) = tl {
|
||||
let clause = PredicateClause::Rule(rule, line_num, col_num);
|
||||
clauses.push(clause);
|
||||
}
|
||||
}
|
||||
TopLevel::Predicate(_) if is_consistent(&tl, &clauses) => {
|
||||
TopLevel::Predicate(_) if is_consistent(tl.name(), tl.arity(), &clauses) => {
|
||||
if let TopLevel::Predicate(pred) = tl {
|
||||
clauses.extend(pred.clauses().into_iter())
|
||||
}
|
||||
@@ -460,19 +496,19 @@ fn setup_declaration<'a, 'b, 'c, R: Read>(
|
||||
("op", 3) =>
|
||||
Ok(Declaration::Op(setup_op_decl(terms, indices.atom_tbl())?)),
|
||||
("module", 2) =>
|
||||
Ok(Declaration::Module(setup_module_decl(terms)?)),
|
||||
Ok(Declaration::Module(setup_module_decl(terms, indices.atom_tbl())?)),
|
||||
("use_module", 1) =>
|
||||
Ok(Declaration::UseModule(setup_use_module_decl(terms)?)),
|
||||
("use_module", 2) => {
|
||||
let (name, exports) = setup_qualified_import(terms)?;
|
||||
let (name, exports) = setup_qualified_import(terms, indices.atom_tbl())?;
|
||||
Ok(Declaration::UseQualifiedModule(name, exports))
|
||||
}
|
||||
("non_counted_backtracking", 1) => {
|
||||
let (name, arity) = setup_predicate_indicator(*terms.pop().unwrap())?;
|
||||
let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?;
|
||||
Ok(Declaration::NonCountedBacktracking(name, arity))
|
||||
}
|
||||
("dynamic", 1) => {
|
||||
let (name, arity) = setup_predicate_indicator(*terms.pop().unwrap())?;
|
||||
let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?;
|
||||
Ok(Declaration::Dynamic(name, arity))
|
||||
}
|
||||
("initialization", 1) => {
|
||||
@@ -563,7 +599,7 @@ impl RelationWorker {
|
||||
|
||||
fn fabricate_disjunct(&self, body_term: Term) -> (JumpStub, VecDeque<Term>) {
|
||||
let vars = self.compute_head(&body_term);
|
||||
let clauses: Vec<_> = unfold_by_str(body_term, ";")
|
||||
let results = unfold_by_str(body_term, ";")
|
||||
.into_iter()
|
||||
.map(|term| {
|
||||
let mut subterms = unfold_by_str(term, ",");
|
||||
@@ -572,13 +608,10 @@ impl RelationWorker {
|
||||
check_for_internal_if_then(&mut subterms);
|
||||
|
||||
let term = subterms.pop().unwrap();
|
||||
fold_by_str(subterms.into_iter(), term, clause_name!(","))
|
||||
})
|
||||
.collect();
|
||||
let clause = fold_by_str(subterms.into_iter(), term, clause_name!(","));
|
||||
|
||||
let results = clauses
|
||||
.into_iter()
|
||||
.map(|clause| self.fabricate_rule_body(&vars, clause))
|
||||
self.fabricate_rule_body(&vars, clause)
|
||||
})
|
||||
.collect();
|
||||
|
||||
(vars, results)
|
||||
@@ -723,11 +756,11 @@ impl RelationWorker {
|
||||
if name.as_str() == "," {
|
||||
let term = Term::Clause(cell, name, terms, op_spec);
|
||||
let mut subterms = unfold_by_str(term, ",");
|
||||
|
||||
|
||||
while let Some(subterm) = subterms.pop() {
|
||||
work_queue.push_front(Box::new(subterm));
|
||||
}
|
||||
|
||||
|
||||
continue;
|
||||
} else {
|
||||
term = Term::Clause(cell, name, terms, op_spec);
|
||||
@@ -741,7 +774,7 @@ impl RelationWorker {
|
||||
query_terms.push(self.pre_query_term(indices, term)?);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Ok(query_terms)
|
||||
}
|
||||
|
||||
@@ -946,14 +979,14 @@ impl<'a, R: Read> TopLevelBatchWorker<'a, R> {
|
||||
&mut self,
|
||||
indices: &mut IndexStore,
|
||||
preds: &mut Vec<PredicateClause>,
|
||||
) -> Result<(), SessionError> {
|
||||
) -> Result<(), SessionError> {
|
||||
let mut indices = CompositeIndices::new(
|
||||
&mut self.term_stream,
|
||||
IndexSource::Local(indices),
|
||||
if self.in_module { None } else { Some(IndexSource::TermStream) }
|
||||
);
|
||||
|
||||
let queue = self.rel_worker.parse_queue(&mut indices)?;
|
||||
let queue = self.rel_worker.parse_queue(&mut indices)?;
|
||||
let result = (append_preds(preds), queue);
|
||||
|
||||
let in_situ_code_dir = &mut indices.term_stream.wam.indices.in_situ_code_dir;
|
||||
@@ -992,17 +1025,18 @@ impl<'a, R: Read> TopLevelBatchWorker<'a, R> {
|
||||
|
||||
while !self.term_stream.eof()? {
|
||||
let term = self.term_stream.read_term(&indices.op_dir)?;
|
||||
|
||||
// if is_consistent is false, preds is non-empty.
|
||||
if !is_consistent(term.predicate_name(), term.predicate_arity(), &preds) {
|
||||
self.process_result(indices, &mut preds)?;
|
||||
self.take_dynamic_clauses();
|
||||
}
|
||||
|
||||
let (mut tl, new_rel_worker) = self.try_term_to_tl(indices, term)?;
|
||||
|
||||
if tl.is_end_of_file_atom() {
|
||||
tl = TopLevel::Declaration(Declaration::EndOfFile);
|
||||
}
|
||||
|
||||
// if is_consistent is false, preds is non-empty.
|
||||
if !is_consistent(&tl, &preds) {
|
||||
self.process_result(indices, &mut preds)?;
|
||||
self.take_dynamic_clauses();
|
||||
}
|
||||
}
|
||||
|
||||
self.rel_worker.absorb(new_rel_worker);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user