add module-level goal_expansion and term_expansion
This commit is contained in:
@@ -40,6 +40,8 @@ fn print_code(code: &Code) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PredicateCompileQueue = (Predicate, VecDeque<TopLevel>);
|
||||||
|
|
||||||
// throw errors if declaration or query found.
|
// throw errors if declaration or query found.
|
||||||
fn compile_relation(tl: &TopLevel, non_counted_bt: bool, flags: MachineFlags)
|
fn compile_relation(tl: &TopLevel, non_counted_bt: bool, flags: MachineFlags)
|
||||||
-> Result<Code, ParserError>
|
-> Result<Code, ParserError>
|
||||||
@@ -97,9 +99,9 @@ impl CodeRepo {
|
|||||||
Some(preds) => {
|
Some(preds) => {
|
||||||
let mut cg = CodeGenerator::<DebrayAllocator>::new(false, flags);
|
let mut cg = CodeGenerator::<DebrayAllocator>::new(false, flags);
|
||||||
let mut code = cg.compile_predicate(&(preds.0).0)?;
|
let mut code = cg.compile_predicate(&(preds.0).0)?;
|
||||||
|
|
||||||
compile_appendix(&mut code, &preds.1, false, flags)?;
|
compile_appendix(&mut code, &preds.1, false, flags)?;
|
||||||
|
|
||||||
Ok(match hook {
|
Ok(match hook {
|
||||||
CompileTimeHook::UserTermExpansion | CompileTimeHook::TermExpansion =>
|
CompileTimeHook::UserTermExpansion | CompileTimeHook::TermExpansion =>
|
||||||
self.term_expanders = code,
|
self.term_expanders = code,
|
||||||
@@ -159,8 +161,8 @@ pub fn compile_term(wam: &mut Machine, term: Term) -> EvalSession
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct GatherResult {
|
struct GatherResult {
|
||||||
worker_results: Vec<(Predicate, VecDeque<TopLevel>)>,
|
worker_results: Vec<PredicateCompileQueue>,
|
||||||
toplevel_results: Vec<(Predicate, VecDeque<TopLevel>)>,
|
toplevel_results: Vec<PredicateCompileQueue>,
|
||||||
toplevel_indices: IndexStore,
|
toplevel_indices: IndexStore,
|
||||||
addition_results: ExpansionAdditionResult
|
addition_results: ExpansionAdditionResult
|
||||||
}
|
}
|
||||||
@@ -168,13 +170,15 @@ struct GatherResult {
|
|||||||
pub struct ListingCompiler {
|
pub struct ListingCompiler {
|
||||||
non_counted_bt_preds: HashSet<PredicateKey>,
|
non_counted_bt_preds: HashSet<PredicateKey>,
|
||||||
module: Option<Module>,
|
module: Option<Module>,
|
||||||
|
user_term_dir: TermDir
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ListingCompiler {
|
impl ListingCompiler {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
ListingCompiler {
|
ListingCompiler {
|
||||||
module: None, non_counted_bt_preds: HashSet::new()
|
module: None, non_counted_bt_preds: HashSet::new(),
|
||||||
|
user_term_dir: TermDir::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,7 +235,7 @@ impl ListingCompiler {
|
|||||||
.unwrap_or(ClauseName::BuiltIn("user"))
|
.unwrap_or(ClauseName::BuiltIn("user"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_code(&mut self, decls: Vec<(Predicate, VecDeque<TopLevel>)>,
|
fn generate_code(&mut self, decls: Vec<PredicateCompileQueue>,
|
||||||
wam: &Machine, code_dir: &mut CodeDir)
|
wam: &Machine, code_dir: &mut CodeDir)
|
||||||
-> Result<Code, SessionError>
|
-> Result<Code, SessionError>
|
||||||
{
|
{
|
||||||
@@ -250,7 +254,7 @@ impl ListingCompiler {
|
|||||||
wam.machine_flags())?;
|
wam.machine_flags())?;
|
||||||
|
|
||||||
compile_appendix(&mut decl_code, &queue, non_counted_bt, wam.machine_flags())?;
|
compile_appendix(&mut decl_code, &queue, non_counted_bt, wam.machine_flags())?;
|
||||||
|
|
||||||
let idx = code_dir.entry((name, arity)).or_insert(CodeIndex::default());
|
let idx = code_dir.entry((name, arity)).or_insert(CodeIndex::default());
|
||||||
set_code_index!(idx, IndexPtr::Index(p), self.get_module_name());
|
set_code_index!(idx, IndexPtr::Index(p), self.get_module_name());
|
||||||
|
|
||||||
@@ -283,6 +287,41 @@ impl ListingCompiler {
|
|||||||
self.non_counted_bt_preds.insert((name, arity));
|
self.non_counted_bt_preds.insert((name, arity));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn add_term_dir_terms(&mut self, hook: CompileTimeHook, code_repo: &mut CodeRepo,
|
||||||
|
key: PredicateKey, clause: PredicateClause, queue: VecDeque<TopLevel>)
|
||||||
|
-> (usize, usize)
|
||||||
|
{
|
||||||
|
let preds = code_repo.term_dir.entry(key.clone())
|
||||||
|
.or_insert((Predicate::new(), VecDeque::from(vec![])));
|
||||||
|
|
||||||
|
let (mut len, mut queue_len) = ((preds.0).0.len(), preds.1.len());
|
||||||
|
|
||||||
|
if self.module.is_some() && hook.has_module_scope() {
|
||||||
|
let module_preds = self.user_term_dir.entry(key.clone())
|
||||||
|
.or_insert((Predicate::new(), VecDeque::from(vec![])));
|
||||||
|
|
||||||
|
(module_preds.0).0.push(clause);
|
||||||
|
module_preds.1.extend(queue.into_iter());
|
||||||
|
|
||||||
|
(preds.0).0.extend((module_preds.0).0.iter().cloned());
|
||||||
|
preds.1.extend(module_preds.1.iter().cloned());
|
||||||
|
} else {
|
||||||
|
let module_preds = self.user_term_dir.entry(key.clone())
|
||||||
|
.or_insert((Predicate::new(), VecDeque::from(vec![])));
|
||||||
|
|
||||||
|
len += 1;
|
||||||
|
queue_len += queue_len;
|
||||||
|
|
||||||
|
(preds.0).0.push(clause);
|
||||||
|
preds.1.extend(queue.into_iter());
|
||||||
|
|
||||||
|
(preds.0).0.extend((module_preds.0).0.iter().cloned());
|
||||||
|
preds.1.extend(module_preds.1.iter().cloned());
|
||||||
|
}
|
||||||
|
|
||||||
|
(len, queue_len)
|
||||||
|
}
|
||||||
|
|
||||||
fn process_decl(&mut self, decl: Declaration, code_repo: &mut CodeRepo,
|
fn process_decl(&mut self, decl: Declaration, code_repo: &mut CodeRepo,
|
||||||
wam_indices: &mut IndexStore, indices: &mut IndexStore,
|
wam_indices: &mut IndexStore, indices: &mut IndexStore,
|
||||||
flags: MachineFlags)
|
flags: MachineFlags)
|
||||||
@@ -291,17 +330,13 @@ impl ListingCompiler {
|
|||||||
match decl {
|
match decl {
|
||||||
Declaration::Hook(hook, clause, queue) => {
|
Declaration::Hook(hook, clause, queue) => {
|
||||||
let key = (hook.name(), hook.arity());
|
let key = (hook.name(), hook.arity());
|
||||||
|
let (len, queue_len) = self.add_term_dir_terms(hook, code_repo, key.clone(),
|
||||||
|
clause, queue);
|
||||||
|
|
||||||
{
|
let result = code_repo.compile_hook(hook, flags).map_err(SessionError::from);
|
||||||
let preds = code_repo.term_dir.entry(key)
|
code_repo.truncate_terms(key, len, queue_len);
|
||||||
.or_insert((Predicate(vec![]), VecDeque::from(vec![])));
|
|
||||||
|
result
|
||||||
(preds.0).0.push(clause);
|
|
||||||
preds.1.extend(queue.into_iter());
|
|
||||||
}
|
|
||||||
|
|
||||||
code_repo.compile_hook(hook, flags)
|
|
||||||
.map_err(SessionError::from)
|
|
||||||
},
|
},
|
||||||
Declaration::NonCountedBacktracking(name, arity) =>
|
Declaration::NonCountedBacktracking(name, arity) =>
|
||||||
Ok(self.add_non_counted_bt_flag(name, arity)),
|
Ok(self.add_non_counted_bt_flag(name, arity)),
|
||||||
@@ -330,13 +365,15 @@ impl ListingCompiler {
|
|||||||
{
|
{
|
||||||
match &decl {
|
match &decl {
|
||||||
&Declaration::Hook(hook, _, ref queue) if self.module.is_none() =>
|
&Declaration::Hook(hook, _, ref queue) if self.module.is_none() =>
|
||||||
term_stream.incr_expansion_lens(hook, 1, queue.len()),
|
term_stream.incr_expansion_lens(hook.user_scope(), 1, queue.len()),
|
||||||
|
&Declaration::Hook(hook, _, ref queue) if !hook.has_module_scope() =>
|
||||||
|
term_stream.incr_expansion_lens(hook, 1, queue.len()),
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.process_decl(decl, term_stream.code_repo, term_stream.indices, indices, flags)
|
self.process_decl(decl, term_stream.code_repo, term_stream.indices, indices, flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_items<R: Read>(&mut self, wam: &mut Machine, src: R, indices: &mut IndexStore)
|
fn gather_items<R: Read>(&mut self, wam: &mut Machine, src: R, indices: &mut IndexStore)
|
||||||
-> Result<GatherResult, SessionError>
|
-> Result<GatherResult, SessionError>
|
||||||
{
|
{
|
||||||
@@ -396,10 +433,15 @@ fn compile_listing<R: Read>(wam: &mut Machine, src: R, mut indices: IndexStore)
|
|||||||
module.term_expansions = results.addition_results.take_term_expansions();
|
module.term_expansions = results.addition_results.take_term_expansions();
|
||||||
module.goal_expansions = results.addition_results.take_goal_expansions();
|
module.goal_expansions = results.addition_results.take_goal_expansions();
|
||||||
}
|
}
|
||||||
|
|
||||||
try_eval_session!(compiler.add_code(wam, module_code, indices));
|
try_eval_session!(compiler.add_code(wam, module_code, indices));
|
||||||
try_eval_session!(compiler.add_code(wam, toplvl_code, results.toplevel_indices));
|
try_eval_session!(compiler.add_code(wam, toplvl_code, results.toplevel_indices));
|
||||||
|
|
||||||
|
let flags = wam.machine_flags();
|
||||||
|
|
||||||
|
try_eval_session!(wam.code_repo.compile_hook(CompileTimeHook::UserTermExpansion, flags));
|
||||||
|
try_eval_session!(wam.code_repo.compile_hook(CompileTimeHook::UserGoalExpansion, flags));
|
||||||
|
|
||||||
EvalSession::EntrySuccess
|
EvalSession::EntrySuccess
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -386,6 +386,7 @@ impl CompileTimeHook {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn arity(self) -> usize {
|
pub fn arity(self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
CompileTimeHook::UserGoalExpansion
|
CompileTimeHook::UserGoalExpansion
|
||||||
@@ -394,6 +395,24 @@ impl CompileTimeHook {
|
|||||||
| CompileTimeHook::TermExpansion => 2
|
| CompileTimeHook::TermExpansion => 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn user_scope(self) -> Self {
|
||||||
|
match self {
|
||||||
|
CompileTimeHook::UserGoalExpansion | CompileTimeHook::GoalExpansion =>
|
||||||
|
CompileTimeHook::UserGoalExpansion,
|
||||||
|
CompileTimeHook::UserTermExpansion | CompileTimeHook::TermExpansion =>
|
||||||
|
CompileTimeHook::UserTermExpansion,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn has_module_scope(self) -> bool {
|
||||||
|
match self {
|
||||||
|
CompileTimeHook::UserTermExpansion | CompileTimeHook::UserGoalExpansion => false,
|
||||||
|
_ => true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
|||||||
@@ -132,12 +132,10 @@ impl CodeRepo {
|
|||||||
pub fn truncate_terms(&mut self, key: PredicateKey, len: usize, queue_len: usize)
|
pub fn truncate_terms(&mut self, key: PredicateKey, len: usize, queue_len: usize)
|
||||||
-> (Predicate, VecDeque<TopLevel>)
|
-> (Predicate, VecDeque<TopLevel>)
|
||||||
{
|
{
|
||||||
//TODO: fix this! this is causing a test to fail. because term_expansions, when
|
|
||||||
//removed by rollback_expansion_code, aren't jump-labeled properly by generate_code.
|
|
||||||
self.term_dir.get_mut(&key)
|
self.term_dir.get_mut(&key)
|
||||||
.map(|entry| (Predicate((entry.0).0.clone()[len ..].to_vec()), //drain(len ..).collect()),
|
.map(|entry| (Predicate((entry.0).0.drain(len ..).collect()),
|
||||||
entry.1.drain(queue_len ..).collect()))
|
entry.1.drain(queue_len ..).collect()))
|
||||||
.unwrap_or((Predicate(vec![]), VecDeque::from(vec![])))
|
.unwrap_or((Predicate::new(), VecDeque::from(vec![])))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_in_situ_result(&mut self, result: &CompiledResult, in_situ_code_dir: &mut InSituCodeDir,
|
pub fn add_in_situ_result(&mut self, result: &CompiledResult, in_situ_code_dir: &mut InSituCodeDir,
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ fn as_compile_time_hook(name: &str, arity: usize, terms: &Vec<Box<Term>>) -> Opt
|
|||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,8 +106,8 @@ fn is_compile_time_hook(name: &ClauseName, terms: &Vec<Box<Term>>) -> Option<Com
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
as_compile_time_hook(name.as_str(), terms.len(), terms)
|
as_compile_time_hook(name.as_str(), terms.len(), terms)
|
||||||
}
|
}
|
||||||
|
|
||||||
type CompileTimeHookCompileInfo = (CompileTimeHook, PredicateClause, VecDeque<TopLevel>);
|
type CompileTimeHookCompileInfo = (CompileTimeHook, PredicateClause, VecDeque<TopLevel>);
|
||||||
@@ -368,21 +368,25 @@ fn module_resolution_call(mod_name: Term, body: Term) -> Result<QueryTerm, Parse
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn flatten_hook(mut term: Term) -> Term {
|
fn flatten_hook(mut term: Term) -> Term {
|
||||||
if let &mut Term::Clause(_, ref mut name, ref mut terms, _) = &mut term {
|
if let &mut Term::Clause(_, ref mut name, ref mut terms, _) = &mut term {
|
||||||
if name.as_str() == ":-" && terms.len() == 2 {
|
match (name.as_str(), terms.len()) {
|
||||||
let inner_term = match terms.first_mut().map(|term| term.borrow_mut()) {
|
(":-", 2) => {
|
||||||
Some(&mut Term::Clause(_, ref name, ref mut inner_terms, _)) =>
|
let inner_term = match terms.first_mut().map(|term| term.borrow_mut()) {
|
||||||
if name.as_str() == ":" && inner_terms.len() == 2 {
|
Some(&mut Term::Clause(_, ref name, ref mut inner_terms, _)) =>
|
||||||
Some(*inner_terms.pop().unwrap())
|
if name.as_str() == ":" && inner_terms.len() == 2 {
|
||||||
} else {
|
Some(*inner_terms.pop().unwrap())
|
||||||
None
|
} else {
|
||||||
},
|
None
|
||||||
_ => None
|
},
|
||||||
};
|
_ => None
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(mut inner_term) = inner_term {
|
if let Some(mut inner_term) = inner_term {
|
||||||
mem::swap(&mut terms[0], &mut Box::new(inner_term));
|
mem::swap(&mut terms[0], &mut Box::new(inner_term));
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
(":", 2) => return *terms.pop().unwrap(),
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user