]> Repositorios git - scryer-prolog.git/commitdiff
clear user-level definitions when reloading a file (#455)
authorMark Thom <[email protected]>
Tue, 16 Mar 2021 08:30:09 +0000 (02:30 -0600)
committerMark Thom <[email protected]>
Tue, 16 Mar 2021 08:30:09 +0000 (02:30 -0600)
src/clause_types.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/write.rs

index 4d7e35d6aa098cc0772a202b229d0268a9d12d8b..657945d6307737f08364e28d1b2ce4c8f3e6fd82 100644 (file)
@@ -372,6 +372,9 @@ impl SystemClauseType {
             &SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload) => {
                 clause_name!("$push_load_state_payload")
             }
+            &SystemClauseType::REPL(REPLCodePtr::AddInSituFilenameModule) => {
+                clause_name!("$add_in_situ_filename_module")
+            }
             &SystemClauseType::REPL(REPLCodePtr::Asserta) => clause_name!("$asserta"),
             &SystemClauseType::REPL(REPLCodePtr::Assertz) => clause_name!("$assertz"),
             &SystemClauseType::REPL(REPLCodePtr::Retract) => clause_name!("$retract_clause"),
@@ -765,6 +768,9 @@ impl SystemClauseType {
             ("$push_load_state_payload", 1) => {
                 Some(SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload))
             }
+            ("$add_in_situ_filename_module", 1) => {
+                Some(SystemClauseType::REPL(REPLCodePtr::AddInSituFilenameModule))
+            }
             ("$asserta", 5) => Some(SystemClauseType::REPL(REPLCodePtr::Asserta)),
             ("$assertz", 5) => Some(SystemClauseType::REPL(REPLCodePtr::Assertz)),
             ("$retract_clause", 4) => Some(SystemClauseType::REPL(REPLCodePtr::Retract)),
index 91b1ec83d897fddcbf3b6f7f5fea140914756f16..a748f9810f46894d178c88c327cf537cc4fa43a8 100644 (file)
@@ -105,6 +105,10 @@ file_load(_, _).
 
 file_load(Stream, Path, Evacuable) :-
     create_file_load_context(Stream, Path, Evacuable),
+    % '$add_in_situ_filename_module' removes user level predicates,
+    % local predicate clauses, etc. from a previous load of the file
+    % at Path.
+    '$add_in_situ_filename_module'(Evacuable),
     catch((loader:load_loop(Stream, Evacuable),
            loader:run_initialization_goals),
           E,
index b45b58e202d0f28907c607cb1d025f3550ab120e..3e96672e09489fa724f97e0667e4a84e339e2e31 100644 (file)
@@ -9,7 +9,7 @@ use crate::machine::preprocessor::*;
 use crate::machine::term_stream::*;
 use crate::machine::*;
 
-use slice_deque::sdeq;
+use slice_deque::{sdeq, SliceDeque};
 
 use std::cell::Cell;
 use std::collections::VecDeque;
@@ -867,7 +867,7 @@ fn prepend_compiled_clause(
 
     let target_arg_num = skeleton.clauses[0].opt_arg_index_key.arg_num();
     let head_arg_num = skeleton.clauses[1].opt_arg_index_key.arg_num();
-    
+
     let settings = CodeGenSettings {
         global_clock_tick: if skeleton.is_dynamic {
             Some(global_clock_tick)
@@ -1316,6 +1316,18 @@ fn print_overwrite_warning(
 }
 
 impl<'a> LoadState<'a> {
+    pub(super) fn listing_src_file_name(&self) -> Option<ClauseName> {
+        if let Some(load_context) = self.wam.load_contexts.last() {
+            if let Some(path_str) = load_context.path.to_str() {
+                if !path_str.is_empty() {
+                    return Some(clause_name!(path_str.to_string(), self.wam.machine_st.atom_tbl));
+                }
+            }
+        }
+
+        None
+    }
+
     fn compile_standalone_clause(
         &mut self,
         term: Term,
@@ -1349,7 +1361,7 @@ impl<'a> LoadState<'a> {
         key: PredicateKey,
         predicates: &mut PredicateQueue,
         settings: CodeGenSettings,
-    ) -> Result<(), SessionError> {
+    ) -> Result<CodeIndex, SessionError> {
         let code_index = self.get_or_insert_code_index(
             key.clone(),
             predicates.compilation_target.clone(),
@@ -1427,39 +1439,28 @@ impl<'a> LoadState<'a> {
                 }
             };
 
-            match self
-                .wam
-                .indices
-                .get_local_predicate_skeleton_mut(
-                    &self.compilation_target,
-                    predicates.compilation_target.clone(),
-                    key.clone(),
-                )
-            {
-                Some(skeleton) => {
-                    self.retraction_info
-                        .push_record(RetractionRecord::SkeletonLocalClauseTruncateBack(
-                            self.compilation_target.clone(),
-                            predicates.compilation_target.clone(),
-                            key.clone(),
-                            skeleton.clause_clause_locs.len(),
-                        ));
-
-                    skeleton.clause_clause_locs.extend_from_slice(
-                        &clause_clause_locs[0 ..]
+            if let Some(filename) = self.listing_src_file_name() {
+                if let CompilationTarget::User = &predicates.compilation_target {
+                    let compilation_target = mem::replace(
+                        &mut self.compilation_target,
+                        CompilationTarget::Module(filename),
                     );
-                }
-                None => {
-                    let mut skeleton = PredicateSkeleton::new();
-                    skeleton.clause_clause_locs = clause_clause_locs;
 
-                    self.add_local_extensible_predicate(
-                        predicates.compilation_target.clone(),
-                        key.clone(),
-                        skeleton,
+                    self.extend_local_predicate_skeleton(
+                        &CompilationTarget::User,
+                        &key,
+                        clause_clause_locs.clone(),
                     );
+
+                    self.compilation_target = compilation_target;
                 }
             }
+
+            self.extend_local_predicate_skeleton(
+                &predicates.compilation_target,
+                &key,
+                clause_clause_locs,
+            );
         }
 
         print_overwrite_warning(
@@ -1469,20 +1470,22 @@ impl<'a> LoadState<'a> {
             settings.is_dynamic(),
         );
 
+        let index_ptr = if settings.is_dynamic() {
+            IndexPtr::DynamicIndex(code_ptr)
+        } else {
+            IndexPtr::Index(code_ptr)
+        };
+
         set_code_index(
             &mut self.retraction_info,
             &predicates.compilation_target,
             key,
             &code_index,
-            if settings.is_dynamic() {
-                IndexPtr::DynamicIndex(code_ptr)
-            } else {
-                IndexPtr::Index(code_ptr)
-            },
+            index_ptr,
         );
 
         self.wam.code_repo.code.extend(code.into_iter());
-        Ok(())
+        Ok(code_index)
     }
 
     fn record_incremental_compile(
@@ -1516,6 +1519,125 @@ impl<'a> LoadState<'a> {
             });
     }
 
+    fn extend_local_predicate_skeleton(
+        &mut self,
+        compilation_target: &CompilationTarget,
+        key: &PredicateKey,
+        clause_clause_locs: SliceDeque<usize>,
+    ) {
+        match self
+            .wam
+            .indices
+            .get_local_predicate_skeleton_mut(
+                &self.compilation_target,
+                compilation_target.clone(),
+                key.clone(),
+            )
+        {
+            Some(skeleton) => {
+                self.retraction_info
+                    .push_record(RetractionRecord::SkeletonLocalClauseTruncateBack(
+                        self.compilation_target.clone(),
+                        compilation_target.clone(),
+                        key.clone(),
+                        skeleton.clause_clause_locs.len(),
+                    ));
+
+                skeleton.clause_clause_locs.extend_from_slice(
+                    &clause_clause_locs[0 ..]
+                );
+            }
+            None => {
+                let mut skeleton = PredicateSkeleton::new();
+                skeleton.clause_clause_locs = clause_clause_locs;
+
+                self.add_local_extensible_predicate(
+                    compilation_target.clone(),
+                    key.clone(),
+                    skeleton,
+                );
+            }
+        }
+    }
+
+    fn push_front_to_local_predicate_skeleton(
+        &mut self,
+        compilation_target: &CompilationTarget,
+        key: &PredicateKey,
+        code_len: usize,
+    ) {
+        match self
+            .wam
+            .indices
+            .get_local_predicate_skeleton_mut(
+                &self.compilation_target,
+                compilation_target.clone(),
+                key.clone(),
+            )
+        {
+            Some(skeleton) => {
+                self.retraction_info.push_record(
+                    RetractionRecord::SkeletonLocalClauseClausePopFront(
+                        self.compilation_target.clone(),
+                        compilation_target.clone(),
+                        key.clone(),
+                    ),
+                );
+
+                skeleton.clause_clause_locs.push_front(code_len);
+            }
+            None => {
+                let mut skeleton = PredicateSkeleton::new();
+                skeleton.clause_clause_locs.push_front(code_len);
+
+                self.add_local_extensible_predicate(
+                    compilation_target.clone(),
+                    key.clone(),
+                    skeleton,
+                );
+            }
+        }
+    }
+
+    fn push_back_to_local_predicate_skeleton(
+        &mut self,
+        compilation_target: &CompilationTarget,
+        key: &PredicateKey,
+        code_len: usize,
+    ) {
+        match self
+            .wam
+            .indices
+            .get_local_predicate_skeleton_mut(
+                &self.compilation_target,
+                compilation_target.clone(),
+                key.clone(),
+            )
+        {
+            Some(skeleton) => {
+                self.retraction_info.push_record(
+                    RetractionRecord::SkeletonLocalClauseClausePopBack(
+                        self.compilation_target.clone(),
+                        compilation_target.clone(),
+                        key.clone(),
+                    ),
+                );
+
+                skeleton.clause_clause_locs.push_back(code_len);
+            }
+            None => {
+                let mut skeleton = PredicateSkeleton::new();
+                skeleton.clause_clause_locs.push_back(code_len);
+
+                self.add_local_extensible_predicate(
+                    compilation_target.clone(),
+                    key.clone(),
+                    skeleton,
+                );
+            }
+        }
+    }
+
     pub(super) fn incremental_compile_clause(
         &mut self,
         key: PredicateKey,
@@ -1523,7 +1645,7 @@ impl<'a> LoadState<'a> {
         compilation_target: CompilationTarget,
         non_counted_bt: bool,
         append_or_prepend: AppendOrPrepend,
-    ) -> Result<(), SessionError> {
+    ) -> Result<CodeIndex, SessionError> {
         self.record_incremental_compile(
             key.clone(),
             compilation_target.clone(),
@@ -1607,35 +1729,26 @@ impl<'a> LoadState<'a> {
                     self.wam.machine_st.global_clock,
                 );
 
-                match self
-                    .wam
-                    .indices
-                    .get_local_predicate_skeleton_mut(
-                        &self.compilation_target,
-                        compilation_target.clone(),
-                        key.clone(),
-                    )
-                {
-                    Some(skeleton) => {
-                        self.retraction_info.push_record(
-                            RetractionRecord::SkeletonLocalClauseClausePopBack(
-                                self.compilation_target.clone(),
-                                compilation_target.clone(),
-                                key.clone(),
-                            ),
-                        );
+                self.push_back_to_local_predicate_skeleton(
+                    &compilation_target,
+                    &key,
+                    code_len,
+                );
 
-                        skeleton.clause_clause_locs.push_back(code_len);
-                    }
-                    None => {
-                        let mut skeleton = PredicateSkeleton::new();
-                        skeleton.clause_clause_locs.push_back(code_len);
+                if let Some(filename) = self.listing_src_file_name() {
+                    if let CompilationTarget::User = &compilation_target {
+                        let compilation_target = mem::replace(
+                            &mut self.compilation_target,
+                            CompilationTarget::Module(filename),
+                        );
 
-                        self.add_local_extensible_predicate(
-                            compilation_target.clone(),
-                            key.clone(),
-                            skeleton,
+                        self.push_back_to_local_predicate_skeleton(
+                            &CompilationTarget::User,
+                            &key,
+                            code_len,
                         );
+
+                        self.compilation_target = compilation_target;
                     }
                 }
 
@@ -1654,7 +1767,7 @@ impl<'a> LoadState<'a> {
                     );
                 }
 
-                Ok(())
+                Ok(code_index)
             }
             AppendOrPrepend::Prepend => {
                 let clause_index_info = standalone_skeleton.clauses.pop_back().unwrap();
@@ -1679,38 +1792,29 @@ impl<'a> LoadState<'a> {
                     self.wam.machine_st.global_clock,
                 );
 
-                match self
-                    .wam
-                    .indices
-                    .get_local_predicate_skeleton_mut(
-                        &self.compilation_target,
-                        compilation_target.clone(),
-                        key.clone(),
-                    )
-                {
-                    Some(skeleton) => {
-                        self.retraction_info.push_record(
-                            RetractionRecord::SkeletonLocalClauseClausePopFront(
-                                self.compilation_target.clone(),
-                                compilation_target.clone(),
-                                key.clone(),
-                            ),
+                if let Some(filename) = self.listing_src_file_name() {
+                    if let CompilationTarget::User = &compilation_target {
+                        let compilation_target = mem::replace(
+                            &mut self.compilation_target,
+                            CompilationTarget::Module(filename),
                         );
 
-                        skeleton.clause_clause_locs.push_front(code_len);
-                    }
-                    None => {
-                        let mut skeleton = PredicateSkeleton::new();
-                        skeleton.clause_clause_locs.push_front(code_len);
-
-                        self.add_local_extensible_predicate(
-                            compilation_target.clone(),
-                            key.clone(),
-                            skeleton,
+                        self.push_front_to_local_predicate_skeleton(
+                            &CompilationTarget::User,
+                            &key,
+                            code_len,
                         );
+
+                        self.compilation_target = compilation_target;
                     }
                 }
 
+                self.push_front_to_local_predicate_skeleton(
+                    &compilation_target,
+                    &key,
+                    code_len,
+                );
+
                 let code_index = self.get_or_insert_code_index(
                     key.clone(),
                     compilation_target.clone(),
@@ -1724,7 +1828,7 @@ impl<'a> LoadState<'a> {
                     new_code_ptr,
                 );
 
-                Ok(())
+                Ok(code_index)
             }
         }
     }
@@ -2268,7 +2372,30 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
                 non_counted_bt,
             };
 
-            self.load_state.compile(key.clone(), &mut self.predicates, settings)?;
+            let code_index
+                = self.load_state.compile(key.clone(), &mut self.predicates, settings)?;
+
+            if let Some(filename) = self.load_state.listing_src_file_name() {
+                if let CompilationTarget::User = &self.predicates.compilation_target {
+                    match self.load_state.wam.indices.modules.get_mut(&filename) {
+                        Some(ref mut module) => {
+                            let index_ptr = code_index.get();
+                            let code_index = module.code_dir.entry(key.clone())
+                                .or_insert(code_index);
+
+                            set_code_index(
+                                &mut self.load_state.retraction_info,
+                                &CompilationTarget::Module(filename),
+                                key.clone(),
+                                &code_index,
+                                index_ptr,
+                            );
+                        }
+                        None => {
+                        }
+                    }
+                }
+            }
         }
 
         if predicate_info.is_dynamic {
index 4e9d20337bffb0647d7d6e686e25676c266b3034..c51328ff3899145a276398579d5d1c688e36ea59 100644 (file)
@@ -903,7 +903,7 @@ impl<'a> LoadState<'a> {
         }
     }
 
-    pub(crate) fn add_module(&mut self, module_decl: ModuleDecl, listing_src: ListingSource) {
+    pub(crate) fn reset_in_situ_module(&mut self, module_decl: ModuleDecl, listing_src: &ListingSource) {
         let module_name = module_decl.name.clone();
 
         self.remove_module_exports(module_name.clone());
@@ -947,6 +947,21 @@ impl<'a> LoadState<'a> {
                             &skeleton.clause_clause_locs,
                         );
                     }
+
+                    if &self.compilation_target == compilation_target {
+                        let skeleton_opt = self.wam.indices.remove_predicate_skeleton(
+                            compilation_target,
+                            &key,
+                        );
+
+                        if let Some(skeleton) = skeleton_opt {
+                            self.retraction_info.push_record(RetractionRecord::RemovedSkeleton(
+                                compilation_target.clone(),
+                                key.clone(),
+                                skeleton,
+                            ));
+                        }
+                    }
                 }
 
                 self.retraction_info.push_record(RetractionRecord::ReplacedModule(
@@ -957,6 +972,11 @@ impl<'a> LoadState<'a> {
             }
             None => {}
         }
+    }
+
+    pub(crate) fn add_module(&mut self, module_decl: ModuleDecl, listing_src: ListingSource) {
+        self.reset_in_situ_module(module_decl.clone(), &listing_src);
+        let module_name = module_decl.name.clone();
 
         let mut module = match self.wam.indices.modules.remove(&module_name) {
             Some(mut module) => {
index c5c5e2e8735e1bb118ac4ff5a4482166032bd107..7c1c76adf499e78c6281916c812e1b612631bfc4 100644 (file)
@@ -726,7 +726,7 @@ pub(crate) struct Loader<'a, TermStream> {
     pub(super) load_state: LoadState<'a>,
     pub(super) predicates: PredicateQueue,
     pub(super) clause_clauses: Vec<(Term, Term)>,
-    term_stream: TermStream,
+    pub(super) term_stream: TermStream,
     pub(super) non_counted_bt_preds: IndexSet<PredicateKey>,
 }
 
@@ -767,9 +767,10 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
             }
 
             let term = match term {
-                Term::Clause(_, name, terms, _) if name.as_str() == ":-" && terms.len() == 1 => {
-                    return Ok(Some(setup_declaration(&self.load_state, terms)?));
-                }
+                Term::Clause(_, name, terms, _)
+                    if name.as_str() == ":-" && terms.len() == 1 => {
+                        return Ok(Some(setup_declaration(&self.load_state, terms)?));
+                    }
                 term => term,
             };
 
@@ -1463,6 +1464,36 @@ impl Machine {
         self.restore_load_state_payload(result, evacuable_h);
     }
 
+    pub(crate) fn add_in_situ_filename_module(&mut self) {
+        let (mut loader, evacuable_h) = self.loader_from_heap_evacuable(temp_v!(1));
+
+        let add_in_situ_filename_module = || {
+            if let Some(filename) = loader.load_state.listing_src_file_name() {
+                let module_decl = ModuleDecl {
+                    name: filename,
+                    exports: vec![],
+                };
+
+                if !loader.load_state.wam.indices.modules.contains_key(&module_decl.name) {
+                    let module_name = module_decl.name.clone();
+                    let module = Module::new(module_decl, ListingSource::DynamicallyGenerated);
+
+                    loader.load_state.wam.indices.modules.insert(module_name, module);
+                } else {
+                    loader.load_state.reset_in_situ_module(
+                        module_decl.clone(),
+                        &ListingSource::DynamicallyGenerated,
+                    );
+                }
+            }
+
+            LiveTermStream::evacuate(loader)
+        };
+
+        let result = add_in_situ_filename_module();
+        self.restore_load_state_payload(result, evacuable_h);
+    }
+
     pub(crate) fn loader_from_heap_evacuable(
         &mut self,
         r: RegType,
index ab2f332d89084d8a07863379c2b39878b57503da..90593d8fdd07560a4337b21a0d3079818ad9fb6f 100644 (file)
@@ -425,6 +425,7 @@ pub(crate) enum REPLCodePtr {
     AddMultifilePredicate,
     AddGoalExpansionClause,
     AddTermExpansionClause,
+    AddInSituFilenameModule,
     ClauseToEvacuable,
     ScopedClauseToEvacuable,
     ConcludeLoad,
index ad95a9001d9abcbbfcf05534f26f0ebb2286a635..44a40e3277511d8e6ec51f3e157e1a4411c7e080 100644 (file)
@@ -398,6 +398,9 @@ impl Machine {
             REPLCodePtr::AddTermExpansionClause => {
                 self.add_term_expansion_clause();
             }
+            REPLCodePtr::AddInSituFilenameModule => {
+                self.add_in_situ_filename_module();
+            }
             REPLCodePtr::ClauseToEvacuable => {
                 self.clause_to_evacuable();
             }
index 4aa84e995294e8d54a2e0169410f048360a8f57a..1c1fc3dcfa95fc54b2027752fbf19a023d1bb3a3 100644 (file)
@@ -31,6 +31,8 @@ impl fmt::Display for REPLCodePtr {
                 write!(f, "REPLCodePtr::AddGoalExpansionClause"),
             REPLCodePtr::AddTermExpansionClause =>
                 write!(f, "REPLCodePtr::AddTermExpansionClause"),
+            REPLCodePtr::AddInSituFilenameModule =>
+                write!(f, "REPLCodePtr::AddInSituFilenameModule"),
             REPLCodePtr::AbolishClause =>
                 write!(f, "REPLCodePtr::AbolishClause"),
             REPLCodePtr::Assertz =>