perform term and goal expansion on asserted dynamic predicates inside modules

This commit is contained in:
Mark Thom
2019-03-09 13:41:33 -07:00
parent 870aa7651e
commit 9f398b2552
3 changed files with 98 additions and 29 deletions

View File

@@ -237,5 +237,7 @@ pub struct Module {
pub op_dir: OpDir, pub op_dir: OpDir,
pub term_expansions: (Predicate, VecDeque<TopLevel>), pub term_expansions: (Predicate, VecDeque<TopLevel>),
pub goal_expansions: (Predicate, VecDeque<TopLevel>), pub goal_expansions: (Predicate, VecDeque<TopLevel>),
pub user_term_expansions: (Predicate, VecDeque<TopLevel>), // term expansions inherited from the user scope.
pub user_goal_expansions: (Predicate, VecDeque<TopLevel>), // same for goal_expansions.
pub inserted_expansions: bool // has the module been successfully inserted into toplevel?? pub inserted_expansions: bool // has the module been successfully inserted into toplevel??
} }

View File

@@ -162,15 +162,15 @@ fn update_module_indices(wam: &Machine, module_name: ClauseName, mut indices: In
{ {
match wam.indices.modules.get(&module_name) { match wam.indices.modules.get(&module_name) {
Some(module) => { Some(module) => {
let mut code_dir = mem::replace(&mut indices.code_dir, CodeDir::new()); let code_dir = mem::replace(&mut indices.code_dir, CodeDir::new());
// replace the "user" module src's in the indices with module_name. // replace the "user" module src's in the indices with module_name.
for (key, idx) in code_dir.iter_mut() { for (key, idx) in code_dir.iter() {
let p = idx.0.borrow().0; let p = idx.0.borrow().0;
match module.code_dir.get(&key) { match module.code_dir.get(&key) {
Some(idx) => set_code_index!(idx, p, module_name.clone()), Some(idx) => set_code_index!(idx, p, module_name.clone()),
_ => unreachable!() _ => {}
} }
match wam.indices.code_dir.get(&key) { match wam.indices.code_dir.get(&key) {
@@ -185,6 +185,33 @@ fn update_module_indices(wam: &Machine, module_name: ClauseName, mut indices: In
}; };
} }
fn add_hooks_to_mockup(code_repo: &mut CodeRepo, hook: CompileTimeHook,
expansions: (Predicate, VecDeque<TopLevel>))
{
let key = (hook.name(), hook.arity());
let preds = code_repo.term_dir.entry(key.clone())
.or_insert((Predicate::new(), VecDeque::from(vec![])));
(preds.0).0.extend((expansions.0).0.iter().cloned());
preds.1.extend(expansions.1.iter().cloned());
}
fn setup_module_expansions(wam: &mut Machine, module_name: ClauseName)
{
match wam.indices.modules.get(&module_name) {
Some(module) => {
let term_expansions = module.term_expansions.clone();
let goal_expansions = module.goal_expansions.clone();
add_hooks_to_mockup(&mut wam.code_repo, CompileTimeHook::TermExpansion,
term_expansions);
add_hooks_to_mockup(&mut wam.code_repo, CompileTimeHook::GoalExpansion,
goal_expansions);
},
_ => unreachable!()
}
}
pub(super) pub(super)
fn compile_into_module<R: Read>(wam: &mut Machine, module_name: ClauseName, src: R, name: ClauseName) fn compile_into_module<R: Read>(wam: &mut Machine, module_name: ClauseName, src: R, name: ClauseName)
-> EvalSession -> EvalSession
@@ -194,20 +221,39 @@ fn compile_into_module<R: Read>(wam: &mut Machine, module_name: ClauseName, src:
let mut compiler = ListingCompiler::new(&wam.code_repo); let mut compiler = ListingCompiler::new(&wam.code_repo);
let results = try_eval_session!(compiler.gather_items(wam, src, &mut indices)); match compile_into_module_impl(wam, &mut compiler, module_name, src, indices) {
let module_code = try_eval_session!(compiler.generate_code(results.worker_results, wam, Ok(()) => EvalSession::EntrySuccess,
&mut indices.code_dir, 0)); Err(e) => {
compiler.drop_expansions(wam.machine_flags(), &mut wam.code_repo);
EvalSession::from(e)
}
}
}
fn compile_into_module_impl<R: Read>(wam: &mut Machine, compiler: &mut ListingCompiler,
module_name: ClauseName, src: R, mut indices: IndexStore)
-> Result<(), SessionError>
{
setup_module_expansions(wam, module_name.clone());
let flags = wam.machine_flags();
wam.code_repo.compile_hook(CompileTimeHook::TermExpansion, flags)?;
wam.code_repo.compile_hook(CompileTimeHook::GoalExpansion, flags)?;
let results = compiler.gather_items(wam, src, &mut indices)?;
let module_code = compiler.generate_code(results.worker_results, wam,
&mut indices.code_dir, 0)?;
let mut clause_code_generator = ClauseCodeGenerator::new(module_code.len()); let mut clause_code_generator = ClauseCodeGenerator::new(module_code.len());
try_eval_session!(clause_code_generator.generate_clause_code(results.dynamic_clause_map, clause_code_generator.generate_clause_code(results.dynamic_clause_map, wam)?;
wam));
update_module_indices(wam, module_name, indices); update_module_indices(wam, module_name, indices);
wam.code_repo.code.extend(module_code.into_iter()); wam.code_repo.code.extend(module_code.into_iter());
clause_code_generator.add_clause_code(wam); clause_code_generator.add_clause_code(wam);
EvalSession::EntrySuccess Ok(compiler.drop_expansions(wam.machine_flags(), &mut wam.code_repo))
} }
pub struct GatherResult { pub struct GatherResult {
@@ -455,6 +501,10 @@ impl ListingCompiler {
let module_preds = self.user_term_dir.entry(key.clone()) let module_preds = self.user_term_dir.entry(key.clone())
.or_insert((Predicate::new(), VecDeque::from(vec![]))); .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_preds.0).0.push(clause); (module_preds.0).0.push(clause);
module_preds.1.extend(queue.into_iter()); module_preds.1.extend(queue.into_iter());
@@ -600,8 +650,8 @@ fn compile_work<R: Read>(compiler: &mut ListingCompiler, wam: &mut Machine, src:
module_code.len())); module_code.len()));
if let Some(ref mut module) = &mut compiler.module { if let Some(ref mut module) = &mut compiler.module {
module.term_expansions = results.addition_results.take_term_expansions(); module.user_term_expansions = results.addition_results.take_term_expansions();
module.goal_expansions = results.addition_results.take_goal_expansions(); module.user_goal_expansions = results.addition_results.take_goal_expansions();
} }
let flags = wam.machine_flags(); let flags = wam.machine_flags();

View File

@@ -12,6 +12,8 @@ use std::collections::{VecDeque};
impl Module { impl Module {
pub fn new(module_decl: ModuleDecl, atom_tbl: TabledData<Atom>) -> Self { pub fn new(module_decl: ModuleDecl, atom_tbl: TabledData<Atom>) -> Self {
Module { module_decl, atom_tbl, Module { module_decl, atom_tbl,
user_term_expansions: (Predicate::new(), VecDeque::from(vec![])),
user_goal_expansions: (Predicate::new(), VecDeque::from(vec![])),
term_expansions: (Predicate::new(), VecDeque::from(vec![])), term_expansions: (Predicate::new(), VecDeque::from(vec![])),
goal_expansions: (Predicate::new(), VecDeque::from(vec![])), goal_expansions: (Predicate::new(), VecDeque::from(vec![])),
code_dir: CodeDir::new(), code_dir: CodeDir::new(),
@@ -26,16 +28,16 @@ impl Module {
let te = code_repo.term_dir.entry((clause_name!("term_expansion"), 2)) let te = code_repo.term_dir.entry((clause_name!("term_expansion"), 2))
.or_insert((Predicate::new(), VecDeque::from(vec![]))); .or_insert((Predicate::new(), VecDeque::from(vec![])));
(te.0).0.extend((self.term_expansions.0).0.iter().cloned()); (te.0).0.extend((self.user_term_expansions.0).0.iter().cloned());
te.1.extend(self.term_expansions.1.iter().cloned()); te.1.extend(self.user_term_expansions.1.iter().cloned());
} }
{ {
let ge = code_repo.term_dir.entry((clause_name!("goal_expansion"), 2)) let ge = code_repo.term_dir.entry((clause_name!("goal_expansion"), 2))
.or_insert((Predicate::new(), VecDeque::from(vec![]))); .or_insert((Predicate::new(), VecDeque::from(vec![])));
(ge.0).0.extend((self.goal_expansions.0).0.iter().cloned()); (ge.0).0.extend((self.user_goal_expansions.0).0.iter().cloned());
ge.1.extend(self.goal_expansions.1.iter().cloned()); ge.1.extend(self.user_goal_expansions.1.iter().cloned());
} }
code_repo.compile_hook(CompileTimeHook::TermExpansion, flags)?; code_repo.compile_hook(CompileTimeHook::TermExpansion, flags)?;
@@ -43,6 +45,21 @@ impl Module {
Ok(()) Ok(())
} }
pub fn add_module_expansion_record(&mut self, hook: CompileTimeHook, clause: PredicateClause,
queue: VecDeque<TopLevel>)
{
match hook {
CompileTimeHook::TermExpansion | CompileTimeHook::UserTermExpansion => {
(self.term_expansions.0).0.push(clause);
self.term_expansions.1.extend(queue.into_iter());
},
CompileTimeHook::GoalExpansion | CompileTimeHook::UserGoalExpansion => {
(self.goal_expansions.0).0.push(clause);
self.goal_expansions.1.extend(queue.into_iter());
}
}
}
} }
pub trait SubModuleUser pub trait SubModuleUser
@@ -193,11 +210,11 @@ impl SubModuleUser for Module {
{ {
use_qualified_module(self, submodule, exports)?; use_qualified_module(self, submodule, exports)?;
(self.term_expansions.0).0.extend((submodule.term_expansions.0).0.iter().cloned()); (self.user_term_expansions.0).0.extend((submodule.term_expansions.0).0.iter().cloned());
self.term_expansions.1.extend(submodule.term_expansions.1.iter().cloned()); self.user_term_expansions.1.extend(submodule.term_expansions.1.iter().cloned());
(self.goal_expansions.0).0.extend((submodule.goal_expansions.0).0.iter().cloned()); (self.user_goal_expansions.0).0.extend((submodule.goal_expansions.0).0.iter().cloned());
self.goal_expansions.1.extend(submodule.goal_expansions.1.iter().cloned()); self.user_goal_expansions.1.extend(submodule.goal_expansions.1.iter().cloned());
Ok(()) Ok(())
} }
@@ -207,11 +224,11 @@ impl SubModuleUser for Module {
{ {
use_module(self, submodule)?; use_module(self, submodule)?;
(self.term_expansions.0).0.extend((submodule.term_expansions.0).0.iter().cloned()); (self.user_term_expansions.0).0.extend((submodule.term_expansions.0).0.iter().cloned());
self.term_expansions.1.extend(submodule.term_expansions.1.iter().cloned()); self.user_term_expansions.1.extend(submodule.term_expansions.1.iter().cloned());
(self.goal_expansions.0).0.extend((submodule.goal_expansions.0).0.iter().cloned()); (self.user_goal_expansions.0).0.extend((submodule.goal_expansions.0).0.iter().cloned());
self.goal_expansions.1.extend(submodule.goal_expansions.1.iter().cloned()); self.user_goal_expansions.1.extend(submodule.goal_expansions.1.iter().cloned());
Ok(()) Ok(())
} }