compile scoped clauses from loader.pl

This commit is contained in:
Mark Thom
2021-02-13 19:41:04 -07:00
parent b24f68eee7
commit e2a413df78
12 changed files with 313 additions and 142 deletions

View File

@@ -352,6 +352,9 @@ impl SystemClauseType {
&SystemClauseType::REPL(REPLCodePtr::ClauseToEvacuable) => { &SystemClauseType::REPL(REPLCodePtr::ClauseToEvacuable) => {
clause_name!("$clause_to_evacuable") 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::ConcludeLoad) => clause_name!("$conclude_load"),
&SystemClauseType::REPL(REPLCodePtr::DeclareModule) => clause_name!("$declare_module"), &SystemClauseType::REPL(REPLCodePtr::DeclareModule) => clause_name!("$declare_module"),
&SystemClauseType::REPL(REPLCodePtr::LoadCompiledLibrary) => { &SystemClauseType::REPL(REPLCodePtr::LoadCompiledLibrary) => {
@@ -728,9 +731,12 @@ impl SystemClauseType {
("$working_directory", 2) => Some(SystemClauseType::WorkingDirectory), ("$working_directory", 2) => Some(SystemClauseType::WorkingDirectory),
("$path_canonical", 2) => Some(SystemClauseType::PathCanonical), ("$path_canonical", 2) => Some(SystemClauseType::PathCanonical),
("$file_time", 3) => Some(SystemClauseType::FileTime), ("$file_time", 3) => Some(SystemClauseType::FileTime),
("$clause_to_evacuable", 3) => { ("$clause_to_evacuable", 2) => {
Some(SystemClauseType::REPL(REPLCodePtr::ClauseToEvacuable)) Some(SystemClauseType::REPL(REPLCodePtr::ClauseToEvacuable))
} }
("$scoped_clause_to_evacuable", 3) => {
Some(SystemClauseType::REPL(REPLCodePtr::ScopedClauseToEvacuable))
}
("$conclude_load", 1) => Some(SystemClauseType::REPL(REPLCodePtr::ConcludeLoad)), ("$conclude_load", 1) => Some(SystemClauseType::REPL(REPLCodePtr::ConcludeLoad)),
("$use_module", 3) => Some(SystemClauseType::REPL(REPLCodePtr::UseModule)), ("$use_module", 3) => Some(SystemClauseType::REPL(REPLCodePtr::UseModule)),
("$declare_module", 3) => Some(SystemClauseType::REPL(REPLCodePtr::DeclareModule)), ("$declare_module", 3) => Some(SystemClauseType::REPL(REPLCodePtr::DeclareModule)),

View File

@@ -3,6 +3,7 @@ use prolog_parser::parser::OpDesc;
use prolog_parser::{clause_name, is_infix, is_postfix}; use prolog_parser::{clause_name, is_infix, is_postfix};
use crate::clause_types::*; use crate::clause_types::*;
use crate::machine::loader::PredicateQueue;
use crate::machine::machine_errors::*; use crate::machine::machine_errors::*;
use crate::machine::machine_indices::*; use crate::machine::machine_indices::*;
use crate::rug::{Integer, Rational}; use crate::rug::{Integer, Rational};
@@ -114,7 +115,7 @@ impl ListingSource {
} }
pub trait ClauseInfo { pub trait ClauseInfo {
fn is_consistent(&self, clauses: &Vec<PredicateClause>) -> bool { fn is_consistent(&self, clauses: &PredicateQueue) -> bool {
match clauses.first() { match clauses.first() {
Some(cl) => self.name() == cl.name() && self.arity() == cl.arity(), Some(cl) => self.name() == cl.name() && self.arity() == cl.arity(),
None => true, None => true,
@@ -442,7 +443,8 @@ pub struct Module {
pub code_dir: CodeDir, pub code_dir: CodeDir,
pub op_dir: OpDir, pub op_dir: OpDir,
pub meta_predicates: MetaPredicateDir, 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 is_impromptu_module: bool,
pub listing_src: ListingSource, pub listing_src: ListingSource,
pub clause_assert_margin: usize, pub clause_assert_margin: usize,
@@ -457,7 +459,8 @@ impl Module {
op_dir: default_op_dir(), op_dir: default_op_dir(),
meta_predicates: MetaPredicateDir::new(), meta_predicates: MetaPredicateDir::new(),
is_impromptu_module: false, is_impromptu_module: false,
extensible_predicates: IndexMap::new(), extensible_predicates: ExtensiblePredicates::new(),
local_extensible_predicates: LocalExtensiblePredicates::new(),
listing_src, listing_src,
clause_assert_margin: 0, clause_assert_margin: 0,
} }

View File

@@ -175,11 +175,19 @@ expand_term_goals(Terms0, Terms) :-
( Terms0 = (Head1 :- Body0) -> ( Terms0 = (Head1 :- Body0) ->
( var(Head1) -> ( var(Head1) ->
instantiation_error(load/1) 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), ; prolog_load_context(module, Target),
module_expanded_head_variables(Head1, HeadVars), module_expanded_head_variables(Head1, HeadVars),
expand_goal(Body0, Target, Body1, HeadVars) expand_goal(Body0, Target, Body1, HeadVars),
),
Terms = (Head1 :- Body1) Terms = (Head1 :- Body1)
)
; Terms = Terms0 ; Terms = Terms0
). ).
@@ -205,7 +213,7 @@ compile_dispatch_or_clause(Term, Evacuable, VNs) :-
instantiation_error(load/1) instantiation_error(load/1)
; compile_dispatch(Term, Evacuable, VNs) -> ; compile_dispatch(Term, Evacuable, VNs) ->
true true
; compile_clause(Term, Evacuable, VNs) ; compile_clause(Term, Evacuable)
). ).
@@ -257,9 +265,14 @@ compile_declaration(initialization(Goal), Evacuable) :-
assertz(Module:'$initialization_goals'(Goal)). assertz(Module:'$initialization_goals'(Goal)).
compile_clause((Target:Head :- Body), Evacuable) :-
compile_clause(Clause, Evacuable, VNs) :- !,
'$clause_to_evacuable'(Clause, Evacuable, VNs). '$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) :- prolog_load_context(source, Source) :-

View File

@@ -1010,18 +1010,22 @@ impl<'a> LoadState<'a> {
fn compile( fn compile(
&mut self, &mut self,
key: PredicateKey, key: PredicateKey,
predicates: &Vec<PredicateClause>, predicates: &PredicateQueue, // &Vec<PredicateClause>,
queue: &VecDeque<TopLevel>, queue: &VecDeque<TopLevel>,
settings: CodeGenSettings, settings: CodeGenSettings,
) -> Result<IndexPtr, SessionError> { ) -> 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 code_len = self.wam.code_repo.code.len();
let mut code_ptr = code_len; let mut code_ptr = code_len;
let mut cg = let mut cg =
CodeGenerator::<DebrayAllocator>::new(self.wam.machine_st.atom_tbl.clone(), settings); 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( compile_appendix(
&mut code, &mut code,
@@ -1047,12 +1051,12 @@ impl<'a> LoadState<'a> {
match self match self
.wam .wam
.indices .indices
.get_predicate_skeleton_mut(&self.compilation_target, &key) .get_predicate_skeleton_mut(&predicates.compilation_target, &key)
{ {
Some(skeleton) => { Some(skeleton) => {
self.retraction_info self.retraction_info
.push_record(RetractionRecord::SkeletonClauseTruncateBack( .push_record(RetractionRecord::SkeletonClauseTruncateBack(
self.compilation_target.clone(), predicates.compilation_target.clone(),
key.clone(), key.clone(),
skeleton.clauses.len(), skeleton.clauses.len(),
)); ));
@@ -1060,14 +1064,18 @@ impl<'a> LoadState<'a> {
skeleton.clauses.extend(cg.skeleton.clauses.into_iter()); skeleton.clauses.extend(cg.skeleton.clauses.into_iter());
} }
None => { None => {
self.add_extensible_predicate(key.clone(), cg.skeleton); self.add_extensible_predicate(
key.clone(),
cg.skeleton,
predicates.compilation_target.clone(),
);
} }
} }
} }
set_code_index( set_code_index(
&mut self.retraction_info, &mut self.retraction_info,
&self.compilation_target, &predicates.compilation_target,
key, key,
&code_index, &code_index,
IndexPtr::Index(code_ptr), IndexPtr::Index(code_ptr),
@@ -1080,10 +1088,11 @@ impl<'a> LoadState<'a> {
fn record_incremental_compile( fn record_incremental_compile(
&mut self, &mut self,
key: PredicateKey, key: PredicateKey,
compilation_target: CompilationTarget,
append_or_prepend: AppendOrPrepend, append_or_prepend: AppendOrPrepend,
) { ) {
self.retraction_info self.retraction_info
.push_record(match &self.compilation_target { .push_record(match compilation_target {
CompilationTarget::User => match append_or_prepend { CompilationTarget::User => match append_or_prepend {
AppendOrPrepend::Append => { AppendOrPrepend::Append => {
RetractionRecord::AppendedUserExtensiblePredicate(key) RetractionRecord::AppendedUserExtensiblePredicate(key)
@@ -1092,14 +1101,14 @@ impl<'a> LoadState<'a> {
RetractionRecord::PrependedUserExtensiblePredicate(key) RetractionRecord::PrependedUserExtensiblePredicate(key)
} }
}, },
CompilationTarget::Module(ref module_name) => match append_or_prepend { CompilationTarget::Module(module_name) => match append_or_prepend {
AppendOrPrepend::Append => RetractionRecord::AppendedModuleExtensiblePredicate( AppendOrPrepend::Append => RetractionRecord::AppendedModuleExtensiblePredicate(
module_name.clone(), module_name,
key, key,
), ),
AppendOrPrepend::Prepend => { AppendOrPrepend::Prepend => {
RetractionRecord::PrependedModuleExtensiblePredicate( RetractionRecord::PrependedModuleExtensiblePredicate(
module_name.clone(), module_name,
key, key,
) )
} }
@@ -1112,21 +1121,30 @@ impl<'a> LoadState<'a> {
key: PredicateKey, key: PredicateKey,
clause: PredicateClause, clause: PredicateClause,
queue: VecDeque<TopLevel>, queue: VecDeque<TopLevel>,
compilation_target: CompilationTarget,
non_counted_bt: bool, non_counted_bt: bool,
append_or_prepend: AppendOrPrepend, append_or_prepend: AppendOrPrepend,
) -> Result<IndexPtr, SessionError> { ) -> 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 let skeleton = match self
.wam .wam
.indices .indices
.get_predicate_skeleton_mut(&self.compilation_target, &key) .get_predicate_skeleton_mut(&compilation_target, &key)
{ {
Some(skeleton) if !skeleton.clauses.is_empty() => skeleton, Some(skeleton) if !skeleton.clauses.is_empty() => skeleton,
_ => { _ => {
// true because this predicate is extensible. // true because this predicate is extensible.
let settings = CodeGenSettings::new(true, non_counted_bt); 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 self.retraction_info
.push_record(RetractionRecord::SkeletonClausePopBack( .push_record(RetractionRecord::SkeletonClausePopBack(
self.compilation_target.clone(), compilation_target.clone(),
key.clone(), key.clone(),
)); ));
@@ -1157,12 +1175,15 @@ impl<'a> LoadState<'a> {
&mut self.retraction_info, &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 { if let Some(new_code_index) = result {
set_code_index( set_code_index(
&mut self.retraction_info, &mut self.retraction_info,
&self.compilation_target, &compilation_target,
key, key,
&code_index, &code_index,
IndexPtr::Index(new_code_index), IndexPtr::Index(new_code_index),
@@ -1178,24 +1199,27 @@ impl<'a> LoadState<'a> {
self.retraction_info self.retraction_info
.push_record(RetractionRecord::SkeletonClausePopFront( .push_record(RetractionRecord::SkeletonClausePopFront(
self.compilation_target.clone(), compilation_target.clone(),
key.clone(), key.clone(),
)); ));
let threaded_choice_instr_loc = prepend_compiled_clause( let threaded_choice_instr_loc = prepend_compiled_clause(
&mut self.wam.code_repo.code, &mut self.wam.code_repo.code,
self.compilation_target.clone(), compilation_target.clone(),
key.clone(), key.clone(),
clause_code, clause_code,
skeleton, skeleton,
&mut self.retraction_info, &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( set_code_index(
&mut self.retraction_info, &mut self.retraction_info,
&self.compilation_target, &compilation_target,
key, key,
&code_index, &code_index,
IndexPtr::Index(threaded_choice_instr_loc), 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 { 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 let skeleton = match self
.wam .wam
@@ -1516,40 +1543,47 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
_ => compilation_target.clone(), _ => 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![]; let mut clause_clause_locs = sdeq![];
for clause_predicate in clause_predicates { for clause_predicate in clause_predicates {
clause_clause_locs.push_back(self.load_state.wam.code_repo.code.len()); 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_name!("$clause"), 2),
clause_predicate, clause_predicate,
VecDeque::new(), VecDeque::new(),
clause_clause_compilation_target.clone(),
false, // non_counted_bt is false. false, // non_counted_bt is false.
append_or_prepend, 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( match self.load_state.wam.indices.get_predicate_skeleton_mut(
&self.load_state.compilation_target, &clause_clause_compilation_target,
&(clause_name!("$clause"), 2), &(clause_name!("$clause"), 2),
) { ) {
Some(skeleton) if append_or_prepend.is_append() => { 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 skeleton
.clause_clause_locs .clause_clause_locs
.extend_from_slice(&clause_clause_locs[0..]); .extend_from_slice(&clause_clause_locs[0..]);
} }
Some(skeleton) => { 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() { for loc in clause_clause_locs.iter() {
skeleton.clause_clause_locs.push_front(*loc); 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); skeleton.clause_clause_locs.push_front(*loc);
} }
self.load_state self.load_state.increment_clause_assert_margin(
.increment_clause_assert_margin(clause_clause_locs.len()); clause_clause_compilation_target,
clause_clause_locs.len(),
);
} }
None => { None => {
unreachable!(); unreachable!()
} }
} }
self.load_state.compilation_target = old_compilation_target;
Ok(()) Ok(())
} }
@@ -1617,7 +1652,7 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
.load_state .load_state
.wam .wam
.indices .indices
.get_predicate_skeleton(&self.load_state.compilation_target, &key) .get_predicate_skeleton(&self.predicates.compilation_target, &key)
.map(|skeleton| (skeleton.is_dynamic, true)) .map(|skeleton| (skeleton.is_dynamic, true))
.unwrap_or((false, false)); .unwrap_or((false, false));
@@ -1629,7 +1664,7 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
if is_dynamic { if is_dynamic {
let iter = mem::replace(&mut self.clause_clauses, vec![]).into_iter(); 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)?; self.compile_clause_clauses(key, compilation_target, iter, AppendOrPrepend::Append)?;
} }

View File

@@ -329,21 +329,25 @@ fn import_qualified_module_exports_into_module(
impl<'a> LoadState<'a> { impl<'a> LoadState<'a> {
#[inline] #[inline]
pub(super) fn increment_clause_assert_margin(&mut self, incr: usize) { pub(super) fn increment_clause_assert_margin(
match &self.compilation_target { &mut self,
compilation_target: CompilationTarget,
incr: usize,
) {
match compilation_target {
CompilationTarget::User => {} CompilationTarget::User => {}
CompilationTarget::Module(ref module_name) => { CompilationTarget::Module(module_name) => {
self.retraction_info
.push_record(RetractionRecord::IncreasedClauseAssertMargin(
module_name.clone(),
incr,
));
self.wam self.wam
.indices .indices
.modules .modules
.get_mut(module_name) .get_mut(&module_name)
.map(|module| module.clause_assert_margin += incr); .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 { pub(super) fn get_or_insert_code_index(
match self.compilation_target.clone() { &mut self,
key: PredicateKey,
compilation_target: CompilationTarget,
) -> CodeIndex {
match compilation_target {
CompilationTarget::User => self CompilationTarget::User => self
.wam .wam
.indices .indices
@@ -434,8 +442,9 @@ impl<'a> LoadState<'a> {
&mut self, &mut self,
key: PredicateKey, key: PredicateKey,
skeleton: PredicateSkeleton, skeleton: PredicateSkeleton,
compilation_target: CompilationTarget,
) { ) {
match &self.compilation_target { match compilation_target {
CompilationTarget::User => { CompilationTarget::User => {
self.wam self.wam
.indices .indices
@@ -445,12 +454,12 @@ impl<'a> LoadState<'a> {
self.retraction_info self.retraction_info
.push_record(RetractionRecord::AddedUserExtensiblePredicate(key)); .push_record(RetractionRecord::AddedUserExtensiblePredicate(key));
} }
CompilationTarget::Module(ref module_name) => { CompilationTarget::Module(module_name) => {
if let Some(module) = self.wam.indices.modules.get_mut(module_name) { if let Some(module) = self.wam.indices.modules.get_mut(&module_name) {
module.extensible_predicates.insert(key.clone(), skeleton); module.extensible_predicates.insert(key.clone(), skeleton);
self.retraction_info.push_record( self.retraction_info.push_record(
RetractionRecord::AddedModuleExtensiblePredicate(module_name.clone(), key), RetractionRecord::AddedModuleExtensiblePredicate(module_name, key),
); );
} else { } else {
unreachable!() unreachable!()
@@ -497,11 +506,19 @@ impl<'a> LoadState<'a> {
) -> ClauseType { ) -> ClauseType {
match ClauseType::from(name, arity, fixity) { match ClauseType::from(name, arity, fixity) {
ClauseType::Named(name, arity, _) => { 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::Named(name, arity, idx)
} }
ClauseType::Op(name, fixity, _) => { 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) ClauseType::Op(name, fixity, idx)
} }
ct => ct, ct => ct,

View File

@@ -557,7 +557,7 @@ impl<'a> Drop for LoadState<'a> {
} }
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone, PartialEq, Eq)]
pub enum CompilationTarget { pub enum CompilationTarget {
Module(ClauseName), Module(ClauseName),
User, 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(crate) struct Loader<'a, TermStream> {
pub(super) load_state: LoadState<'a>, pub(super) load_state: LoadState<'a>,
pub(super) predicates: Vec<PredicateClause>, pub(super) predicates: PredicateQueue,
pub(super) clause_clauses: Vec<(Term, Term)>, pub(super) clause_clauses: Vec<(Term, Term)>,
term_stream: TermStream, term_stream: TermStream,
pub(super) non_counted_bt_preds: IndexSet<PredicateKey>, pub(super) non_counted_bt_preds: IndexSet<PredicateKey>,
@@ -612,7 +661,7 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
term_stream, term_stream,
non_counted_bt_preds: IndexSet::new(), non_counted_bt_preds: IndexSet::new(),
preprocessor: Preprocessor::new(flags), preprocessor: Preprocessor::new(flags),
predicates: vec![], predicates: predicate_queue![],
clause_clauses: vec![], clause_clauses: vec![],
} }
} }
@@ -643,7 +692,7 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
match tl { match tl {
TopLevel::Fact(fact) => self.predicates.push(PredicateClause::Fact(fact)), TopLevel::Fact(fact) => self.predicates.push(PredicateClause::Fact(fact)),
TopLevel::Rule(rule) => self.predicates.push(PredicateClause::Rule(rule)), 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::Declaration(decl) => return Ok(Some(decl)),
TopLevel::Query(_) => return Err(SessionError::QueryCannotBeDefinedAsFact), TopLevel::Query(_) => return Err(SessionError::QueryCannotBeDefinedAsFact),
} }
@@ -665,6 +714,9 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
self.load_state.compilation_target = self.load_state.compilation_target =
CompilationTarget::Module(module_decl.name.clone()); CompilationTarget::Module(module_decl.name.clone());
self.predicates.compilation_target =
self.load_state.compilation_target.clone();
self.load_state self.load_state
.add_module(module_decl, self.term_stream.listing_src().clone()); .add_module(module_decl, self.term_stream.listing_src().clone());
} }
@@ -827,14 +879,10 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
} }
} }
None => { None => {
self.load_state self.load_state.add_extensible_predicate(
.wam key.clone(),
.indices PredicateSkeleton::new().set_dynamic(true),
.extensible_predicates CompilationTarget::User,
.insert(key.clone(), PredicateSkeleton::new().set_dynamic(true));
self.load_state.retraction_info.push_record(
RetractionRecord::AddedUserExtensiblePredicate(key.clone()),
); );
} }
} }
@@ -855,15 +903,10 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
} }
} }
None => { None => {
module self.load_state.add_extensible_predicate(
.extensible_predicates
.insert(key.clone(), PredicateSkeleton::new().set_dynamic(true));
self.load_state.retraction_info.push_record(
RetractionRecord::AddedModuleExtensiblePredicate(
module_name.clone(),
key.clone(), 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( set_code_index(
&mut self.load_state.retraction_info, &mut self.load_state.retraction_info,
@@ -884,6 +930,29 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
IndexPtr::DynamicUndefined, 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 { impl Machine {
@@ -1180,36 +1249,29 @@ impl Machine {
} }
} }
pub(crate) fn clause_to_evacuable(&mut self) { pub(crate) fn scoped_clause_to_evacuable(&mut self) {
let (mut loader, evacuable_h) = self.loader_from_heap_evacuable(temp_v!(2)); 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 (loader, evacuable_h) = self.loader_from_heap_evacuable(temp_v!(3));
let term = loader.read_term_from_heap(temp_v!(1))?;
if let Some(predicate_name) = ClauseInfo::name(&term) { let compilation_target = match module_name.as_str() {
let arity = ClauseInfo::arity(&term); "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())?;
}
}
loader.enqueue_term(term);
loader.load()
}; };
let result = enqueue_term(); let result = loader.read_and_enqueue_term(temp_v!(2), compilation_target);
self.restore_load_state_payload(result, evacuable_h);
}
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 = loader.read_and_enqueue_term(temp_v!(1), compilation_target);
self.restore_load_state_payload(result, evacuable_h); self.restore_load_state_payload(result, evacuable_h);
} }
@@ -1470,7 +1532,11 @@ impl Machine {
skeleton.clause_clause_locs.clear(); 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); code_index.set(IndexPtr::DynamicUndefined);
loader.load_state.compilation_target = clause_clause_compilation_target; loader.load_state.compilation_target = clause_clause_compilation_target;
@@ -1778,7 +1844,7 @@ impl<'a> Loader<'a, LiveTermStream> {
&mut self.load_state.retraction_info, &mut self.load_state.retraction_info,
RetractionInfo::new(self.load_state.wam.code_repo.code.len()), 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![]), clause_clauses: mem::replace(&mut self.clause_clauses, vec![]),
module_op_exports: mem::replace(&mut self.load_state.module_op_exports, 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()), non_counted_bt_preds: mem::replace(&mut payload.non_counted_bt_preds, IndexSet::new()),
clause_clauses: mem::replace(&mut payload.clause_clauses, vec![]), clause_clauses: mem::replace(&mut payload.clause_clauses, vec![]),
predicates: mem::replace(&mut payload.predicates, vec![]), predicates: payload.predicates.take(),
load_state: LoadState { load_state: LoadState {
compilation_target: payload.compilation_target.take(), compilation_target: payload.compilation_target.take(),
module_op_exports: mem::replace(&mut payload.module_op_exports, vec![]), module_op_exports: mem::replace(&mut payload.module_op_exports, vec![]),
@@ -1819,7 +1885,11 @@ impl<'a> Loader<'a, LiveTermStream> {
) -> Result<(), SessionError> { ) -> Result<(), SessionError> {
let mut preprocessor = Preprocessor::new(self.load_state.wam.machine_st.flags); 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)?; let queue = preprocessor.parse_queue(&mut self.load_state)?;
@@ -1831,26 +1901,37 @@ impl<'a> Loader<'a, LiveTermStream> {
} }
}; };
let compilation_target = self.load_state.incremental_compile_clause(
mem::replace(&mut self.load_state.compilation_target, compilation_target);
let result = self.load_state.incremental_compile_clause(
key, key,
clause, clause,
queue, queue,
compilation_target,
non_counted_bt, non_counted_bt,
append_or_prepend, append_or_prepend,
); )?;
self.load_state.compilation_target = compilation_target;
result?;
Ok(()) Ok(())
} }
#[inline] fn read_and_enqueue_term(
fn enqueue_term(&mut self, term: 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.term_stream.term_queue.push_back(term);
self.load()
} }
} }

View File

@@ -421,6 +421,7 @@ pub enum REPLCodePtr {
AddGoalExpansionClause, AddGoalExpansionClause,
AddTermExpansionClause, AddTermExpansionClause,
ClauseToEvacuable, ClauseToEvacuable,
ScopedClauseToEvacuable,
ConcludeLoad, ConcludeLoad,
DeclareModule, DeclareModule,
LoadCompiledLibrary, LoadCompiledLibrary,
@@ -692,7 +693,6 @@ pub(crate) struct ModuleStub {
pub(crate) in_situ_code_dir: InSituCodeDir, pub(crate) in_situ_code_dir: InSituCodeDir,
} }
// pub(crate) type ModuleStubDir = IndexMap<ClauseName, ModuleStub>;
pub(crate) type StreamAliasDir = IndexMap<ClauseName, Stream>; pub(crate) type StreamAliasDir = IndexMap<ClauseName, Stream>;
pub(crate) type StreamDir = BTreeSet<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 ExtensiblePredicates = IndexMap<PredicateKey, PredicateSkeleton>;
pub type LocalExtensiblePredicates = IndexMap<(CompilationTarget, PredicateKey), PredicateSkeleton>;
#[derive(Debug)] #[derive(Debug)]
pub struct IndexStore { pub struct IndexStore {
pub(super) code_dir: CodeDir, pub(super) code_dir: CodeDir,
pub(super) extensible_predicates: ExtensiblePredicates, pub(super) extensible_predicates: ExtensiblePredicates,
pub(super) local_extensible_predicates: LocalExtensiblePredicates,
pub(super) global_variables: GlobalVarDir, pub(super) global_variables: GlobalVarDir,
pub(super) meta_predicates: MetaPredicateDir, pub(super) meta_predicates: MetaPredicateDir,
pub(super) modules: ModuleDir, pub(super) modules: ModuleDir,

View File

@@ -15,11 +15,12 @@ use crate::read::*;
mod attributed_variables; mod attributed_variables;
pub(super) mod code_repo; pub(super) mod code_repo;
pub mod code_walker; pub mod code_walker;
#[macro_use]
pub(crate) mod loader;
mod compile; mod compile;
mod copier; mod copier;
pub mod heap; pub mod heap;
mod load_state; mod load_state;
mod loader;
pub mod machine_errors; pub mod machine_errors;
pub mod machine_indices; pub mod machine_indices;
pub(super) mod machine_state; pub(super) mod machine_state;
@@ -36,10 +37,8 @@ mod arithmetic_ops;
mod machine_state_impl; mod machine_state_impl;
mod system_calls; mod system_calls;
//use crate::machine::attributed_variables::*;
use crate::machine::code_repo::*; use crate::machine::code_repo::*;
use crate::machine::compile::*; use crate::machine::compile::*;
// use crate::machine::loader::*;
use crate::machine::machine_errors::*; use crate::machine::machine_errors::*;
use crate::machine::machine_indices::*; use crate::machine::machine_indices::*;
use crate::machine::machine_state::*; use crate::machine::machine_state::*;
@@ -425,6 +424,9 @@ impl Machine {
REPLCodePtr::ClauseToEvacuable => { REPLCodePtr::ClauseToEvacuable => {
self.clause_to_evacuable(); self.clause_to_evacuable();
} }
REPLCodePtr::ScopedClauseToEvacuable => {
self.scoped_clause_to_evacuable();
}
REPLCodePtr::ConcludeLoad => { REPLCodePtr::ConcludeLoad => {
self.conclude_load(); self.conclude_load();
} }

View File

@@ -780,7 +780,8 @@ impl Preprocessor {
query_term query_term
}) })
} else { } 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), _ => self.to_query_term(load_state, term),
@@ -831,8 +832,11 @@ impl Preprocessor {
cut_context: CutContext, cut_context: CutContext,
) -> Result<Rule, CompilationError> { ) -> Result<Rule, CompilationError> {
let post_head_terms: Vec<_> = terms.drain(1..).collect(); let post_head_terms: Vec<_> = terms.drain(1..).collect();
let mut query_terms = self.setup_query(
let mut query_terms = self.setup_query(load_state, post_head_terms, cut_context)?; load_state,
post_head_terms,
cut_context,
)?;
let clauses = query_terms.drain(1..).collect(); let clauses = query_terms.drain(1..).collect();
let qt = query_terms.pop().unwrap(); let qt = query_terms.pop().unwrap();
@@ -899,7 +903,11 @@ impl Preprocessor {
let mut results = VecDeque::new(); let mut results = VecDeque::new();
for term in terms.into_iter() { 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) Ok(results)

View File

@@ -101,7 +101,7 @@ pub struct LoadStatePayload {
pub(super) module_op_exports: Vec<(OpDecl, Option<(usize, Specifier)>)>, pub(super) module_op_exports: Vec<(OpDecl, Option<(usize, Specifier)>)>,
pub(super) non_counted_bt_preds: IndexSet<PredicateKey>, pub(super) non_counted_bt_preds: IndexSet<PredicateKey>,
pub(super) preprocessor: Preprocessor, pub(super) preprocessor: Preprocessor,
pub(super) predicates: Vec<PredicateClause>, pub(super) predicates: PredicateQueue,
pub(super) clause_clauses: Vec<(Term, Term)>, pub(super) clause_clauses: Vec<(Term, Term)>,
} }
@@ -120,7 +120,7 @@ impl LoadStatePayload {
module_op_exports: vec![], module_op_exports: vec![],
non_counted_bt_preds: IndexSet::new(), non_counted_bt_preds: IndexSet::new(),
preprocessor: Preprocessor::new(wam.machine_st.flags), preprocessor: Preprocessor::new(wam.machine_st.flags),
predicates: vec![], predicates: predicate_queue![],
clause_clauses: vec![], clause_clauses: vec![],
} }
} }

View File

@@ -362,6 +362,7 @@ macro_rules! index_store {
IndexStore { IndexStore {
code_dir: $code_dir, code_dir: $code_dir,
extensible_predicates: ExtensiblePredicates::new(), extensible_predicates: ExtensiblePredicates::new(),
local_extensible_predicates: LocalExtensiblePredicates::new(),
global_variables: GlobalVarDir::new(), global_variables: GlobalVarDir::new(),
meta_predicates: MetaPredicateDir::new(), meta_predicates: MetaPredicateDir::new(),
modules: $modules, modules: $modules,

View File

@@ -36,6 +36,8 @@ impl fmt::Display for REPLCodePtr {
write!(f, "REPLCodePtr::Retract"), write!(f, "REPLCodePtr::Retract"),
REPLCodePtr::ClauseToEvacuable => REPLCodePtr::ClauseToEvacuable =>
write!(f, "REPLCodePtr::ClauseToEvacuable"), write!(f, "REPLCodePtr::ClauseToEvacuable"),
REPLCodePtr::ScopedClauseToEvacuable =>
write!(f, "REPLCodePtr::ScopedClauseToEvacuable"),
REPLCodePtr::ConcludeLoad => REPLCodePtr::ConcludeLoad =>
write!(f, "REPLCodePtr::ConcludeLoad"), write!(f, "REPLCodePtr::ConcludeLoad"),
REPLCodePtr::DeclareModule => REPLCodePtr::DeclareModule =>