compile scoped clauses from loader.pl
This commit is contained in:
@@ -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)),
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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) :-
|
||||
|
||||
@@ -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)?;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 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 compilation_target = match module_name.as_str() {
|
||||
"user" => CompilationTarget::User,
|
||||
_ => CompilationTarget::Module(module_name),
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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![],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 =>
|
||||
|
||||
Reference in New Issue
Block a user