From: Mark Thom Date: Sat, 9 Mar 2019 20:41:33 +0000 (-0700) Subject: perform term and goal expansion on asserted dynamic predicates inside modules X-Git-Tag: v0.8.110~189 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=9f398b255291540c97b9716f93cef3c19923bb70;p=scryer-prolog.git perform term and goal expansion on asserted dynamic predicates inside modules --- diff --git a/src/prolog/forms.rs b/src/prolog/forms.rs index 863fd4ce..62ed3a48 100644 --- a/src/prolog/forms.rs +++ b/src/prolog/forms.rs @@ -237,5 +237,7 @@ pub struct Module { pub op_dir: OpDir, pub term_expansions: (Predicate, VecDeque), pub goal_expansions: (Predicate, VecDeque), + pub user_term_expansions: (Predicate, VecDeque), // term expansions inherited from the user scope. + pub user_goal_expansions: (Predicate, VecDeque), // same for goal_expansions. pub inserted_expansions: bool // has the module been successfully inserted into toplevel?? } diff --git a/src/prolog/machine/compile.rs b/src/prolog/machine/compile.rs index e6762506..8bb2ee45 100644 --- a/src/prolog/machine/compile.rs +++ b/src/prolog/machine/compile.rs @@ -162,15 +162,15 @@ fn update_module_indices(wam: &Machine, module_name: ClauseName, mut indices: In { 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) { @@ -179,10 +179,37 @@ fn update_module_indices(wam: &Machine, module_name: ClauseName, mut indices: In }, _ => {} } - } + } + }, + _ => unreachable!() + }; +} + +fn add_hooks_to_mockup(code_repo: &mut CodeRepo, hook: CompileTimeHook, + expansions: (Predicate, VecDeque)) +{ + 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) @@ -194,20 +221,39 @@ fn compile_into_module(wam: &mut Machine, module_name: ClauseName, src: 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(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 { @@ -455,6 +501,10 @@ impl ListingCompiler { 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()); @@ -600,8 +650,8 @@ fn compile_work(compiler: &mut ListingCompiler, wam: &mut Machine, src: 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(); diff --git a/src/prolog/machine/modules.rs b/src/prolog/machine/modules.rs index aa040ba2..001bbbf1 100644 --- a/src/prolog/machine/modules.rs +++ b/src/prolog/machine/modules.rs @@ -12,6 +12,8 @@ use std::collections::{VecDeque}; impl Module { pub fn new(module_decl: ModuleDecl, atom_tbl: TabledData) -> 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(), @@ -26,16 +28,16 @@ impl Module { 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)?; @@ -43,6 +45,21 @@ impl Module { Ok(()) } + + pub fn add_module_expansion_record(&mut self, hook: CompileTimeHook, clause: PredicateClause, + queue: VecDeque) + { + 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 @@ -116,14 +133,14 @@ 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 { @@ -193,11 +210,11 @@ impl SubModuleUser for Module { { 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(()) } @@ -207,11 +224,11 @@ impl SubModuleUser for Module { { 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(()) }