]> Repositorios git - scryer-prolog.git/commitdiff
record module-level term_expansion and goal_expansion as inner predicates (#228)
authorMark Thom <[email protected]>
Sun, 24 Nov 2019 19:50:53 +0000 (12:50 -0700)
committerMark Thom <[email protected]>
Sun, 24 Nov 2019 19:50:53 +0000 (12:50 -0700)
src/prolog/forms.rs
src/prolog/machine/compile.rs
src/prolog/machine/modules.rs

index ed64a67f61c79844f1f47212f053d2b22e02cd06..c2e4ac14d91341f26d5b03feb63cb6042a35f971 100644 (file)
@@ -337,6 +337,8 @@ pub struct Module {
     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,
  }
index 55a916bfd24e127e7e1c29ccee999f0a269b506d..19a20425f613d957beefb50717828c207310989d 100644 (file)
@@ -448,7 +448,8 @@ fn add_toplevel_code(wam: &mut Machine, code: Code, indices: IndexStore) {
 }
 
 #[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());
 
@@ -683,7 +684,8 @@ impl ListingCompiler {
                 .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);
@@ -918,7 +920,7 @@ fn compile_work_impl(
     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,
@@ -969,7 +971,17 @@ fn compile_work_impl(
 
             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);
         }
 
index ace04f65d4690423d83564a762c376d5807ef316..b6c07e8f8875d7fe10b7c92da149d6fbd609df4d 100644 (file)
@@ -7,6 +7,7 @@ use crate::prolog::machine::machine_errors::*;
 use crate::prolog::machine::machine_indices::*;
 
 use std::collections::VecDeque;
+use std::mem;
 
 // Module's and related types are defined in forms.
 impl Module {
@@ -19,6 +20,8 @@ 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,
@@ -61,7 +64,7 @@ impl Module {
         Ok(())
     }
 
-    pub fn add_module_expansion_record(
+    pub fn add_expansion_record(
         &mut self,
         hook: CompileTimeHook,
         clause: PredicateClause,
@@ -78,6 +81,45 @@ impl Module {
             }
         }
     }
+
+    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 {
@@ -283,7 +325,7 @@ impl SubModuleUser for Module {
         self.user_goal_expansions
             .1
             .extend(submodule.goal_expansions.1.iter().cloned());
-       
+
         Ok(())
     }
 }