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 local_term_expansions: (Predicate, VecDeque<TopLevel>), // expansions local to the module.
+ pub local_goal_expansions: (Predicate, VecDeque<TopLevel>),
pub inserted_expansions: bool, // has the module been successfully inserted into toplevel??
pub is_impromptu_module: bool,
}
}
#[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());
.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);
mut indices: IndexStore,
mut results: GatherResult,
) -> Result<(), SessionError> {
- let module_code = compiler.generate_code(
+ let mut module_code = compiler.generate_code(
results.worker_results,
wam,
&mut indices.code_dir,
wam.indices.use_module(&mut wam.code_repo, wam.machine_st.flags, &module)?;
wam.indices.insert_module(module);
- } else {
+ } else {
+ // compile the module-level goal and term expansions and store
+ // their locations to the module's code_dir.
+ let offset = module_code.len() + toplvl_code.len();
+ let decls = module.take_local_expansions();
+
+ if !decls.is_empty() {
+ let code = compiler.generate_code(decls, &wam, &mut indices.code_dir, offset)?;
+ module_code.extend(code.into_iter());
+ }
+
add_module_code(wam, module, module_code, indices);
}
use crate::prolog::machine::machine_indices::*;
use std::collections::VecDeque;
+use std::mem;
// Module's and related types are defined in forms.
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,
Ok(())
}
- pub fn add_module_expansion_record(
+ pub fn add_expansion_record(
&mut self,
hook: CompileTimeHook,
clause: PredicateClause,
}
}
}
+
+ 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 {
self.user_goal_expansions
.1
.extend(submodule.goal_expansions.1.iter().cloned());
-
+
Ok(())
}
}