perform term and goal expansion on asserted dynamic predicates inside modules
This commit is contained in:
@@ -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??
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
||||||
@@ -179,10 +179,37 @@ fn update_module_indices(wam: &Machine, module_name: ClauseName, mut indices: In
|
|||||||
},
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => unreachable!()
|
_ => unreachable!()
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
@@ -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();
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -116,14 +133,14 @@ pub trait SubModuleUser
|
|||||||
} else if arity == 2 {
|
} else if arity == 2 {
|
||||||
insert_op_dir(Fixity::In);
|
insert_op_dir(Fixity::In);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(code_data) = submodule.code_dir.get(&(name.clone(), arity)) {
|
if let Some(code_data) = submodule.code_dir.get(&(name.clone(), arity)) {
|
||||||
let name = name.with_table(submodule.atom_tbl.clone());
|
let name = name.with_table(submodule.atom_tbl.clone());
|
||||||
let mut atom_tbl = self.atom_tbl();
|
let mut atom_tbl = self.atom_tbl();
|
||||||
|
|
||||||
atom_tbl.borrow_mut().insert(name.to_rc());
|
atom_tbl.borrow_mut().insert(name.to_rc());
|
||||||
|
|
||||||
self.insert_dir_entry(name, arity, code_data.clone());
|
self.insert_dir_entry(name, arity, code_data.clone());
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
@@ -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(())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user