clone in situ compiled terms
This commit is contained in:
@@ -405,6 +405,46 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
|
|||||||
evaluator.eval(term)
|
evaluator.eval(term)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn compile_is_call(&mut self, terms: &'a Vec<Box<Term>>, code: &mut Code,
|
||||||
|
term_loc: GenContext, use_default_call_policy: bool)
|
||||||
|
-> Result<(), ParserError>
|
||||||
|
{
|
||||||
|
let (mut acode, at) = self.call_arith_eval(terms[1].as_ref(), 1)?;
|
||||||
|
code.append(&mut acode);
|
||||||
|
|
||||||
|
Ok(match terms[0].as_ref() {
|
||||||
|
&Term::Var(ref vr, ref name) => {
|
||||||
|
let mut target = Vec::new();
|
||||||
|
|
||||||
|
self.marker.reset_arg(2);
|
||||||
|
self.marker.mark_var(name.clone(), Level::Shallow, vr,
|
||||||
|
term_loc, &mut target);
|
||||||
|
|
||||||
|
if !target.is_empty() {
|
||||||
|
code.push(Line::Query(target));
|
||||||
|
}
|
||||||
|
|
||||||
|
if use_default_call_policy {
|
||||||
|
code.push(is_call_by_default!(temp_v!(1), at.unwrap_or(interm!(1))))
|
||||||
|
} else {
|
||||||
|
code.push(is_call!(temp_v!(1), at.unwrap_or(interm!(1))))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
&Term::Constant(_, ref c @ Constant::Number(_)) => {
|
||||||
|
code.push(query![put_constant!(Level::Shallow,
|
||||||
|
c.clone(),
|
||||||
|
temp_v!(1))]);
|
||||||
|
|
||||||
|
if use_default_call_policy {
|
||||||
|
code.push(is_call_by_default!(temp_v!(1), at.unwrap_or(interm!(1))))
|
||||||
|
} else {
|
||||||
|
code.push(is_call!(temp_v!(1), at.unwrap_or(interm!(1))))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => code.push(fail!())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn compile_seq(&mut self, iter: ChunkedIterator<'a>, conjunct_info: &ConjunctInfo<'a>,
|
fn compile_seq(&mut self, iter: ChunkedIterator<'a>, conjunct_info: &ConjunctInfo<'a>,
|
||||||
code: &mut Code, is_exposed: bool)
|
code: &mut Code, is_exposed: bool)
|
||||||
-> Result<(), ParserError>
|
-> Result<(), ParserError>
|
||||||
@@ -441,47 +481,9 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
|
|||||||
}),
|
}),
|
||||||
&QueryTerm::Clause(_, ClauseType::BuiltIn(BuiltInClauseType::Is(..)),
|
&QueryTerm::Clause(_, ClauseType::BuiltIn(BuiltInClauseType::Is(..)),
|
||||||
ref terms, use_default_call_policy)
|
ref terms, use_default_call_policy)
|
||||||
=>
|
=> self.compile_is_call(terms, code, term_loc, use_default_call_policy)?,
|
||||||
{
|
&QueryTerm::Clause(_, ClauseType::Inlined(ref ct), ref terms, _)
|
||||||
let (mut acode, at) = self.call_arith_eval(terms[1].as_ref(), 1)?;
|
=> self.compile_inlined(ct, terms, term_loc, code)?,
|
||||||
code.append(&mut acode);
|
|
||||||
|
|
||||||
match terms[0].as_ref() {
|
|
||||||
&Term::Var(ref vr, ref name) => {
|
|
||||||
let mut target = Vec::new();
|
|
||||||
|
|
||||||
self.marker.reset_arg(2);
|
|
||||||
self.marker.mark_var(name.clone(), Level::Shallow, vr,
|
|
||||||
term_loc, &mut target);
|
|
||||||
|
|
||||||
if !target.is_empty() {
|
|
||||||
code.push(Line::Query(target));
|
|
||||||
}
|
|
||||||
|
|
||||||
if use_default_call_policy {
|
|
||||||
code.push(is_call_by_default!(temp_v!(1), at.unwrap_or(interm!(1))));
|
|
||||||
} else {
|
|
||||||
code.push(is_call!(temp_v!(1), at.unwrap_or(interm!(1))));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
&Term::Constant(_, ref c @ Constant::Number(_)) => {
|
|
||||||
code.push(query![put_constant!(Level::Shallow,
|
|
||||||
c.clone(),
|
|
||||||
temp_v!(1))]);
|
|
||||||
|
|
||||||
if use_default_call_policy {
|
|
||||||
code.push(is_call_by_default!(temp_v!(1), at.unwrap_or(interm!(1))));
|
|
||||||
} else {
|
|
||||||
code.push(is_call!(temp_v!(1), at.unwrap_or(interm!(1))));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
code.push(fail!());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
&QueryTerm::Clause(_, ClauseType::Inlined(ref ct), ref terms, _) =>
|
|
||||||
try!(self.compile_inlined(ct, terms, term_loc, code)),
|
|
||||||
_ => {
|
_ => {
|
||||||
let num_perm_vars = if chunk_num == 0 {
|
let num_perm_vars = if chunk_num == 0 {
|
||||||
conjunct_info.perm_vars()
|
conjunct_info.perm_vars()
|
||||||
@@ -491,7 +493,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
|
|||||||
|
|
||||||
self.compile_query_line(term, term_loc, code, num_perm_vars, is_exposed);
|
self.compile_query_line(term, term_loc, code, num_perm_vars, is_exposed);
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.marker.reset_contents();
|
self.marker.reset_contents();
|
||||||
|
|||||||
@@ -490,6 +490,5 @@ fn setup_indices(wam: &mut Machine, indices: &mut IndexStore) -> Result<(), Sess
|
|||||||
pub fn compile_user_module<R: Read>(wam: &mut Machine, src: R) -> EvalSession {
|
pub fn compile_user_module<R: Read>(wam: &mut Machine, src: R) -> EvalSession {
|
||||||
let mut indices = default_index_store!(wam.indices.atom_tbl.clone());
|
let mut indices = default_index_store!(wam.indices.atom_tbl.clone());
|
||||||
try_eval_session!(setup_indices(wam, &mut indices));
|
try_eval_session!(setup_indices(wam, &mut indices));
|
||||||
|
|
||||||
compile_listing(wam, src, indices)
|
compile_listing(wam, src, indices)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -258,7 +258,6 @@ impl<'a> Allocator<'a> for DebrayAllocator
|
|||||||
RegType::Temp(0) => {
|
RegType::Temp(0) => {
|
||||||
// here, r is temporary *and* unassigned.
|
// here, r is temporary *and* unassigned.
|
||||||
let o = self.alloc_reg_to_var(&var, lvl, term_loc, target);
|
let o = self.alloc_reg_to_var(&var, lvl, term_loc, target);
|
||||||
|
|
||||||
cell.set(VarReg::Norm(RegType::Temp(o)));
|
cell.set(VarReg::Norm(RegType::Temp(o)));
|
||||||
|
|
||||||
(RegType::Temp(o), true)
|
(RegType::Temp(o), true)
|
||||||
|
|||||||
@@ -109,8 +109,8 @@ impl<'a> VariableFixtures<'a>
|
|||||||
var_count
|
var_count
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mark_vars_in_chunk<Iter>(&mut self, iter: Iter, lt_arity: usize, term_loc: GenContext)
|
pub fn mark_vars_in_chunk<I>(&mut self, iter: I, lt_arity: usize, term_loc: GenContext)
|
||||||
where Iter: Iterator<Item=TermRef<'a>>
|
where I: Iterator<Item=TermRef<'a>>
|
||||||
{
|
{
|
||||||
let chunk_num = term_loc.chunk_num();
|
let chunk_num = term_loc.chunk_num();
|
||||||
let mut arg_c = 1;
|
let mut arg_c = 1;
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ impl QueryTerm {
|
|||||||
match self {
|
match self {
|
||||||
&mut QueryTerm::Clause(_, _, _, ref mut use_default_cp) => *use_default_cp = true,
|
&mut QueryTerm::Clause(_, _, _, ref mut use_default_cp) => *use_default_cp = true,
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn arity(&self) -> usize {
|
pub fn arity(&self) -> usize {
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
:- op(400, yfx, /).
|
:- op(400, yfx, /).
|
||||||
|
|
||||||
:- module(builtins, [(=)/2, (+)/2, (**)/2, (*)/2, (-)/2, (/)/2,
|
:- module(builtins, [(=)/2, (+)/1, (+)/2, (**)/2, (*)/2, (-)/1, (-)/2,
|
||||||
(/\)/2, (\/)/2, (is)/2, (xor)/2, (div)/2, (//)/2, (rdiv)/2,
|
(/)/2, (/\)/2, (\/)/2, (is)/2, (xor)/2, (div)/2, (//)/2,
|
||||||
(<<)/2, (>>)/2, (mod)/2, (rem)/2, (>)/2, (<)/2, (=\=)/2,
|
(rdiv)/2, (<<)/2, (>>)/2, (mod)/2, (rem)/2, (>)/2, (<)/2,
|
||||||
(=:=)/2, (-)/1, (>=)/2, (=<)/2, (,)/2, (->)/2, (;)/2, (=..)/2,
|
(=\=)/2, (=:=)/2, (-)/1, (>=)/2, (=<)/2, (,)/2, (->)/2, (;)/2,
|
||||||
(==)/2, (\==)/2, (@=<)/2, (@>=)/2, (@<)/2, (@>)/2, (=@=)/2,
|
(=..)/2, (==)/2, (\==)/2, (@=<)/2, (@>=)/2, (@<)/2, (@>)/2,
|
||||||
(\=@=)/2, (:)/2, call_with_inference_limit/3, catch/3,
|
(=@=)/2, (\=@=)/2, (:)/2, call_with_inference_limit/3,
|
||||||
current_prolog_flag/2, expand_goal/2, expand_term/2,
|
catch/3, current_prolog_flag/2, expand_goal/2, expand_term/2,
|
||||||
set_prolog_flag/2, setup_call_cleanup/3, term_variables/2,
|
set_prolog_flag/2, setup_call_cleanup/3, term_variables/2,
|
||||||
throw/1, true/0, false/0, write/1, write_canonical/1,
|
throw/1, true/0, false/0, write/1, write_canonical/1,
|
||||||
writeq/1, write_term/2]).
|
writeq/1, write_term/2]).
|
||||||
@@ -34,7 +34,7 @@ expand_op_list([Op | OtherOps], Pred, Spec, [(:- op(Pred, Spec, Op)) | OtherResu
|
|||||||
:- op(500, yfx, [/\, \/, xor]).
|
:- op(500, yfx, [/\, \/, xor]).
|
||||||
:- op(400, yfx, [div, //, rdiv]).
|
:- op(400, yfx, [div, //, rdiv]).
|
||||||
:- op(400, yfx, [<<, >>, mod, rem]).
|
:- op(400, yfx, [<<, >>, mod, rem]).
|
||||||
:- op(200, fy, -).
|
:- op(200, fy, [+, -]).
|
||||||
|
|
||||||
% arithmetic comparison operators.
|
% arithmetic comparison operators.
|
||||||
:- op(700, xfx, [>, <, =\=, =:=, >=, =<]).
|
:- op(700, xfx, [>, <, =\=, =:=, >=, =<]).
|
||||||
|
|||||||
@@ -268,8 +268,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_in_situ_lookup(name: ClauseName, arity: usize, indices: &IndexStore)
|
fn try_in_situ_lookup(name: ClauseName, arity: usize, indices: &IndexStore) -> Option<usize>
|
||||||
-> Option<usize>
|
|
||||||
{
|
{
|
||||||
match indices.in_situ_code_dir.get(&(name.clone(), arity)) {
|
match indices.in_situ_code_dir.get(&(name.clone(), arity)) {
|
||||||
Some(p) => Some(*p),
|
Some(p) => Some(*p),
|
||||||
|
|||||||
@@ -149,11 +149,12 @@ impl CodeRepo {
|
|||||||
cl.name().map(|name| (name, arity))
|
cl.name().map(|name| (name, arity))
|
||||||
}).ok_or(SessionError::NamelessEntry)?;
|
}).ok_or(SessionError::NamelessEntry)?;
|
||||||
|
|
||||||
let p = self.in_situ_code.len();
|
let p = self.in_situ_code.len();
|
||||||
in_situ_code_dir.insert((name, arity), p);
|
in_situ_code_dir.insert((name, arity), p);
|
||||||
|
|
||||||
let mut cg = CodeGenerator::<DebrayAllocator>::new(true, flags);
|
let mut cg = CodeGenerator::<DebrayAllocator>::new(true, flags);
|
||||||
let mut decl_code = cg.compile_predicate(&decl.0)?;
|
// clone the decl to avoid the need to wipe its register cells later.
|
||||||
|
let mut decl_code = cg.compile_predicate(&decl.0.clone())?;
|
||||||
|
|
||||||
compile_appendix(&mut decl_code, queue, true, flags)?;
|
compile_appendix(&mut decl_code, queue, true, flags)?;
|
||||||
|
|
||||||
|
|||||||
@@ -322,7 +322,6 @@ impl MachineState {
|
|||||||
};
|
};
|
||||||
|
|
||||||
output.push_char('.');
|
output.push_char('.');
|
||||||
|
|
||||||
self.reset();
|
self.reset();
|
||||||
Some(output.result())
|
Some(output.result())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -487,12 +487,12 @@ impl RelationWorker {
|
|||||||
fn to_query_term(&mut self, indices: &mut CompositeIndices, term: Term) -> Result<QueryTerm, ParserError>
|
fn to_query_term(&mut self, indices: &mut CompositeIndices, term: Term) -> Result<QueryTerm, ParserError>
|
||||||
{
|
{
|
||||||
match term {
|
match term {
|
||||||
Term::Constant(r, Constant::Atom(name, fixity)) =>
|
Term::Constant(_, Constant::Atom(name, fixity)) =>
|
||||||
if name.as_str() == "!" || name.as_str() == "blocked_!" {
|
if name.as_str() == "!" || name.as_str() == "blocked_!" {
|
||||||
Ok(QueryTerm::BlockedCut)
|
Ok(QueryTerm::BlockedCut)
|
||||||
} else {
|
} else {
|
||||||
let ct = indices.get_clause_type(name, 0, fixity);
|
let ct = indices.get_clause_type(name, 0, fixity);
|
||||||
Ok(QueryTerm::Clause(r, ct, vec![], false))
|
Ok(QueryTerm::Clause(Cell::default(), ct, vec![], false))
|
||||||
},
|
},
|
||||||
Term::Var(_, ref v) if v.as_str() == "!" =>
|
Term::Var(_, ref v) if v.as_str() == "!" =>
|
||||||
Ok(QueryTerm::UnblockedCut(Cell::default())),
|
Ok(QueryTerm::UnblockedCut(Cell::default())),
|
||||||
|
|||||||
Reference in New Issue
Block a user