fix several issues with goal expansion, crashing after attribute_goals is called

This commit is contained in:
Mark Thom
2019-10-08 12:28:23 -06:00
parent 673fb31ae2
commit 3409db010f
8 changed files with 150 additions and 180 deletions

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "scryer-prolog" name = "scryer-prolog"
version = "0.8.103" version = "0.8.104"
authors = ["Mark Thom <markjordanthom@gmail.com>"] authors = ["Mark Thom <markjordanthom@gmail.com>"]
build = "build.rs" build = "build.rs"
repository = "https://github.com/mthom/scryer-prolog" repository = "https://github.com/mthom/scryer-prolog"

View File

@@ -18,7 +18,8 @@
'$default_attr_list'([PG | PGs], Module, AttrVar) --> '$default_attr_list'([PG | PGs], Module, AttrVar) -->
( { '$module_of'(Module, PG) } -> [Module:put_atts(AttrVar, PG)] ( { '$module_of'(Module, PG) } -> [Module:put_atts(AttrVar, PG)]
; { true } ), ; true
),
'$default_attr_list'(PGs, Module, AttrVar). '$default_attr_list'(PGs, Module, AttrVar).
'$default_attr_list'([], _, _) --> []. '$default_attr_list'([], _, _) --> [].

View File

@@ -160,6 +160,7 @@ comma_errors(G1, G2, B) :- '$call_with_default_policy'(','(G1, G2, B)).
:- non_counted_backtracking (;)/3. :- non_counted_backtracking (;)/3.
;(G1, G4, B) :- compound(G1), ;(G1, G4, B) :- compound(G1),
'$call_with_default_policy'(G1 = ->(G2, G3)), '$call_with_default_policy'(G1 = ->(G2, G3)),
!,
(G2 -> G3 ; '$set_cp'(B), G4). (G2 -> G3 ; '$set_cp'(B), G4).
;(G1, G2, B) :- G1 == !, '$set_cp'(B), G2. ;(G1, G2, B) :- G1 == !, '$set_cp'(B), G2.
;(G1, G2, B) :- G2 == !, G1, '$set_cp'(B). ;(G1, G2, B) :- G2 == !, G1, '$set_cp'(B).

View File

@@ -7,16 +7,7 @@
user:term_expansion(Term0, (Head :- Body)) :- user:term_expansion(Term0, (Head :- Body)) :-
dcg_rule(Term0, Term), dcg_rule(Term0, Term),
Term = (Head :- Body0), Term = (Head :- Body).
unravel_commas(Body0, Body).
unravel_commas(((A, B), C), Body) :-
!,
unravel_commas((B, C), Body0),
unravel_commas((A, Body0), Body).
unravel_commas((A, B), (A, Body0)) :-
!, unravel_commas(B, Body0).
unravel_commas(Body, Body).
phrase(GRBody, S0) :- phrase(GRBody, S0) :-
phrase(GRBody, S0, []). phrase(GRBody, S0, []).

View File

@@ -901,7 +901,7 @@ impl ListingCompiler {
CodeIndex::dynamic_undefined(self.get_module_name())); CodeIndex::dynamic_undefined(self.get_module_name()));
} }
&Declaration::Hook(hook, _, ref queue) if self.module.is_none() => worker &Declaration::Hook(hook, _, ref queue) if self.module.is_none() => worker
.term_stream .term_stream
.incr_expansion_lens(hook.user_scope(), 1, queue.len()), .incr_expansion_lens(hook.user_scope(), 1, queue.len()),
&Declaration::Hook(hook, _, ref queue) if !hook.has_module_scope() => { &Declaration::Hook(hook, _, ref queue) if !hook.has_module_scope() => {
worker.term_stream.incr_expansion_lens(hook, 1, queue.len()) worker.term_stream.incr_expansion_lens(hook, 1, queue.len())

View File

@@ -15,11 +15,16 @@ enqueue_goals(Goals0) :-
enqueue_goals(Goals). enqueue_goals(Goals).
enqueue_goals(_). enqueue_goals(_).
'$print_exception'(E) :-
write_term('caught: ', [quoted(false)]),
writeq(E),
nl.
call_project_attributes([], _, _). call_project_attributes([], _, _).
call_project_attributes([Module|Modules], QueryVars, AttrVars) :- call_project_attributes([Module|Modules], QueryVars, AttrVars) :-
( catch(Module:project_attributes(QueryVars, AttrVars), ( catch(Module:project_attributes(QueryVars, AttrVars),
error(evaluation_error((Module:project_attributes)/2), project_attributes/2), E, %error(evaluation_error((Module:project_attributes)/2), project_attributes/2),
true) -> true '$print_exception'(E)) -> true
; true ; true
), ),
call_project_attributes(Modules, QueryVars, AttrVars). call_project_attributes(Modules, QueryVars, AttrVars).
@@ -33,8 +38,8 @@ call_attribute_goals([Module | Modules], AttrVars) :-
call_goals([], _, []). call_goals([], _, []).
call_goals([AttrVar|AttrVars], Module, Goals) :- call_goals([AttrVar|AttrVars], Module, Goals) :-
( catch(Module:attribute_goals(AttrVar, Goals, RGoals), ( catch(Module:attribute_goals(AttrVar, Goals, RGoals),
error(evaluation_error((Module:attribute_goals)/3), attribute_goals/3), E, %error(evaluation_error((Module:attribute_goals)/3), attribute_goals/3),
atts:'$default_attr_list'(Module, AttrVar, Goals, RGoals)) -> true ('$print_exception'(E), atts:'$default_attr_list'(Module, AttrVar, Goals, RGoals))) -> true
; true ; true
), ),
call_goals(AttrVars, Module, RGoals). call_goals(AttrVars, Module, RGoals).

View File

@@ -313,12 +313,14 @@ impl<'a, R: Read> TermStream<'a, R> {
initial_term, initial_term,
clause_name!(","), clause_name!(","),
))); )));
Ok(Term::Clause(cell, name, terms, arity)) Ok(Term::Clause(cell, name, terms, arity))
} }
_ => Ok(term), _ => Ok(term),
} }
} }
pub(super)
fn expand_goals( fn expand_goals(
&mut self, &mut self,
machine_st: &mut MachineState, machine_st: &mut MachineState,
@@ -327,7 +329,7 @@ impl<'a, R: Read> TermStream<'a, R> {
) -> Result<Vec<Term>, ParserError> { ) -> Result<Vec<Term>, ParserError> {
let mut results = vec![]; let mut results = vec![];
while let Some(term) = terms.pop_front() { while let Some(term) = terms.pop_front() {
match machine_st.try_expand_term(self.wam, &term, CompileTimeHook::GoalExpansion) { match machine_st.try_expand_term(self.wam, &term, CompileTimeHook::GoalExpansion) {
Some(term_string) => { Some(term_string) => {
let term = self.parse_expansion_output(term_string.as_str(), op_dir)?; let term = self.parse_expansion_output(term_string.as_str(), op_dir)?;

View File

@@ -5,7 +5,6 @@ use prolog::forms::*;
use prolog::iterators::*; use prolog::iterators::*;
use prolog::machine::machine_errors::*; use prolog::machine::machine_errors::*;
use prolog::machine::machine_indices::*; use prolog::machine::machine_indices::*;
use prolog::machine::machine_state::MachineState;
use prolog::machine::term_expansion::*; use prolog::machine::term_expansion::*;
use prolog::machine::*; use prolog::machine::*;
@@ -18,48 +17,75 @@ use std::io::Read;
use std::mem; use std::mem;
use std::rc::Rc; use std::rc::Rc;
struct CompositeIndices<'a, 'b> { enum IndexSource<'a, T> {
local: &'a mut IndexStore, TermStream,
static_code_dir: Option<&'b CodeDir>, Local(&'a mut T)
} }
macro_rules! composite_indices { fn op_dir<'a, 'b: 'a>(from: &'b IndexSource<'a, IndexStore>) -> RefOrOwned<'a, OpDir> {
($in_module: expr, $local: expr, $static_code_dir: expr) => { match from {
CompositeIndices { IndexSource::TermStream => RefOrOwned::Owned(OpDir::new()),
local: $local, IndexSource::Local(ref indices) => RefOrOwned::Borrowed(&indices.op_dir)
static_code_dir: if $in_module { }
None
} else {
Some($static_code_dir)
},
}
};
($local: expr) => {
CompositeIndices {
local: $local,
static_code_dir: None,
}
};
} }
impl<'a, 'b> CompositeIndices<'a, 'b> { struct CompositeIndices<'a, 'b, 'c, R: Read> {
term_stream: &'b mut TermStream<'a, R>,
index_src: IndexSource<'c, IndexStore>,
static_code_dir: Option<IndexSource<'c, CodeDir>>
}
impl<'a, 'b, 'c, R: Read> CompositeIndices<'a, 'b, 'c, R> {
fn new(
term_stream: &'b mut TermStream<'a, R>,
index_src: IndexSource<'c, IndexStore>,
static_code_dir: Option<IndexSource<'c, CodeDir>>,
) -> Self {
CompositeIndices {
term_stream,
index_src,
static_code_dir,
}
}
fn atom_tbl(&self) -> TabledData<Atom> {
match self.index_src {
IndexSource::TermStream => self.term_stream.wam.indices.atom_tbl.clone(),
IndexSource::Local(ref indices) => indices.atom_tbl.clone(),
}
}
fn local_code_dir(&mut self) -> &mut CodeDir {
match self.index_src {
IndexSource::TermStream => &mut self.term_stream.wam.indices.code_dir,
IndexSource::Local(ref mut indices) => &mut indices.code_dir,
}
}
fn static_code_dir(&self) -> Option<&CodeDir> {
match self.static_code_dir {
Some(IndexSource::TermStream) => Some(&self.term_stream.wam.indices.code_dir),
Some(IndexSource::Local(ref code_dir)) => Some(code_dir),
None => None
}
}
fn get_code_index(&mut self, name: ClauseName, arity: usize) -> CodeIndex { fn get_code_index(&mut self, name: ClauseName, arity: usize) -> CodeIndex {
let idx_opt = self let idx_opt = self.local_code_dir().get(&(name.clone(), arity));
.local let idx_opt = match idx_opt {
.code_dir Some(idx) => Some(idx.clone()),
.get(&(name.clone(), arity)) None => match self.static_code_dir() {
.or_else(|| match &self.static_code_dir { Some(ref code_dir) => code_dir.get(&(name.clone(), arity)).cloned(),
&Some(ref code_dir) => code_dir.get(&(name.clone(), arity)),
_ => None, _ => None,
}) }
.cloned(); };
if let Some(idx) = idx_opt { if let Some(idx) = idx_opt {
self.local.code_dir.insert((name, arity), idx.clone()); self.local_code_dir().insert((name, arity), idx.clone());
idx idx
} else { } else {
let idx = CodeIndex::default(); let idx = CodeIndex::default();
self.local.code_dir.insert((name, arity), idx.clone()); self.local_code_dir().insert((name, arity), idx.clone());
idx idx
} }
} }
@@ -400,7 +426,7 @@ fn check_for_internal_if_then(terms: &mut Vec<Term>) {
} }
fn flatten_hook(mut term: Term) -> Term { fn flatten_hook(mut term: Term) -> Term {
if let &mut Term::Clause(_, ref mut name, ref mut terms, _) = &mut term { if let Term::Clause(_, ref mut name, ref mut terms, _) = &mut term {
match (name.as_str(), terms.len()) { match (name.as_str(), terms.len()) {
(":-", 2) => { (":-", 2) => {
let inner_term = match terms.first_mut().map(|term| term.borrow_mut()) { let inner_term = match terms.first_mut().map(|term| term.borrow_mut()) {
@@ -426,8 +452,8 @@ fn flatten_hook(mut term: Term) -> Term {
term term
} }
fn setup_declaration( fn setup_declaration<'a, 'b, 'c, R: Read>(
indices: &mut CompositeIndices, indices: &mut CompositeIndices<'a, 'b, 'c, R>,
flags: MachineFlags, flags: MachineFlags,
mut terms: Vec<Box<Term>>, mut terms: Vec<Box<Term>>,
line_num: usize, line_num: usize,
@@ -439,7 +465,7 @@ fn setup_declaration(
Term::Clause(_, name, mut terms, _) => Term::Clause(_, name, mut terms, _) =>
match (name.as_str(), terms.len()) { match (name.as_str(), terms.len()) {
("op", 3) => ("op", 3) =>
Ok(Declaration::Op(setup_op_decl(terms, indices.local.atom_tbl.clone())?)), Ok(Declaration::Op(setup_op_decl(terms, indices.atom_tbl())?)),
("module", 2) => ("module", 2) =>
Ok(Declaration::Module(setup_module_decl(terms)?)), Ok(Declaration::Module(setup_module_decl(terms)?)),
("use_module", 1) => ("use_module", 1) =>
@@ -597,9 +623,9 @@ impl RelationWorker {
self.fabricate_rule(fold_by_str(prec_seq.into_iter(), body_term, comma_sym)) self.fabricate_rule(fold_by_str(prec_seq.into_iter(), body_term, comma_sym))
} }
fn to_query_term( fn to_query_term<'a, 'b, 'c, R: Read>(
&mut self, &mut self,
indices: &mut CompositeIndices, indices: &mut CompositeIndices<'a, 'b, 'c, R>,
term: Term, term: Term,
) -> Result<QueryTerm, ParserError> { ) -> Result<QueryTerm, ParserError> {
match term { match term {
@@ -657,37 +683,9 @@ impl RelationWorker {
} }
} }
// never blocks cuts in the consequent. fn pre_query_term<'a, 'b, 'c, R: Read>(
fn prepend_if_then(
&self,
prec: Term,
conq: Term,
queue: &mut VecDeque<Box<Term>>,
blocks_cuts: bool,
) {
let cut_symb = atom!("blocked_!");
let mut terms_seq = unfold_by_str(prec, ",");
terms_seq.push(Term::Constant(Cell::default(), cut_symb));
let mut conq_seq = unfold_by_str(conq, ",");
if !blocks_cuts {
for item in conq_seq.iter_mut() {
mark_cut_variable(item);
}
}
terms_seq.append(&mut conq_seq);
while let Some(term) = terms_seq.pop() {
queue.push_front(Box::new(term));
}
}
fn pre_query_term(
&mut self, &mut self,
indices: &mut CompositeIndices, indices: &mut CompositeIndices<'a, 'b, 'c, R>,
term: Term, term: Term,
) -> Result<QueryTerm, ParserError> { ) -> Result<QueryTerm, ParserError> {
match term { match term {
@@ -706,48 +704,64 @@ impl RelationWorker {
} }
} }
fn setup_query( fn setup_query<'a, 'b, 'c, R: Read>(
&mut self, &mut self,
indices: &mut CompositeIndices, indices: &mut CompositeIndices<'a, 'b, 'c, R>,
terms: Vec<Box<Term>>, terms: Vec<Box<Term>>,
blocks_cuts: bool, blocks_cuts: bool,
) -> Result<Vec<QueryTerm>, ParserError> { ) -> Result<Vec<QueryTerm>, ParserError> {
let mut query_terms = vec![]; let mut query_terms = vec![];
let mut work_queue = VecDeque::from(terms); let mut work_queue = VecDeque::from(terms);
let mut machine_st = MachineState::new();
while let Some(term) = work_queue.pop_front() { while let Some(term) = work_queue.pop_front() {
let mut term = *term; let mut term = *term;
// a (->) clause makes up the entire query. That's what the test confirms. if let Term::Clause(cell, name, terms, op_spec) = term {
if query_terms.is_empty() && work_queue.is_empty() { if name.as_str() == "," {
// check for ->, inline it if found. let term = Term::Clause(cell, name, terms, op_spec);
if let &mut Term::Clause(_, ref name, ref mut subterms, _) = &mut term { let mut subterms = unfold_by_str(term, ",");
if name.as_str() == "->" && subterms.len() == 2 {
let conq = *subterms.pop().unwrap();
let prec = *subterms.pop().unwrap();
self.prepend_if_then(prec, conq, &mut work_queue, blocks_cuts); while let Some(subterm) = subterms.pop() {
continue; work_queue.push_front(Box::new(subterm));
} }
continue;
} else {
term = Term::Clause(cell, name, terms, op_spec);
} }
} }
for mut subterm in unfold_by_str(term, ",") { let op_dir = op_dir(&indices.index_src);
let mut expanded_terms = indices.term_stream.expand_goals(
&mut machine_st,
op_dir.as_ref(),
VecDeque::from(vec![term])
)?;
while let Some(term) = expanded_terms.pop() {
work_queue.push_front(Box::new(term));
}
if let Some(term) = work_queue.pop_front() {
let mut term = *term;
if !blocks_cuts { if !blocks_cuts {
mark_cut_variable(&mut subterm); mark_cut_variable(&mut term);
} }
query_terms.push(self.pre_query_term(indices, subterm)?); query_terms.push(self.pre_query_term(indices, term)?);
} }
} }
Ok(query_terms) Ok(query_terms)
} }
fn setup_hook( fn setup_hook<'a, 'b, 'c, R: Read>(
&mut self, &mut self,
hook: CompileTimeHook, hook: CompileTimeHook,
indices: &mut CompositeIndices, indices: &mut CompositeIndices<'a, 'b, 'c, R>,
term: Term, term: Term,
) -> Result<CompileTimeHookCompileInfo, ParserError> { ) -> Result<CompileTimeHookCompileInfo, ParserError> {
match flatten_hook(term) { match flatten_hook(term) {
@@ -768,9 +782,9 @@ impl RelationWorker {
} }
} }
fn setup_rule( fn setup_rule<'a, 'b, 'c, R: Read>(
&mut self, &mut self,
indices: &mut CompositeIndices, indices: &mut CompositeIndices<'a, 'b, 'c, R>,
mut terms: Vec<Box<Term>>, mut terms: Vec<Box<Term>>,
blocks_cuts: bool, blocks_cuts: bool,
assume_dyn: bool, assume_dyn: bool,
@@ -801,9 +815,9 @@ impl RelationWorker {
} }
} }
fn try_term_to_query( fn try_term_to_query<'a, 'b, 'c, R: Read>(
&mut self, &mut self,
indices: &mut CompositeIndices, indices: &mut CompositeIndices<'a, 'b, 'c, R>,
terms: Vec<Box<Term>>, terms: Vec<Box<Term>>,
blocks_cuts: bool, blocks_cuts: bool,
) -> Result<TopLevel, ParserError> { ) -> Result<TopLevel, ParserError> {
@@ -814,9 +828,9 @@ impl RelationWorker {
)?)) )?))
} }
fn try_term_to_tl( fn try_term_to_tl<'a, 'b, 'c, R: Read>(
&mut self, &mut self,
indices: &mut CompositeIndices, indices: &mut CompositeIndices<'a, 'b, 'c, R>,
term: Term, term: Term,
blocks_cuts: bool, blocks_cuts: bool,
) -> Result<TopLevel, ParserError> { ) -> Result<TopLevel, ParserError> {
@@ -850,14 +864,14 @@ impl RelationWorker {
} }
} }
fn try_terms_to_tls<I>( fn try_terms_to_tls<'a, 'b, 'c, I, R>(
&mut self, &mut self,
indices: &mut CompositeIndices, indices: &mut CompositeIndices<'a, 'b, 'c, R>,
terms: I, terms: I,
blocks_cuts: bool, blocks_cuts: bool,
) -> Result<VecDeque<TopLevel>, ParserError> ) -> Result<VecDeque<TopLevel>, ParserError>
where where
I: IntoIterator<Item = Term>, I: IntoIterator<Item = Term>, R: Read
{ {
let mut results = VecDeque::new(); let mut results = VecDeque::new();
@@ -868,9 +882,9 @@ impl RelationWorker {
Ok(results) Ok(results)
} }
fn parse_queue( fn parse_queue<'a, 'b, 'c, R: Read>(
&mut self, &mut self,
indices: &mut CompositeIndices, indices: &mut CompositeIndices<'a, 'b, 'c, R>,
) -> Result<VecDeque<TopLevel>, ParserError> { ) -> Result<VecDeque<TopLevel>, ParserError> {
let mut queue = VecDeque::new(); let mut queue = VecDeque::new();
@@ -887,54 +901,6 @@ impl RelationWorker {
self.dynamic_clauses self.dynamic_clauses
.extend(other.dynamic_clauses.into_iter()); .extend(other.dynamic_clauses.into_iter());
} }
fn expand_queue_contents<R>(
&mut self,
term_stream: &mut TermStream<R>,
op_dir: &OpDir,
) -> Result<(), SessionError>
where
R: Read,
{
let mut machine_st = MachineState::new();
let mut new_queue = VecDeque::new();
while let Some(terms) = self.queue.pop_front() {
let mut new_terms = VecDeque::new();
for term in terms {
new_terms.push_back(term_stream.run_goal_expanders(
&mut machine_st,
&op_dir,
term,
)?);
}
new_queue.push_back(new_terms);
}
Ok(self.queue = new_queue)
}
}
fn term_to_toplevel<R>(
term_stream: &mut TermStream<R>,
code_dir: &mut CodeDir,
term: Term,
flags: MachineFlags,
) -> Result<(TopLevel, RelationWorker), ParserError>
where
R: Read,
{
let line_num = term_stream.line_num();
let col_num = term_stream.col_num();
let mut rel_worker = RelationWorker::new(flags, line_num, col_num);
let mut indices = composite_indices!(false, &mut term_stream.wam.indices, code_dir);
let tl = rel_worker.try_term_to_tl(&mut indices, term, true)?;
Ok((tl, rel_worker))
} }
pub fn stream_to_toplevel<R: Read>( pub fn stream_to_toplevel<R: Read>(
@@ -954,10 +920,17 @@ pub fn stream_to_toplevel<R: Read>(
let term = term_stream.read_term(&OpDir::new())?; let term = term_stream.read_term(&OpDir::new())?;
let mut code_dir = CodeDir::new(); let mut code_dir = CodeDir::new();
let (tl, mut rel_worker) = term_to_toplevel(&mut term_stream, &mut code_dir, term, flags)?; let line_num = term_stream.line_num();
rel_worker.expand_queue_contents(&mut term_stream, &OpDir::new())?; let col_num = term_stream.col_num();
let mut indices = composite_indices!(false, &mut term_stream.wam.indices, &mut code_dir); let mut rel_worker = RelationWorker::new(flags, line_num, col_num);
let mut indices = CompositeIndices::new(
&mut term_stream,
IndexSource::TermStream,
Some(IndexSource::Local(&mut code_dir))
);
let tl = rel_worker.try_term_to_tl(&mut indices, term, true)?;
let queue = rel_worker.parse_queue(&mut indices)?; let queue = rel_worker.parse_queue(&mut indices)?;
Ok(deque_to_packet(tl, queue)) Ok(deque_to_packet(tl, queue))
@@ -995,7 +968,7 @@ impl<'a, R: Read> TopLevelBatchWorker<'a, R> {
} }
fn try_term_to_tl( fn try_term_to_tl(
&self, &mut self,
indices: &mut IndexStore, indices: &mut IndexStore,
term: Term, term: Term,
) -> Result<(TopLevel, RelationWorker), SessionError> { ) -> Result<(TopLevel, RelationWorker), SessionError> {
@@ -1003,10 +976,10 @@ impl<'a, R: Read> TopLevelBatchWorker<'a, R> {
let col_num = self.term_stream.col_num(); let col_num = self.term_stream.col_num();
let mut new_rel_worker = RelationWorker::new(self.rel_worker.flags, line_num, col_num); let mut new_rel_worker = RelationWorker::new(self.rel_worker.flags, line_num, col_num);
let mut indices = composite_indices!( let mut indices = CompositeIndices::new(
self.in_module, &mut self.term_stream,
indices, IndexSource::Local(indices),
&self.term_stream.wam.indices.code_dir if self.in_module { None } else { Some(IndexSource::TermStream) }
); );
Ok(( Ok((
@@ -1020,24 +993,21 @@ impl<'a, R: Read> TopLevelBatchWorker<'a, R> {
indices: &mut IndexStore, indices: &mut IndexStore,
preds: &mut Vec<PredicateClause>, preds: &mut Vec<PredicateClause>,
) -> Result<(), SessionError> { ) -> Result<(), SessionError> {
self.rel_worker let mut indices = CompositeIndices::new(
.expand_queue_contents(&mut self.term_stream, &indices.op_dir)?; &mut self.term_stream,
IndexSource::Local(indices),
let mut indices = composite_indices!( if self.in_module { None } else { Some(IndexSource::TermStream) }
self.in_module,
indices,
&mut self.term_stream.wam.indices.code_dir
); );
let queue = self.rel_worker.parse_queue(&mut indices)?; let queue = self.rel_worker.parse_queue(&mut indices)?;
let result = (append_preds(preds), queue); let result = (append_preds(preds), queue);
let in_situ_code_dir = &mut self.term_stream.wam.indices.in_situ_code_dir; let in_situ_code_dir = &mut indices.term_stream.wam.indices.in_situ_code_dir;
self.term_stream.wam.code_repo.add_in_situ_result( indices.term_stream.wam.code_repo.add_in_situ_result(
&result, &result,
in_situ_code_dir, in_situ_code_dir,
self.term_stream.flags, indices.term_stream.flags,
)?; )?;
Ok(self.results.push(result)) Ok(self.results.push(result))