From: Mark Thom Date: Sun, 14 Feb 2021 02:41:04 +0000 (-0700) Subject: compile scoped clauses from loader.pl X-Git-Tag: v0.9.0~150^2~51 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=e2a413df786db71f257a2c6500eba12b7dab6745;p=scryer-prolog.git compile scoped clauses from loader.pl --- diff --git a/src/clause_types.rs b/src/clause_types.rs index a3fa0ee8..33294fa4 100644 --- a/src/clause_types.rs +++ b/src/clause_types.rs @@ -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)), diff --git a/src/forms.rs b/src/forms.rs index 408d691d..fc63e7e5 100644 --- a/src/forms.rs +++ b/src/forms.rs @@ -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) -> 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, + 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, } diff --git a/src/loader.pl b/src/loader.pl index 0abd573c..475bb4b7 100644 --- a/src/loader.pl +++ b/src/loader.pl @@ -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) :- diff --git a/src/machine/compile.rs b/src/machine/compile.rs index faac9421..e75259a6 100644 --- a/src/machine/compile.rs +++ b/src/machine/compile.rs @@ -1010,18 +1010,22 @@ impl<'a> LoadState<'a> { fn compile( &mut self, key: PredicateKey, - predicates: &Vec, + predicates: &PredicateQueue, // &Vec, queue: &VecDeque, settings: CodeGenSettings, ) -> Result { - 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::::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, + compilation_target: CompilationTarget, non_counted_bt: bool, append_or_prepend: AppendOrPrepend, ) -> Result { - 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)?; } diff --git a/src/machine/load_state.rs b/src/machine/load_state.rs index 8ed61cef..81427d05 100644 --- a/src/machine/load_state.rs +++ b/src/machine/load_state.rs @@ -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, diff --git a/src/machine/loader.rs b/src/machine/loader.rs index 07b00e20..7046fa1e 100644 --- a/src/machine/loader.rs +++ b/src/machine/loader.rs @@ -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, + 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) { + 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, + pub(super) predicates: PredicateQueue, pub(super) clause_clauses: Vec<(Term, Term)>, term_stream: TermStream, pub(super) non_counted_bt_preds: IndexSet, @@ -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 { + 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() } } diff --git a/src/machine/machine_indices.rs b/src/machine/machine_indices.rs index b72fff67..4b4a4c18 100644 --- a/src/machine/machine_indices.rs +++ b/src/machine/machine_indices.rs @@ -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; pub(crate) type StreamAliasDir = IndexMap; pub(crate) type StreamDir = BTreeSet; @@ -700,10 +700,13 @@ pub type MetaPredicateDir = IndexMap>; pub type ExtensiblePredicates = IndexMap; +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, diff --git a/src/machine/mod.rs b/src/machine/mod.rs index 36e1e629..38ecd285 100644 --- a/src/machine/mod.rs +++ b/src/machine/mod.rs @@ -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(); } diff --git a/src/machine/preprocessor.rs b/src/machine/preprocessor.rs index bdb9d7fb..6e055134 100644 --- a/src/machine/preprocessor.rs +++ b/src/machine/preprocessor.rs @@ -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 { 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) diff --git a/src/machine/term_stream.rs b/src/machine/term_stream.rs index d87f9e25..21a30e29 100644 --- a/src/machine/term_stream.rs +++ b/src/machine/term_stream.rs @@ -101,7 +101,7 @@ pub struct LoadStatePayload { pub(super) module_op_exports: Vec<(OpDecl, Option<(usize, Specifier)>)>, pub(super) non_counted_bt_preds: IndexSet, pub(super) preprocessor: Preprocessor, - pub(super) predicates: Vec, + 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![], } } diff --git a/src/macros.rs b/src/macros.rs index aa043327..7e03e231 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -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, diff --git a/src/write.rs b/src/write.rs index 4137cf05..dacf0ed9 100644 --- a/src/write.rs +++ b/src/write.rs @@ -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 =>