]> Repositorios git - scryer-prolog.git/commitdiff
compile scoped clauses from loader.pl
authorMark Thom <[email protected]>
Sun, 14 Feb 2021 02:41:04 +0000 (19:41 -0700)
committerMark Thom <[email protected]>
Sun, 14 Feb 2021 02:41:04 +0000 (19:41 -0700)
12 files changed:
src/clause_types.rs
src/forms.rs
src/loader.pl
src/machine/compile.rs
src/machine/load_state.rs
src/machine/loader.rs
src/machine/machine_indices.rs
src/machine/mod.rs
src/machine/preprocessor.rs
src/machine/term_stream.rs
src/macros.rs
src/write.rs

index a3fa0ee833b0013b29efc0d111465755359f9d1e..33294fa48fdceb9b5be0971e0ec1ef1cd09ae1ff 100644 (file)
@@ -352,6 +352,9 @@ impl SystemClauseType {
             &SystemClauseType::REPL(REPLCodePtr::ClauseToEvacuable) => {
                 clause_name!("$clause_to_evacuable")
             }
+            &SystemClauseType::REPL(REPLCodePtr::ScopedClauseToEvacuable) => {
+                clause_name!("$scoped_clause_to_evacuable")
+            }
             &SystemClauseType::REPL(REPLCodePtr::ConcludeLoad) => clause_name!("$conclude_load"),
             &SystemClauseType::REPL(REPLCodePtr::DeclareModule) => clause_name!("$declare_module"),
             &SystemClauseType::REPL(REPLCodePtr::LoadCompiledLibrary) => {
@@ -728,9 +731,12 @@ impl SystemClauseType {
             ("$working_directory", 2) => Some(SystemClauseType::WorkingDirectory),
             ("$path_canonical", 2) => Some(SystemClauseType::PathCanonical),
             ("$file_time", 3) => Some(SystemClauseType::FileTime),
-            ("$clause_to_evacuable", 3) => {
+            ("$clause_to_evacuable", 2) => {
                 Some(SystemClauseType::REPL(REPLCodePtr::ClauseToEvacuable))
             }
+            ("$scoped_clause_to_evacuable", 3) => {
+                Some(SystemClauseType::REPL(REPLCodePtr::ScopedClauseToEvacuable))
+            }
             ("$conclude_load", 1) => Some(SystemClauseType::REPL(REPLCodePtr::ConcludeLoad)),
             ("$use_module", 3) => Some(SystemClauseType::REPL(REPLCodePtr::UseModule)),
             ("$declare_module", 3) => Some(SystemClauseType::REPL(REPLCodePtr::DeclareModule)),
index 408d691dc945f8500ce9243769da7848be6c3d91..fc63e7e51604a9e6de2fdfb0aeb1e8ec4e5c59b1 100644 (file)
@@ -3,6 +3,7 @@ use prolog_parser::parser::OpDesc;
 use prolog_parser::{clause_name, is_infix, is_postfix};
 
 use crate::clause_types::*;
+use crate::machine::loader::PredicateQueue;
 use crate::machine::machine_errors::*;
 use crate::machine::machine_indices::*;
 use crate::rug::{Integer, Rational};
@@ -114,7 +115,7 @@ impl ListingSource {
 }
 
 pub trait ClauseInfo {
-    fn is_consistent(&self, clauses: &Vec<PredicateClause>) -> bool {
+    fn is_consistent(&self, clauses: &PredicateQueue) -> bool {
         match clauses.first() {
             Some(cl) => self.name() == cl.name() && self.arity() == cl.arity(),
             None => true,
@@ -442,7 +443,8 @@ pub struct Module {
     pub code_dir: CodeDir,
     pub op_dir: OpDir,
     pub meta_predicates: MetaPredicateDir,
-    pub extensible_predicates: IndexMap<PredicateKey, PredicateSkeleton>,
+    pub extensible_predicates: ExtensiblePredicates,
+    pub local_extensible_predicates: LocalExtensiblePredicates,
     pub is_impromptu_module: bool,
     pub listing_src: ListingSource,
     pub clause_assert_margin: usize,
@@ -457,7 +459,8 @@ impl Module {
             op_dir: default_op_dir(),
             meta_predicates: MetaPredicateDir::new(),
             is_impromptu_module: false,
-            extensible_predicates: IndexMap::new(),
+            extensible_predicates: ExtensiblePredicates::new(),
+            local_extensible_predicates: LocalExtensiblePredicates::new(),
             listing_src,
             clause_assert_margin: 0,
         }
index 0abd573c8f7ead4f5f52343aafa2e46e5c884e1d..475bb4b7cbe0d8eb3c52f65528586557fad61fbe 100644 (file)
@@ -175,11 +175,19 @@ expand_term_goals(Terms0, Terms) :-
     (  Terms0 = (Head1 :- Body0) ->
        (  var(Head1) ->
           instantiation_error(load/1)
+       ;  Head1 = Module:Head2 ->
+          (  atom(Module) ->
+             prolog_load_context(module, Target),
+             module_expanded_head_variables(Head2, HeadVars),
+             expand_goal(Body0, Target, Body1, HeadVars),
+             Terms = (Module:Head2 :- Body1)
+          ;  type_error(atom, Module, load/1)
+          )
        ;  prolog_load_context(module, Target),
           module_expanded_head_variables(Head1, HeadVars),
-          expand_goal(Body0, Target, Body1, HeadVars)
-       ),
-       Terms = (Head1 :- Body1)
+          expand_goal(Body0, Target, Body1, HeadVars),
+          Terms = (Head1 :- Body1)
+       )
     ;  Terms = Terms0
     ).
 
@@ -205,7 +213,7 @@ compile_dispatch_or_clause(Term, Evacuable, VNs) :-
        instantiation_error(load/1)
     ;  compile_dispatch(Term, Evacuable, VNs) ->
        true
-    ;  compile_clause(Term, Evacuable, VNs)
+    ;  compile_clause(Term, Evacuable)
     ).
 
 
@@ -257,9 +265,14 @@ compile_declaration(initialization(Goal), Evacuable) :-
     assertz(Module:'$initialization_goals'(Goal)).
 
 
-
-compile_clause(Clause, Evacuable, VNs) :-
-    '$clause_to_evacuable'(Clause, Evacuable, VNs).
+compile_clause((Target:Head :- Body), Evacuable) :-
+    !,
+    '$scoped_clause_to_evacuable'(Target, (Head :- Body), Evacuable).
+compile_clause(Target:Clause, Evacuable) :-
+    !,
+    '$scoped_clause_to_evacuable'(Target, Clause, Evacuable).
+compile_clause(Clause, Evacuable) :-
+    '$clause_to_evacuable'(Clause, Evacuable).
 
 
 prolog_load_context(source, Source) :-
index faac9421c093c36284653e2efbfc161868c96682..e75259a60eefbb263ff651e46f15ba9b075aec8e 100644 (file)
@@ -1010,18 +1010,22 @@ impl<'a> LoadState<'a> {
     fn compile(
         &mut self,
         key: PredicateKey,
-        predicates: &Vec<PredicateClause>,
+        predicates: &PredicateQueue, // &Vec<PredicateClause>,
         queue: &VecDeque<TopLevel>,
         settings: CodeGenSettings,
     ) -> Result<IndexPtr, SessionError> {
-        let code_index = self.get_or_insert_code_index(key.clone());
+        let code_index = self.get_or_insert_code_index(
+            key.clone(),
+            predicates.compilation_target.clone(),
+        );
+
         let code_len = self.wam.code_repo.code.len();
         let mut code_ptr = code_len;
 
         let mut cg =
             CodeGenerator::<DebrayAllocator>::new(self.wam.machine_st.atom_tbl.clone(), settings);
 
-        let mut code = cg.compile_predicate(predicates)?;
+        let mut code = cg.compile_predicate(&predicates.predicates)?;
 
         compile_appendix(
             &mut code,
@@ -1047,12 +1051,12 @@ impl<'a> LoadState<'a> {
             match self
                 .wam
                 .indices
-                .get_predicate_skeleton_mut(&self.compilation_target, &key)
+                .get_predicate_skeleton_mut(&predicates.compilation_target, &key)
             {
                 Some(skeleton) => {
                     self.retraction_info
                         .push_record(RetractionRecord::SkeletonClauseTruncateBack(
-                            self.compilation_target.clone(),
+                            predicates.compilation_target.clone(),
                             key.clone(),
                             skeleton.clauses.len(),
                         ));
@@ -1060,14 +1064,18 @@ impl<'a> LoadState<'a> {
                     skeleton.clauses.extend(cg.skeleton.clauses.into_iter());
                 }
                 None => {
-                    self.add_extensible_predicate(key.clone(), cg.skeleton);
+                    self.add_extensible_predicate(
+                        key.clone(),
+                        cg.skeleton,
+                        predicates.compilation_target.clone(),
+                    );
                 }
             }
         }
 
         set_code_index(
             &mut self.retraction_info,
-            &self.compilation_target,
+            &predicates.compilation_target,
             key,
             &code_index,
             IndexPtr::Index(code_ptr),
@@ -1080,10 +1088,11 @@ impl<'a> LoadState<'a> {
     fn record_incremental_compile(
         &mut self,
         key: PredicateKey,
+        compilation_target: CompilationTarget,
         append_or_prepend: AppendOrPrepend,
     ) {
         self.retraction_info
-            .push_record(match &self.compilation_target {
+            .push_record(match compilation_target {
                 CompilationTarget::User => match append_or_prepend {
                     AppendOrPrepend::Append => {
                         RetractionRecord::AppendedUserExtensiblePredicate(key)
@@ -1092,14 +1101,14 @@ impl<'a> LoadState<'a> {
                         RetractionRecord::PrependedUserExtensiblePredicate(key)
                     }
                 },
-                CompilationTarget::Module(ref module_name) => match append_or_prepend {
+                CompilationTarget::Module(module_name) => match append_or_prepend {
                     AppendOrPrepend::Append => RetractionRecord::AppendedModuleExtensiblePredicate(
-                        module_name.clone(),
+                        module_name,
                         key,
                     ),
                     AppendOrPrepend::Prepend => {
                         RetractionRecord::PrependedModuleExtensiblePredicate(
-                            module_name.clone(),
+                            module_name,
                             key,
                         )
                     }
@@ -1112,21 +1121,30 @@ impl<'a> LoadState<'a> {
         key: PredicateKey,
         clause: PredicateClause,
         queue: VecDeque<TopLevel>,
+        compilation_target: CompilationTarget,
         non_counted_bt: bool,
         append_or_prepend: AppendOrPrepend,
     ) -> Result<IndexPtr, SessionError> {
-        self.record_incremental_compile(key.clone(), append_or_prepend);
+        self.record_incremental_compile(
+            key.clone(),
+            compilation_target.clone(),
+            append_or_prepend,
+        );
 
         let skeleton = match self
             .wam
             .indices
-            .get_predicate_skeleton_mut(&self.compilation_target, &key)
+            .get_predicate_skeleton_mut(&compilation_target, &key)
         {
             Some(skeleton) if !skeleton.clauses.is_empty() => skeleton,
             _ => {
                 // true because this predicate is extensible.
                 let settings = CodeGenSettings::new(true, non_counted_bt);
-                return self.compile(key, &vec![clause], &queue, settings);
+
+                let mut predicate_queue = predicate_queue![clause];
+                predicate_queue.compilation_target = compilation_target;
+
+                return self.compile(key, &predicate_queue, &queue, settings);
             }
         };
 
@@ -1146,7 +1164,7 @@ impl<'a> LoadState<'a> {
 
                 self.retraction_info
                     .push_record(RetractionRecord::SkeletonClausePopBack(
-                        self.compilation_target.clone(),
+                        compilation_target.clone(),
                         key.clone(),
                     ));
 
@@ -1157,12 +1175,15 @@ impl<'a> LoadState<'a> {
                     &mut self.retraction_info,
                 );
 
-                let code_index = self.get_or_insert_code_index(key.clone());
+                let code_index = self.get_or_insert_code_index(
+                    key.clone(),
+                    compilation_target.clone(),
+                );
 
                 if let Some(new_code_index) = result {
                     set_code_index(
                         &mut self.retraction_info,
-                        &self.compilation_target,
+                        &compilation_target,
                         key,
                         &code_index,
                         IndexPtr::Index(new_code_index),
@@ -1178,24 +1199,27 @@ impl<'a> LoadState<'a> {
 
                 self.retraction_info
                     .push_record(RetractionRecord::SkeletonClausePopFront(
-                        self.compilation_target.clone(),
+                        compilation_target.clone(),
                         key.clone(),
                     ));
 
                 let threaded_choice_instr_loc = prepend_compiled_clause(
                     &mut self.wam.code_repo.code,
-                    self.compilation_target.clone(),
+                    compilation_target.clone(),
                     key.clone(),
                     clause_code,
                     skeleton,
                     &mut self.retraction_info,
                 );
 
-                let code_index = self.get_or_insert_code_index(key.clone());
+                let code_index = self.get_or_insert_code_index(
+                    key.clone(),
+                    compilation_target.clone(),
+                );
 
                 set_code_index(
                     &mut self.retraction_info,
-                    &self.compilation_target,
+                    &compilation_target,
                     key,
                     &code_index,
                     IndexPtr::Index(threaded_choice_instr_loc),
@@ -1207,7 +1231,10 @@ impl<'a> LoadState<'a> {
     }
 
     pub(super) fn retract_clause(&mut self, key: PredicateKey, target_pos: usize) -> usize {
-        let code_index = self.get_or_insert_code_index(key.clone());
+        let code_index = self.get_or_insert_code_index(
+            key.clone(),
+            self.compilation_target.clone(),
+        );
 
         let skeleton = match self
             .wam
@@ -1516,40 +1543,47 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
             _ => compilation_target.clone(),
         };
 
-        let old_compilation_target = mem::replace(
-            &mut self.load_state.compilation_target,
-            clause_clause_compilation_target,
-        );
-
         let mut clause_clause_locs = sdeq![];
 
         for clause_predicate in clause_predicates {
             clause_clause_locs.push_back(self.load_state.wam.code_repo.code.len());
 
-            let result = self.load_state.incremental_compile_clause(
+            self.load_state.incremental_compile_clause(
                 (clause_name!("$clause"), 2),
                 clause_predicate,
                 VecDeque::new(),
+                clause_clause_compilation_target.clone(),
                 false, // non_counted_bt is false.
                 append_or_prepend,
-            );
-
-            if let Err(e) = result {
-                self.load_state.compilation_target = old_compilation_target;
-                return Err(e);
-            }
+            )?;
         }
 
         match self.load_state.wam.indices.get_predicate_skeleton_mut(
-            &self.load_state.compilation_target,
+            &clause_clause_compilation_target,
             &(clause_name!("$clause"), 2),
         ) {
             Some(skeleton) if append_or_prepend.is_append() => {
+                self.load_state.retraction_info.push_record(
+                    RetractionRecord::SkeletonClauseClausesTruncateBack(
+                        clause_clause_compilation_target.clone(),
+                        (clause_name!("$clause"), 2),
+                        skeleton.clause_clause_locs.len(),
+                    ),
+                );
+
                 skeleton
                     .clause_clause_locs
                     .extend_from_slice(&clause_clause_locs[0..]);
             }
             Some(skeleton) => {
+                self.load_state.retraction_info.push_record(
+                    RetractionRecord::SkeletonClauseClausesTruncateFront(
+                        clause_clause_compilation_target.clone(),
+                        (clause_name!("$clause"), 2),
+                        skeleton.clause_clause_locs.len(),
+                    ),
+                );
+
                 for loc in clause_clause_locs.iter() {
                     skeleton.clause_clause_locs.push_front(*loc);
                 }
@@ -1589,15 +1623,16 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
                     skeleton.clause_clause_locs.push_front(*loc);
                 }
 
-                self.load_state
-                    .increment_clause_assert_margin(clause_clause_locs.len());
+                self.load_state.increment_clause_assert_margin(
+                    clause_clause_compilation_target,
+                    clause_clause_locs.len(),
+                );
             }
             None => {
-                unreachable!();
+                unreachable!()
             }
         }
 
-        self.load_state.compilation_target = old_compilation_target;
         Ok(())
     }
 
@@ -1617,7 +1652,7 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
             .load_state
             .wam
             .indices
-            .get_predicate_skeleton(&self.load_state.compilation_target, &key)
+            .get_predicate_skeleton(&self.predicates.compilation_target, &key)
             .map(|skeleton| (skeleton.is_dynamic, true))
             .unwrap_or((false, false));
 
@@ -1629,7 +1664,7 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
 
         if is_dynamic {
             let iter = mem::replace(&mut self.clause_clauses, vec![]).into_iter();
-            let compilation_target = self.load_state.compilation_target.clone();
+            let compilation_target = self.predicates.compilation_target.clone();
 
             self.compile_clause_clauses(key, compilation_target, iter, AppendOrPrepend::Append)?;
         }
index 8ed61cefdeee8211d1cbe58e81f7a9b6a0b1b8fc..81427d05d918a8395bd99e8faa6233126de0d7b3 100644 (file)
@@ -329,21 +329,25 @@ fn import_qualified_module_exports_into_module(
 
 impl<'a> LoadState<'a> {
     #[inline]
-    pub(super) fn increment_clause_assert_margin(&mut self, incr: usize) {
-        match &self.compilation_target {
+    pub(super) fn increment_clause_assert_margin(
+        &mut self,
+        compilation_target: CompilationTarget,
+        incr: usize,
+    ) {
+        match compilation_target {
             CompilationTarget::User => {}
-            CompilationTarget::Module(ref module_name) => {
-                self.retraction_info
-                    .push_record(RetractionRecord::IncreasedClauseAssertMargin(
-                        module_name.clone(),
-                        incr,
-                    ));
-
+            CompilationTarget::Module(module_name) => {
                 self.wam
                     .indices
                     .modules
-                    .get_mut(module_name)
+                    .get_mut(&module_name)
                     .map(|module| module.clause_assert_margin += incr);
+
+                self.retraction_info
+                    .push_record(RetractionRecord::IncreasedClauseAssertMargin(
+                        module_name,
+                        incr,
+                    ));
             }
         }
     }
@@ -396,8 +400,12 @@ impl<'a> LoadState<'a> {
         }
     }
 
-    pub(super) fn get_or_insert_code_index(&mut self, key: PredicateKey) -> CodeIndex {
-        match self.compilation_target.clone() {
+    pub(super) fn get_or_insert_code_index(
+        &mut self,
+        key: PredicateKey,
+        compilation_target: CompilationTarget,
+    ) -> CodeIndex {
+        match compilation_target {
             CompilationTarget::User => self
                 .wam
                 .indices
@@ -434,8 +442,9 @@ impl<'a> LoadState<'a> {
         &mut self,
         key: PredicateKey,
         skeleton: PredicateSkeleton,
+        compilation_target: CompilationTarget,
     ) {
-        match &self.compilation_target {
+        match compilation_target {
             CompilationTarget::User => {
                 self.wam
                     .indices
@@ -445,12 +454,12 @@ impl<'a> LoadState<'a> {
                 self.retraction_info
                     .push_record(RetractionRecord::AddedUserExtensiblePredicate(key));
             }
-            CompilationTarget::Module(ref module_name) => {
-                if let Some(module) = self.wam.indices.modules.get_mut(module_name) {
+            CompilationTarget::Module(module_name) => {
+                if let Some(module) = self.wam.indices.modules.get_mut(&module_name) {
                     module.extensible_predicates.insert(key.clone(), skeleton);
 
                     self.retraction_info.push_record(
-                        RetractionRecord::AddedModuleExtensiblePredicate(module_name.clone(), key),
+                        RetractionRecord::AddedModuleExtensiblePredicate(module_name, key),
                     );
                 } else {
                     unreachable!()
@@ -497,11 +506,19 @@ impl<'a> LoadState<'a> {
     ) -> ClauseType {
         match ClauseType::from(name, arity, fixity) {
             ClauseType::Named(name, arity, _) => {
-                let idx = self.get_or_insert_code_index((name.clone(), arity));
+                let idx = self.get_or_insert_code_index(
+                    (name.clone(), arity),
+                    self.compilation_target.clone(),
+                );
+
                 ClauseType::Named(name, arity, idx)
             }
             ClauseType::Op(name, fixity, _) => {
-                let idx = self.get_or_insert_code_index((name.clone(), arity));
+                let idx = self.get_or_insert_code_index(
+                    (name.clone(), arity),
+                    self.compilation_target.clone(),
+                );
+
                 ClauseType::Op(name, fixity, idx)
             }
             ct => ct,
index 07b00e2082432a01285f525ce4d87d93a4542a5d..7046fa1e296de01c186dac627a2805298d9dfe74 100644 (file)
@@ -557,7 +557,7 @@ impl<'a> Drop for LoadState<'a> {
     }
 }
 
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, PartialEq, Eq)]
 pub enum CompilationTarget {
     Module(ClauseName),
     User,
@@ -587,9 +587,58 @@ impl CompilationTarget {
     }
 }
 
+pub struct PredicateQueue {
+    pub(super) predicates: Vec<PredicateClause>,
+    pub(super) compilation_target: CompilationTarget,
+}
+
+impl PredicateQueue {
+    #[inline]
+    pub(super) fn push(&mut self, clause: PredicateClause) {
+        self.predicates.push(clause);
+    }
+
+    #[inline]
+    pub(super) fn extend(&mut self, iter: impl Iterator<Item = PredicateClause>) {
+        self.predicates.extend(iter);
+    }
+
+    #[inline]
+    pub(super) fn clear(&mut self) {
+        self.predicates.clear();
+    }
+
+    #[inline]
+    pub(crate) fn first(&self) -> Option<&PredicateClause> {
+        self.predicates.first()
+    }
+
+    #[inline]
+    pub(crate) fn is_empty(&self) -> bool {
+        self.predicates.is_empty()
+    }
+
+    #[inline]
+    pub(super) fn take(&mut self) -> Self {
+        Self {
+            predicates: mem::replace(&mut self.predicates, vec![]),
+            compilation_target: self.compilation_target.take(),
+        }
+    }
+}
+
+macro_rules! predicate_queue {
+    [$($v:expr),*] => (
+        PredicateQueue {
+            predicates: vec![$($v,)*],
+            compilation_target: CompilationTarget::default(),
+        }
+    )
+}
+
 pub(crate) struct Loader<'a, TermStream> {
     pub(super) load_state: LoadState<'a>,
-    pub(super) predicates: Vec<PredicateClause>,
+    pub(super) predicates: PredicateQueue,
     pub(super) clause_clauses: Vec<(Term, Term)>,
     term_stream: TermStream,
     pub(super) non_counted_bt_preds: IndexSet<PredicateKey>,
@@ -612,7 +661,7 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
             term_stream,
             non_counted_bt_preds: IndexSet::new(),
             preprocessor: Preprocessor::new(flags),
-            predicates: vec![],
+            predicates: predicate_queue![],
             clause_clauses: vec![],
         }
     }
@@ -643,7 +692,7 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
             match tl {
                 TopLevel::Fact(fact) => self.predicates.push(PredicateClause::Fact(fact)),
                 TopLevel::Rule(rule) => self.predicates.push(PredicateClause::Rule(rule)),
-                TopLevel::Predicate(pred) => self.predicates.extend(pred),
+                TopLevel::Predicate(pred) => self.predicates.extend(pred.into_iter()),
                 TopLevel::Declaration(decl) => return Ok(Some(decl)),
                 TopLevel::Query(_) => return Err(SessionError::QueryCannotBeDefinedAsFact),
             }
@@ -665,6 +714,9 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
                 self.load_state.compilation_target =
                     CompilationTarget::Module(module_decl.name.clone());
 
+                self.predicates.compilation_target =
+                    self.load_state.compilation_target.clone();
+
                 self.load_state
                     .add_module(module_decl, self.term_stream.listing_src().clone());
             }
@@ -827,14 +879,10 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
                         }
                     }
                     None => {
-                        self.load_state
-                            .wam
-                            .indices
-                            .extensible_predicates
-                            .insert(key.clone(), PredicateSkeleton::new().set_dynamic(true));
-
-                        self.load_state.retraction_info.push_record(
-                            RetractionRecord::AddedUserExtensiblePredicate(key.clone()),
+                        self.load_state.add_extensible_predicate(
+                            key.clone(),
+                            PredicateSkeleton::new().set_dynamic(true),
+                            CompilationTarget::User,
                         );
                     }
                 }
@@ -855,15 +903,10 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
                             }
                         }
                         None => {
-                            module
-                                .extensible_predicates
-                                .insert(key.clone(), PredicateSkeleton::new().set_dynamic(true));
-
-                            self.load_state.retraction_info.push_record(
-                                RetractionRecord::AddedModuleExtensiblePredicate(
-                                    module_name.clone(),
-                                    key.clone(),
-                                ),
+                            self.load_state.add_extensible_predicate(
+                                key.clone(),
+                                PredicateSkeleton::new().set_dynamic(true),
+                                self.load_state.compilation_target.clone(),
                             );
                         }
                     },
@@ -874,7 +917,10 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
             }
         }
 
-        let code_index = self.load_state.get_or_insert_code_index(key.clone());
+        let code_index = self.load_state.get_or_insert_code_index(
+            key.clone(),
+            self.load_state.compilation_target.clone(),
+        );
 
         set_code_index(
             &mut self.load_state.retraction_info,
@@ -884,6 +930,29 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
             IndexPtr::DynamicUndefined,
         );
     }
+
+    fn add_clause_clause_if_dynamic(&mut self, term: &Term) -> Result<(), SessionError> {
+        if let Some(predicate_name) = ClauseInfo::name(term) {
+            let arity = ClauseInfo::arity(term);
+
+            let is_dynamic = self
+                .load_state
+                .wam
+                .indices
+                .get_predicate_skeleton(
+                    &self.predicates.compilation_target,
+                    &(predicate_name, arity),
+                )
+                .map(|skeleton| skeleton.is_dynamic)
+                .unwrap_or(false);
+
+            if is_dynamic {
+                self.add_clause_clause(term.clone())?;
+            }
+        }
+
+        Ok(())
+    }
 }
 
 impl Machine {
@@ -1180,36 +1249,29 @@ impl Machine {
         }
     }
 
-    pub(crate) fn clause_to_evacuable(&mut self) {
-        let (mut loader, evacuable_h) = self.loader_from_heap_evacuable(temp_v!(2));
+    pub(crate) fn scoped_clause_to_evacuable(&mut self) {
+        let module_name = atom_from!(
+            self.machine_st,
+            self.machine_st
+                .store(self.machine_st.deref(self.machine_st[temp_v!(1)]))
+        );
 
-        let enqueue_term = || {
-            let term = loader.read_term_from_heap(temp_v!(1))?;
+        let (loader, evacuable_h) = self.loader_from_heap_evacuable(temp_v!(3));
 
-            if let Some(predicate_name) = ClauseInfo::name(&term) {
-                let arity = ClauseInfo::arity(&term);
+        let compilation_target = match module_name.as_str() {
+            "user" => CompilationTarget::User,
+            _ => CompilationTarget::Module(module_name),
+        };
 
-                let is_dynamic = loader
-                    .load_state
-                    .wam
-                    .indices
-                    .get_predicate_skeleton(
-                        &loader.load_state.compilation_target,
-                        &(predicate_name, arity),
-                    )
-                    .map(|skeleton| skeleton.is_dynamic)
-                    .unwrap_or(false);
-
-                if is_dynamic {
-                    loader.add_clause_clause(term.clone())?;
-                }
-            }
+        let result = loader.read_and_enqueue_term(temp_v!(2), compilation_target);
+        self.restore_load_state_payload(result, evacuable_h);
+    }
 
-            loader.enqueue_term(term);
-            loader.load()
-        };
+    pub(crate) fn clause_to_evacuable(&mut self) {
+        let (loader, evacuable_h) = self.loader_from_heap_evacuable(temp_v!(2));
+        let compilation_target = loader.load_state.compilation_target.clone();
 
-        let result = enqueue_term();
+        let result = loader.read_and_enqueue_term(temp_v!(1), compilation_target);
         self.restore_load_state_payload(result, evacuable_h);
     }
 
@@ -1470,7 +1532,11 @@ impl Machine {
                     skeleton.clause_clause_locs.clear();
                 });
 
-            let code_index = loader.load_state.get_or_insert_code_index(key);
+            let code_index = loader.load_state.get_or_insert_code_index(
+                key,
+                loader.load_state.compilation_target.clone(),
+            );
+
             code_index.set(IndexPtr::DynamicUndefined);
 
             loader.load_state.compilation_target = clause_clause_compilation_target;
@@ -1778,7 +1844,7 @@ impl<'a> Loader<'a, LiveTermStream> {
                 &mut self.load_state.retraction_info,
                 RetractionInfo::new(self.load_state.wam.code_repo.code.len()),
             ),
-            predicates: mem::replace(&mut self.predicates, vec![]),
+            predicates: self.predicates.take(),
             clause_clauses: mem::replace(&mut self.clause_clauses, vec![]),
             module_op_exports: mem::replace(&mut self.load_state.module_op_exports, vec![]),
         }
@@ -1799,7 +1865,7 @@ impl<'a> Loader<'a, LiveTermStream> {
             ),
             non_counted_bt_preds: mem::replace(&mut payload.non_counted_bt_preds, IndexSet::new()),
             clause_clauses: mem::replace(&mut payload.clause_clauses, vec![]),
-            predicates: mem::replace(&mut payload.predicates, vec![]),
+            predicates: payload.predicates.take(),
             load_state: LoadState {
                 compilation_target: payload.compilation_target.take(),
                 module_op_exports: mem::replace(&mut payload.module_op_exports, vec![]),
@@ -1819,7 +1885,11 @@ impl<'a> Loader<'a, LiveTermStream> {
     ) -> Result<(), SessionError> {
         let mut preprocessor = Preprocessor::new(self.load_state.wam.machine_st.flags);
 
-        let tl = preprocessor.try_term_to_tl(&mut self.load_state, term, CutContext::BlocksCuts)?;
+        let tl = preprocessor.try_term_to_tl(
+            &mut self.load_state,
+            term,
+            CutContext::BlocksCuts,
+        )?;
 
         let queue = preprocessor.parse_queue(&mut self.load_state)?;
 
@@ -1831,26 +1901,37 @@ impl<'a> Loader<'a, LiveTermStream> {
             }
         };
 
-        let compilation_target =
-            mem::replace(&mut self.load_state.compilation_target, compilation_target);
-
-        let result = self.load_state.incremental_compile_clause(
+        self.load_state.incremental_compile_clause(
             key,
             clause,
             queue,
+            compilation_target,
             non_counted_bt,
             append_or_prepend,
-        );
-
-        self.load_state.compilation_target = compilation_target;
-        result?;
+        )?;
 
         Ok(())
     }
 
-    #[inline]
-    fn enqueue_term(&mut self, term: Term) {
+    fn read_and_enqueue_term(
+        mut self,
+        term_reg: RegType,
+        compilation_target: CompilationTarget,
+    ) -> Result<LoadStatePayload, SessionError> {
+        if self.predicates.compilation_target != compilation_target {
+            if !self.predicates.is_empty() {
+                self.compile_and_submit()?;
+            }
+
+            self.predicates.compilation_target = compilation_target;
+        }
+
+        let term = self.read_term_from_heap(term_reg)?;
+
+        self.add_clause_clause_if_dynamic(&term)?;
         self.term_stream.term_queue.push_back(term);
+
+        self.load()
     }
 }
 
index b72fff677aeb0c4f084bf24dc9f66fb3ac80d6af..4b4a4c18a6c63f1dd91ccc6abb75d809394c6472 100644 (file)
@@ -421,6 +421,7 @@ pub enum REPLCodePtr {
     AddGoalExpansionClause,
     AddTermExpansionClause,
     ClauseToEvacuable,
+    ScopedClauseToEvacuable,
     ConcludeLoad,
     DeclareModule,
     LoadCompiledLibrary,
@@ -692,7 +693,6 @@ pub(crate) struct ModuleStub {
     pub(crate) in_situ_code_dir: InSituCodeDir,
 }
 
-// pub(crate) type ModuleStubDir = IndexMap<ClauseName, ModuleStub>;
 pub(crate) type StreamAliasDir = IndexMap<ClauseName, Stream>;
 pub(crate) type StreamDir = BTreeSet<Stream>;
 
@@ -700,10 +700,13 @@ pub type MetaPredicateDir = IndexMap<PredicateKey, Vec<MetaSpec>>;
 
 pub type ExtensiblePredicates = IndexMap<PredicateKey, PredicateSkeleton>;
 
+pub type LocalExtensiblePredicates = IndexMap<(CompilationTarget, PredicateKey), PredicateSkeleton>;
+
 #[derive(Debug)]
 pub struct IndexStore {
     pub(super) code_dir: CodeDir,
     pub(super) extensible_predicates: ExtensiblePredicates,
+    pub(super) local_extensible_predicates: LocalExtensiblePredicates,
     pub(super) global_variables: GlobalVarDir,
     pub(super) meta_predicates: MetaPredicateDir,
     pub(super) modules: ModuleDir,
index 36e1e6295c3112fe8766d83cd12acc723ae3462c..38ecd2859ec56c6af803b9dcdd9d3fd6dd59614b 100644 (file)
@@ -15,11 +15,12 @@ use crate::read::*;
 mod attributed_variables;
 pub(super) mod code_repo;
 pub mod code_walker;
+#[macro_use]
+pub(crate) mod loader;
 mod compile;
 mod copier;
 pub mod heap;
 mod load_state;
-mod loader;
 pub mod machine_errors;
 pub mod machine_indices;
 pub(super) mod machine_state;
@@ -36,10 +37,8 @@ mod arithmetic_ops;
 mod machine_state_impl;
 mod system_calls;
 
-//use crate::machine::attributed_variables::*;
 use crate::machine::code_repo::*;
 use crate::machine::compile::*;
-// use crate::machine::loader::*;
 use crate::machine::machine_errors::*;
 use crate::machine::machine_indices::*;
 use crate::machine::machine_state::*;
@@ -425,6 +424,9 @@ impl Machine {
             REPLCodePtr::ClauseToEvacuable => {
                 self.clause_to_evacuable();
             }
+            REPLCodePtr::ScopedClauseToEvacuable => {
+                self.scoped_clause_to_evacuable();
+            }
             REPLCodePtr::ConcludeLoad => {
                 self.conclude_load();
             }
index bdb9d7fb7c4bfa2fe5a07ae44245bd4fe0b8ae8c..6e05513410d970a7573d47f28d87dc667c38cbb6 100644 (file)
@@ -780,7 +780,8 @@ impl Preprocessor {
                             query_term
                         })
                 } else {
-                    self.to_query_term(load_state, Term::Clause(r, name, subterms, fixity))
+                    let clause = Term::Clause(r, name, subterms, fixity);
+                    self.to_query_term(load_state, clause)
                 }
             }
             _ => self.to_query_term(load_state, term),
@@ -831,8 +832,11 @@ impl Preprocessor {
         cut_context: CutContext,
     ) -> Result<Rule, CompilationError> {
         let post_head_terms: Vec<_> = terms.drain(1..).collect();
-
-        let mut query_terms = self.setup_query(load_state, post_head_terms, cut_context)?;
+        let mut query_terms = self.setup_query(
+            load_state,
+            post_head_terms,
+            cut_context,
+        )?;
 
         let clauses = query_terms.drain(1..).collect();
         let qt = query_terms.pop().unwrap();
@@ -899,7 +903,11 @@ impl Preprocessor {
         let mut results = VecDeque::new();
 
         for term in terms.into_iter() {
-            results.push_back(self.try_term_to_tl(load_state, term, cut_context)?);
+            results.push_back(self.try_term_to_tl(
+                load_state,
+                term,
+                cut_context,
+            )?);
         }
 
         Ok(results)
index d87f9e25f8104e5227a66534db7c9ff1d2c8ec6c..21a30e299d9f5acb763e979bf6cbd20e80612b96 100644 (file)
@@ -101,7 +101,7 @@ pub struct LoadStatePayload {
     pub(super) module_op_exports: Vec<(OpDecl, Option<(usize, Specifier)>)>,
     pub(super) non_counted_bt_preds: IndexSet<PredicateKey>,
     pub(super) preprocessor: Preprocessor,
-    pub(super) predicates: Vec<PredicateClause>,
+    pub(super) predicates: PredicateQueue,
     pub(super) clause_clauses: Vec<(Term, Term)>,
 }
 
@@ -120,7 +120,7 @@ impl LoadStatePayload {
             module_op_exports: vec![],
             non_counted_bt_preds: IndexSet::new(),
             preprocessor: Preprocessor::new(wam.machine_st.flags),
-            predicates: vec![],
+            predicates: predicate_queue![],
             clause_clauses: vec![],
         }
     }
index aa0433274f4c3336b6cdca653eb2da6b8afbbb86..7e03e23178540bcf961d760cc750d0ec4016a52e 100644 (file)
@@ -362,6 +362,7 @@ macro_rules! index_store {
         IndexStore {
             code_dir: $code_dir,
             extensible_predicates: ExtensiblePredicates::new(),
+            local_extensible_predicates: LocalExtensiblePredicates::new(),
             global_variables: GlobalVarDir::new(),
             meta_predicates: MetaPredicateDir::new(),
             modules: $modules,
index 4137cf05b2491b48c39ecc1a271563d938260034..dacf0ed94434aa2953f6f5f17de1b0ca06160916 100644 (file)
@@ -36,6 +36,8 @@ impl fmt::Display for REPLCodePtr {
                 write!(f, "REPLCodePtr::Retract"),
             REPLCodePtr::ClauseToEvacuable =>
                 write!(f, "REPLCodePtr::ClauseToEvacuable"),
+            REPLCodePtr::ScopedClauseToEvacuable =>
+                write!(f, "REPLCodePtr::ScopedClauseToEvacuable"),
             REPLCodePtr::ConcludeLoad =>
                 write!(f, "REPLCodePtr::ConcludeLoad"),
                REPLCodePtr::DeclareModule =>