{
match wam.indices.modules.get(&module_name) {
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.
- for (key, idx) in code_dir.iter_mut() {
+ for (key, idx) in code_dir.iter() {
let p = idx.0.borrow().0;
match module.code_dir.get(&key) {
Some(idx) => set_code_index!(idx, p, module_name.clone()),
- _ => unreachable!()
+ _ => {}
}
match wam.indices.code_dir.get(&key) {
},
_ => {}
}
- }
+ }
+ },
+ _ => 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)
let mut compiler = ListingCompiler::new(&wam.code_repo);
- let results = try_eval_session!(compiler.gather_items(wam, src, &mut indices));
- let module_code = try_eval_session!(compiler.generate_code(results.worker_results, wam,
- &mut indices.code_dir, 0));
+ match compile_into_module_impl(wam, &mut compiler, module_name, src, indices) {
+ Ok(()) => EvalSession::EntrySuccess,
+ 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());
- try_eval_session!(clause_code_generator.generate_clause_code(results.dynamic_clause_map,
- wam));
+ clause_code_generator.generate_clause_code(results.dynamic_clause_map, wam)?;
update_module_indices(wam, module_name, indices);
-
+
wam.code_repo.code.extend(module_code.into_iter());
clause_code_generator.add_clause_code(wam);
- EvalSession::EntrySuccess
+ Ok(compiler.drop_expansions(wam.machine_flags(), &mut wam.code_repo))
}
pub struct GatherResult {
let module_preds = self.user_term_dir.entry(key.clone())
.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.1.extend(queue.into_iter());
module_code.len()));
if let Some(ref mut module) = &mut compiler.module {
- module.term_expansions = results.addition_results.take_term_expansions();
- module.goal_expansions = results.addition_results.take_goal_expansions();
+ module.user_term_expansions = results.addition_results.take_term_expansions();
+ module.user_goal_expansions = results.addition_results.take_goal_expansions();
}
let flags = wam.machine_flags();
impl Module {
pub fn new(module_decl: ModuleDecl, atom_tbl: TabledData<Atom>) -> Self {
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![])),
goal_expansions: (Predicate::new(), VecDeque::from(vec![])),
code_dir: CodeDir::new(),
let te = code_repo.term_dir.entry((clause_name!("term_expansion"), 2))
.or_insert((Predicate::new(), VecDeque::from(vec![])));
- (te.0).0.extend((self.term_expansions.0).0.iter().cloned());
- te.1.extend(self.term_expansions.1.iter().cloned());
+ (te.0).0.extend((self.user_term_expansions.0).0.iter().cloned());
+ te.1.extend(self.user_term_expansions.1.iter().cloned());
}
{
let ge = code_repo.term_dir.entry((clause_name!("goal_expansion"), 2))
.or_insert((Predicate::new(), VecDeque::from(vec![])));
- (ge.0).0.extend((self.goal_expansions.0).0.iter().cloned());
- ge.1.extend(self.goal_expansions.1.iter().cloned());
+ (ge.0).0.extend((self.user_goal_expansions.0).0.iter().cloned());
+ ge.1.extend(self.user_goal_expansions.1.iter().cloned());
}
code_repo.compile_hook(CompileTimeHook::TermExpansion, flags)?;
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
} 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());
+ let name = name.with_table(submodule.atom_tbl.clone());
let mut atom_tbl = self.atom_tbl();
atom_tbl.borrow_mut().insert(name.to_rc());
-
+
self.insert_dir_entry(name, arity, code_data.clone());
true
} else {
{
use_qualified_module(self, submodule, exports)?;
- (self.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.0).0.extend((submodule.term_expansions.0).0.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.goal_expansions.1.extend(submodule.goal_expansions.1.iter().cloned());
+ (self.user_goal_expansions.0).0.extend((submodule.goal_expansions.0).0.iter().cloned());
+ self.user_goal_expansions.1.extend(submodule.goal_expansions.1.iter().cloned());
Ok(())
}
{
use_module(self, submodule)?;
- (self.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.0).0.extend((submodule.term_expansions.0).0.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.goal_expansions.1.extend(submodule.goal_expansions.1.iter().cloned());
+ (self.user_goal_expansions.0).0.extend((submodule.goal_expansions.0).0.iter().cloned());
+ self.user_goal_expansions.1.extend(submodule.goal_expansions.1.iter().cloned());
Ok(())
}