]> Repositorios git - scryer-prolog.git/commitdiff
perform term and goal expansion on asserted dynamic predicates inside modules
authorMark Thom <[email protected]>
Sat, 9 Mar 2019 20:41:33 +0000 (13:41 -0700)
committerMark Thom <[email protected]>
Sat, 9 Mar 2019 20:41:33 +0000 (13:41 -0700)
src/prolog/forms.rs
src/prolog/machine/compile.rs
src/prolog/machine/modules.rs

index 863fd4cef91f30de6cd86a41229aac14900e941e..62ed3a48bfaa2ba8d8082935334eea6102d144cc 100644 (file)
@@ -237,5 +237,7 @@ pub struct Module {
     pub op_dir: OpDir,
     pub term_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??
 }
index e6762506a3dc1e5e89f9aa2a88b3ce484e7aa837..8bb2ee45a0a53854fe1345bbad72d5bc1418305c 100644 (file)
@@ -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<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)
@@ -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 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 {
@@ -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<R: Read>(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();
index aa040ba29a4b3ed74d6b03e2efef4bdc76ae11e4..001bbbf1960ac27ddd5185a120d8f4547c23c9b7 100644 (file)
@@ -12,6 +12,8 @@ use std::collections::{VecDeque};
 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(),
@@ -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<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
@@ -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(())
     }