inline comparison instructions.
This commit is contained in:
@@ -8,6 +8,8 @@ pub struct ArithExprIterator<'a> {
|
|||||||
state_stack: Vec<IteratorState<'a>>
|
state_stack: Vec<IteratorState<'a>>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type ArithCont = (Code, Option<ArithmeticTerm>);
|
||||||
|
|
||||||
impl<'a> ArithExprIterator<'a> {
|
impl<'a> ArithExprIterator<'a> {
|
||||||
fn push_subterm(&mut self, lvl: Level, term: &'a Term) {
|
fn push_subterm(&mut self, lvl: Level, term: &'a Term) {
|
||||||
self.state_stack.push(IteratorState::to_state(lvl, term));
|
self.state_stack.push(IteratorState::to_state(lvl, term));
|
||||||
@@ -73,14 +75,13 @@ impl<'a> Iterator for ArithExprIterator<'a> {
|
|||||||
|
|
||||||
pub struct ArithmeticEvaluator<'a> {
|
pub struct ArithmeticEvaluator<'a> {
|
||||||
bindings: &'a AllocVarDict<'a>,
|
bindings: &'a AllocVarDict<'a>,
|
||||||
target_int: usize,
|
|
||||||
interm: Vec<ArithmeticTerm>,
|
interm: Vec<ArithmeticTerm>,
|
||||||
interm_c: usize
|
interm_c: usize
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ArithmeticEvaluator<'a> {
|
impl<'a> ArithmeticEvaluator<'a> {
|
||||||
pub fn new(bindings: &'a AllocVarDict<'a>, target_int: usize) -> Self {
|
pub fn new(bindings: &'a AllocVarDict<'a>, target_int: usize) -> Self {
|
||||||
ArithmeticEvaluator { bindings, target_int, interm: Vec::new(), interm_c: target_int }
|
ArithmeticEvaluator { bindings, interm: Vec::new(), interm_c: target_int }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_unary_instr(name: &Atom, a1: ArithmeticTerm, t: usize)
|
fn get_unary_instr(name: &Atom, a1: ArithmeticTerm, t: usize)
|
||||||
@@ -180,7 +181,7 @@ impl<'a> ArithmeticEvaluator<'a> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eval(&mut self, term: &Term) -> Result<Code, ArithmeticError> {
|
pub fn eval(&mut self, term: &Term) -> Result<ArithCont, ArithmeticError> {
|
||||||
let mut code = Vec::new();
|
let mut code = Vec::new();
|
||||||
|
|
||||||
for term_ref in term.arith_expr_iter()? {
|
for term_ref in term.arith_expr_iter()? {
|
||||||
@@ -212,18 +213,6 @@ impl<'a> ArithmeticEvaluator<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok((code, self.interm.pop()))
|
||||||
if let Some(arith_term) = self.interm.pop() {
|
|
||||||
let t = self.target_int;
|
|
||||||
|
|
||||||
match arith_term {
|
|
||||||
n @ ArithmeticTerm::Integer(_) => code.push(move_at!(n, t)),
|
|
||||||
n @ ArithmeticTerm::Float(_) => code.push(move_at!(n, t)),
|
|
||||||
r @ ArithmeticTerm::Reg(_) => code.push(move_at!(r, t)),
|
|
||||||
_ => {}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(code)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -315,6 +315,7 @@ pub enum Term {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub enum InlinedQueryTerm {
|
pub enum InlinedQueryTerm {
|
||||||
|
CompareNumber(CompareNumberQT, Vec<Box<Term>>),
|
||||||
IsAtomic(Vec<Box<Term>>),
|
IsAtomic(Vec<Box<Term>>),
|
||||||
IsVar(Vec<Box<Term>>)
|
IsVar(Vec<Box<Term>>)
|
||||||
}
|
}
|
||||||
@@ -322,6 +323,7 @@ pub enum InlinedQueryTerm {
|
|||||||
impl InlinedQueryTerm {
|
impl InlinedQueryTerm {
|
||||||
pub fn arity(&self) -> usize {
|
pub fn arity(&self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
|
&InlinedQueryTerm::CompareNumber(_, _) => 2,
|
||||||
&InlinedQueryTerm::IsAtomic(_) => 1,
|
&InlinedQueryTerm::IsAtomic(_) => 1,
|
||||||
&InlinedQueryTerm::IsVar(_) => 1
|
&InlinedQueryTerm::IsVar(_) => 1
|
||||||
}
|
}
|
||||||
@@ -341,7 +343,6 @@ pub enum CompareNumberQT {
|
|||||||
pub enum QueryTerm {
|
pub enum QueryTerm {
|
||||||
CallN(Vec<Box<Term>>),
|
CallN(Vec<Box<Term>>),
|
||||||
Catch(Vec<Box<Term>>),
|
Catch(Vec<Box<Term>>),
|
||||||
CompareNumber(CompareNumberQT, Vec<Box<Term>>),
|
|
||||||
Cut,
|
Cut,
|
||||||
Is(Vec<Box<Term>>),
|
Is(Vec<Box<Term>>),
|
||||||
Inlined(InlinedQueryTerm),
|
Inlined(InlinedQueryTerm),
|
||||||
@@ -353,7 +354,6 @@ impl QueryTerm {
|
|||||||
pub fn arity(&self) -> usize {
|
pub fn arity(&self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
&QueryTerm::Catch(_) => 3,
|
&QueryTerm::Catch(_) => 3,
|
||||||
&QueryTerm::CompareNumber(_, _) => 2,
|
|
||||||
&QueryTerm::Throw(_) => 1,
|
&QueryTerm::Throw(_) => 1,
|
||||||
&QueryTerm::Inlined(ref term) => term.arity(),
|
&QueryTerm::Inlined(ref term) => term.arity(),
|
||||||
&QueryTerm::Is(_) => 2,
|
&QueryTerm::Is(_) => 2,
|
||||||
@@ -709,6 +709,7 @@ pub enum ArithmeticInstruction {
|
|||||||
|
|
||||||
pub enum BuiltInInstruction {
|
pub enum BuiltInInstruction {
|
||||||
CleanUpBlock,
|
CleanUpBlock,
|
||||||
|
CompareNumber(CompareNumberQT, ArithmeticTerm, ArithmeticTerm),
|
||||||
DuplicateTerm,
|
DuplicateTerm,
|
||||||
EraseBall,
|
EraseBall,
|
||||||
Fail,
|
Fail,
|
||||||
@@ -735,10 +736,8 @@ pub enum ControlInstruction {
|
|||||||
Execute(Atom, usize),
|
Execute(Atom, usize),
|
||||||
ExecuteN(usize),
|
ExecuteN(usize),
|
||||||
Goto(usize, usize), // p, arity.
|
Goto(usize, usize), // p, arity.
|
||||||
CompareNumberCall(CompareNumberQT),
|
IsCall(RegType, ArithmeticTerm),
|
||||||
CompareNumberExecute(CompareNumberQT),
|
IsExecute(RegType, ArithmeticTerm),
|
||||||
IsCall(RegType),
|
|
||||||
IsExecute(RegType),
|
|
||||||
Proceed,
|
Proceed,
|
||||||
ThrowCall,
|
ThrowCall,
|
||||||
ThrowExecute,
|
ThrowExecute,
|
||||||
@@ -757,8 +756,8 @@ impl ControlInstruction {
|
|||||||
&ControlInstruction::ThrowExecute => true,
|
&ControlInstruction::ThrowExecute => true,
|
||||||
&ControlInstruction::Goto(_, _) => true,
|
&ControlInstruction::Goto(_, _) => true,
|
||||||
&ControlInstruction::Proceed => true,
|
&ControlInstruction::Proceed => true,
|
||||||
&ControlInstruction::IsCall(_) => true,
|
&ControlInstruction::IsCall(_, _) => true,
|
||||||
&ControlInstruction::IsExecute(_) => true,
|
&ControlInstruction::IsExecute(_, _) => true,
|
||||||
_ => false
|
_ => false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -790,7 +789,6 @@ pub enum FactInstruction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub enum QueryInstruction {
|
pub enum QueryInstruction {
|
||||||
MoveArithmeticTerm(ArithmeticTerm, usize),
|
|
||||||
GetVariable(RegType, usize),
|
GetVariable(RegType, usize),
|
||||||
PutConstant(Level, Constant, RegType),
|
PutConstant(Level, Constant, RegType),
|
||||||
PutList(Level, RegType),
|
PutList(Level, RegType),
|
||||||
|
|||||||
@@ -230,12 +230,16 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
|
|||||||
ConjunctInfo::new(vs, num_of_chunks, has_deep_cut)
|
ConjunctInfo::new(vs, num_of_chunks, has_deep_cut)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_conditional_call_inlined(term: &InlinedQueryTerm, code: &mut Code)
|
fn add_conditional_call_inlined(_: &InlinedQueryTerm, code: &mut Code)
|
||||||
{
|
{
|
||||||
|
code.push(proceed!());
|
||||||
|
|
||||||
|
/*
|
||||||
match term {
|
match term {
|
||||||
&InlinedQueryTerm::IsAtomic(_) | &InlinedQueryTerm::IsVar(_) =>
|
&InlinedQueryTerm::IsAtomic(_) | &InlinedQueryTerm::IsVar(_) =>
|
||||||
code.push(proceed!())
|
code.push(proceed!())
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_conditional_call(code: &mut Code, qt: &QueryTerm, pvs: usize)
|
fn add_conditional_call(code: &mut Code, qt: &QueryTerm, pvs: usize)
|
||||||
@@ -276,10 +280,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
|
|||||||
*ctrl = ControlInstruction::Execute(name, arity),
|
*ctrl = ControlInstruction::Execute(name, arity),
|
||||||
ControlInstruction::CallN(arity) =>
|
ControlInstruction::CallN(arity) =>
|
||||||
*ctrl = ControlInstruction::ExecuteN(arity),
|
*ctrl = ControlInstruction::ExecuteN(arity),
|
||||||
ControlInstruction::CompareNumberCall(cmp) =>
|
ControlInstruction::IsCall(r, at) =>
|
||||||
*ctrl = ControlInstruction::CompareNumberExecute(cmp),
|
*ctrl = ControlInstruction::IsExecute(r, at),
|
||||||
ControlInstruction::IsCall(r) =>
|
|
||||||
*ctrl = ControlInstruction::IsExecute(r),
|
|
||||||
ControlInstruction::CatchCall =>
|
ControlInstruction::CatchCall =>
|
||||||
*ctrl = ControlInstruction::CatchExecute,
|
*ctrl = ControlInstruction::CatchExecute,
|
||||||
ControlInstruction::ThrowCall =>
|
ControlInstruction::ThrowCall =>
|
||||||
@@ -293,21 +295,33 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn compile_inlined(&mut self, term: &'a InlinedQueryTerm, term_loc: GenContext, code: &mut Code)
|
fn compile_inlined(&mut self, term: &'a InlinedQueryTerm, term_loc: GenContext, code: &mut Code)
|
||||||
|
-> Result<(), ParserError>
|
||||||
{
|
{
|
||||||
match term {
|
match term {
|
||||||
&InlinedQueryTerm::IsAtomic(ref inner_term) =>
|
&InlinedQueryTerm::CompareNumber(cmp, ref terms) => {
|
||||||
match inner_term[0].as_ref() {
|
let (mut lcode, at_1) = self.call_arith_eval(terms[0].as_ref(), 1)?;
|
||||||
&Term::AnonVar | &Term::Clause(_, _, _) | &Term::Cons(_, _, _) => {
|
let (mut rcode, at_2) = self.call_arith_eval(terms[1].as_ref(), 2)?;
|
||||||
code.push(fail!());
|
|
||||||
},
|
code.append(&mut lcode);
|
||||||
&Term::Constant(_, _) => {
|
code.append(&mut rcode);
|
||||||
code.push(succeed!());
|
|
||||||
},
|
code.push(compare_number_instr!(cmp,
|
||||||
&Term::Var(ref vr, ref name) => {
|
at_1.unwrap_or(interm!(1)),
|
||||||
let r = self.mark_non_callable(name, 1, term_loc, vr, code);
|
at_2.unwrap_or(interm!(2))));
|
||||||
code.push(is_atomic!(r));
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
&InlinedQueryTerm::IsAtomic(ref inner_term) =>
|
||||||
|
match inner_term[0].as_ref() {
|
||||||
|
&Term::AnonVar | &Term::Clause(_, _, _) | &Term::Cons(_, _, _) => {
|
||||||
|
code.push(fail!());
|
||||||
|
},
|
||||||
|
&Term::Constant(_, _) => {
|
||||||
|
code.push(succeed!());
|
||||||
|
},
|
||||||
|
&Term::Var(ref vr, ref name) => {
|
||||||
|
let r = self.mark_non_callable(name, 1, term_loc, vr, code);
|
||||||
|
code.push(is_atomic!(r));
|
||||||
|
}
|
||||||
|
},
|
||||||
&InlinedQueryTerm::IsVar(ref inner_term) =>
|
&InlinedQueryTerm::IsVar(ref inner_term) =>
|
||||||
match inner_term[0].as_ref() {
|
match inner_term[0].as_ref() {
|
||||||
&Term::Constant(_, _) | &Term::Clause(_, _, _) | &Term::Cons(_, _, _) => {
|
&Term::Constant(_, _) | &Term::Clause(_, _, _) | &Term::Cons(_, _, _) => {
|
||||||
@@ -322,9 +336,12 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call_arith_eval(&self, term: &'a Term, target_int: usize) -> Result<Code, ArithmeticError> {
|
fn call_arith_eval(&self, term: &'a Term, target_int: usize) -> Result<ArithCont, ArithmeticError>
|
||||||
|
{
|
||||||
let mut evaluator = ArithmeticEvaluator::new(self.marker.bindings(), target_int);
|
let mut evaluator = ArithmeticEvaluator::new(self.marker.bindings(), target_int);
|
||||||
evaluator.eval(term)
|
evaluator.eval(term)
|
||||||
}
|
}
|
||||||
@@ -360,10 +377,10 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
&QueryTerm::Inlined(ref term) =>
|
&QueryTerm::Inlined(ref term) =>
|
||||||
self.compile_inlined(term, term_loc, code),
|
self.compile_inlined(term, term_loc, code)?,
|
||||||
&QueryTerm::Is(ref terms) => {
|
&QueryTerm::Is(ref terms) => {
|
||||||
let mut arith_code = self.call_arith_eval(terms[1].as_ref(), 1)?;
|
let (mut acode, at) = try!(self.call_arith_eval(terms[1].as_ref(), 1));
|
||||||
code.append(&mut arith_code);
|
code.append(&mut acode);
|
||||||
|
|
||||||
match terms[0].as_ref() {
|
match terms[0].as_ref() {
|
||||||
&Term::Var(ref vr, ref name) => {
|
&Term::Var(ref vr, ref name) => {
|
||||||
@@ -373,35 +390,26 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
|
|||||||
vr,
|
vr,
|
||||||
code);
|
code);
|
||||||
|
|
||||||
code.push(is_call!(r));
|
code.push(is_call!(r, at.unwrap_or(interm!(1))));
|
||||||
},
|
},
|
||||||
&Term::Constant(_, Constant::Float(fl)) => {
|
&Term::Constant(_, Constant::Float(fl)) => {
|
||||||
code.push(query![put_constant!(Level::Shallow,
|
code.push(query![put_constant!(Level::Shallow,
|
||||||
Constant::Float(fl),
|
Constant::Float(fl),
|
||||||
temp_v!(1))]);
|
temp_v!(1))]);
|
||||||
code.push(is_call!(temp_v!(1)));
|
code.push(is_call!(temp_v!(1), at.unwrap_or(interm!(1))));
|
||||||
},
|
},
|
||||||
&Term::Constant(_, Constant::Integer(ref bi)) => {
|
&Term::Constant(_, Constant::Integer(ref bi)) => {
|
||||||
let bi = bi.clone();
|
let bi = bi.clone();
|
||||||
code.push(query![put_constant!(Level::Shallow,
|
code.push(query![put_constant!(Level::Shallow,
|
||||||
Constant::Integer(bi),
|
Constant::Integer(bi),
|
||||||
temp_v!(1))]);
|
temp_v!(1))]);
|
||||||
code.push(is_call!(temp_v!(1)));
|
code.push(is_call!(temp_v!(1), at.unwrap_or(interm!(1))));
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
code.push(fail!());
|
code.push(fail!());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
&QueryTerm::CompareNumber(cmp, ref terms) => {
|
|
||||||
let mut larith_code = self.call_arith_eval(terms[0].as_ref(), 1)?;
|
|
||||||
let mut rarith_code = self.call_arith_eval(terms[1].as_ref(), 2)?;
|
|
||||||
|
|
||||||
code.append(&mut larith_code);
|
|
||||||
code.append(&mut rarith_code);
|
|
||||||
|
|
||||||
code.push(compare_number_call!(cmp));
|
|
||||||
},
|
|
||||||
_ if chunk_num == 0 => {
|
_ if chunk_num == 0 => {
|
||||||
self.marker.reset_arg(term.arity());
|
self.marker.reset_arg(term.arity());
|
||||||
|
|
||||||
|
|||||||
@@ -46,8 +46,6 @@ impl fmt::Display for FactInstruction {
|
|||||||
impl fmt::Display for QueryInstruction {
|
impl fmt::Display for QueryInstruction {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
&QueryInstruction::MoveArithmeticTerm(ref at, ref r) =>
|
|
||||||
write!(f, "move_arithmetic_term {}, {}", at, r),
|
|
||||||
&QueryInstruction::GetVariable(ref x, ref a) =>
|
&QueryInstruction::GetVariable(ref x, ref a) =>
|
||||||
write!(f, "query:get_variable {}, A{}", x, a),
|
write!(f, "query:get_variable {}, A{}", x, a),
|
||||||
&QueryInstruction::PutConstant(Level::Shallow, ref constant, ref r) =>
|
&QueryInstruction::PutConstant(Level::Shallow, ref constant, ref r) =>
|
||||||
@@ -108,10 +106,6 @@ impl fmt::Display for ControlInstruction {
|
|||||||
write!(f, "call_catch"),
|
write!(f, "call_catch"),
|
||||||
&ControlInstruction::CatchExecute =>
|
&ControlInstruction::CatchExecute =>
|
||||||
write!(f, "execute_catch"),
|
write!(f, "execute_catch"),
|
||||||
&ControlInstruction::CompareNumberCall(cmp) =>
|
|
||||||
write!(f, "n_compare_call {}", cmp),
|
|
||||||
&ControlInstruction::CompareNumberExecute(cmp) =>
|
|
||||||
write!(f, "n_compare_execute {}", cmp),
|
|
||||||
&ControlInstruction::ExecuteN(arity) =>
|
&ControlInstruction::ExecuteN(arity) =>
|
||||||
write!(f, "execute_N {}", arity),
|
write!(f, "execute_N {}", arity),
|
||||||
&ControlInstruction::Deallocate =>
|
&ControlInstruction::Deallocate =>
|
||||||
@@ -126,10 +120,10 @@ impl fmt::Display for ControlInstruction {
|
|||||||
write!(f, "call_throw"),
|
write!(f, "call_throw"),
|
||||||
&ControlInstruction::ThrowExecute =>
|
&ControlInstruction::ThrowExecute =>
|
||||||
write!(f, "execute_throw"),
|
write!(f, "execute_throw"),
|
||||||
&ControlInstruction::IsCall(r) =>
|
&ControlInstruction::IsCall(r, ref at) =>
|
||||||
write!(f, "is_call {}", r),
|
write!(f, "is_call {}, {}", r, at),
|
||||||
&ControlInstruction::IsExecute(r) =>
|
&ControlInstruction::IsExecute(r, ref at) =>
|
||||||
write!(f, "is_execute {}", r),
|
write!(f, "is_execute {}, {}", r, at),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -153,6 +147,8 @@ impl fmt::Display for BuiltInInstruction {
|
|||||||
match self {
|
match self {
|
||||||
&BuiltInInstruction::CleanUpBlock =>
|
&BuiltInInstruction::CleanUpBlock =>
|
||||||
write!(f, "clean_up_block"),
|
write!(f, "clean_up_block"),
|
||||||
|
&BuiltInInstruction::CompareNumber(cmp, ref at_1, ref at_2) =>
|
||||||
|
write!(f, "number_test {}, {}, {} ", cmp, at_1, at_2),
|
||||||
&BuiltInInstruction::DuplicateTerm =>
|
&BuiltInInstruction::DuplicateTerm =>
|
||||||
write!(f, "duplicate_term X1"),
|
write!(f, "duplicate_term X1"),
|
||||||
&BuiltInInstruction::EraseBall =>
|
&BuiltInInstruction::EraseBall =>
|
||||||
|
|||||||
@@ -40,9 +40,10 @@ impl<'a> QueryIterator<'a> {
|
|||||||
let state = IteratorState::Clause(0, ClauseType::Catch, terms);
|
let state = IteratorState::Clause(0, ClauseType::Catch, terms);
|
||||||
QueryIterator { state_stack: vec![state] }
|
QueryIterator { state_stack: vec![state] }
|
||||||
},
|
},
|
||||||
&QueryTerm::CompareNumber(_, ref terms) | &QueryTerm::Is(ref terms) => {
|
&QueryTerm::Inlined(InlinedQueryTerm::CompareNumber(_, ref terms))
|
||||||
let state = IteratorState::Clause(0, ClauseType::Is, terms);
|
| &QueryTerm::Is(ref terms) => {
|
||||||
QueryIterator { state_stack: vec![state] }
|
let state = IteratorState::Clause(0, ClauseType::Is, terms);
|
||||||
|
QueryIterator { state_stack: vec![state] }
|
||||||
},
|
},
|
||||||
&QueryTerm::Inlined(InlinedQueryTerm::IsAtomic(ref terms))
|
&QueryTerm::Inlined(InlinedQueryTerm::IsAtomic(ref terms))
|
||||||
| &QueryTerm::Inlined(InlinedQueryTerm::IsVar(ref terms)) =>
|
| &QueryTerm::Inlined(InlinedQueryTerm::IsVar(ref terms)) =>
|
||||||
@@ -270,7 +271,7 @@ impl<'a> ChunkedIterator<'a>
|
|||||||
arity = child_terms.len();
|
arity = child_terms.len();
|
||||||
break;
|
break;
|
||||||
},
|
},
|
||||||
&QueryTerm::Is(_) | &QueryTerm::CompareNumber(_, _) => {
|
&QueryTerm::Is(_) => {
|
||||||
result.push(term);
|
result.push(term);
|
||||||
arity = 2;
|
arity = 2;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1379,10 +1379,6 @@ impl MachineState {
|
|||||||
|
|
||||||
fn execute_query_instr(&mut self, instr: &QueryInstruction) {
|
fn execute_query_instr(&mut self, instr: &QueryInstruction) {
|
||||||
match instr {
|
match instr {
|
||||||
&QueryInstruction::MoveArithmeticTerm(ref at, t) => {
|
|
||||||
let n = try_or_fail!(self, self.get_number(at));
|
|
||||||
self.interms[t - 1] = n;
|
|
||||||
},
|
|
||||||
&QueryInstruction::GetVariable(norm, arg) =>
|
&QueryInstruction::GetVariable(norm, arg) =>
|
||||||
self[norm] = self.registers[arg].clone(),
|
self[norm] = self.registers[arg].clone(),
|
||||||
&QueryInstruction::PutConstant(_, ref constant, reg) =>
|
&QueryInstruction::PutConstant(_, ref constant, reg) =>
|
||||||
@@ -1609,6 +1605,22 @@ impl MachineState {
|
|||||||
fn execute_built_in_instr(&mut self, code_dir: &CodeDir, instr: &BuiltInInstruction)
|
fn execute_built_in_instr(&mut self, code_dir: &CodeDir, instr: &BuiltInInstruction)
|
||||||
{
|
{
|
||||||
match instr {
|
match instr {
|
||||||
|
&BuiltInInstruction::CompareNumber(cmp, ref at_1, ref at_2) => {
|
||||||
|
let n1 = try_or_fail!(self, self.get_number(at_1));
|
||||||
|
let n2 = try_or_fail!(self, self.get_number(at_2));
|
||||||
|
|
||||||
|
self.fail = match cmp {
|
||||||
|
CompareNumberQT::GreaterThan if !(n1.gt(n2)) => true,
|
||||||
|
CompareNumberQT::GreaterThanOrEqual if !(n1.gte(n2)) => true,
|
||||||
|
CompareNumberQT::LessThan if !(n1.lt(n2)) => true,
|
||||||
|
CompareNumberQT::LessThanOrEqual if !(n1.lte(n2)) => true,
|
||||||
|
CompareNumberQT::NotEqual if !(n1.ne(n2)) => true,
|
||||||
|
CompareNumberQT::Equal if !(n1.eq(n2)) => true,
|
||||||
|
_ => false
|
||||||
|
};
|
||||||
|
|
||||||
|
self.p += 1;
|
||||||
|
},
|
||||||
&BuiltInInstruction::DuplicateTerm => {
|
&BuiltInInstruction::DuplicateTerm => {
|
||||||
let old_h = self.h;
|
let old_h = self.h;
|
||||||
|
|
||||||
@@ -1744,21 +1756,6 @@ impl MachineState {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_n_compare(&mut self, cmp: CompareNumberQT) {
|
|
||||||
let n1 = self.interms[0].clone();
|
|
||||||
let n2 = self.interms[1].clone();
|
|
||||||
|
|
||||||
self.fail = match cmp {
|
|
||||||
CompareNumberQT::GreaterThan if !(n1.gt(n2)) => true,
|
|
||||||
CompareNumberQT::GreaterThanOrEqual if !(n1.gte(n2)) => true,
|
|
||||||
CompareNumberQT::LessThan if !(n1.lt(n2)) => true,
|
|
||||||
CompareNumberQT::LessThanOrEqual if !(n1.lte(n2)) => true,
|
|
||||||
CompareNumberQT::NotEqual if !(n1.ne(n2)) => true,
|
|
||||||
CompareNumberQT::Equal if !(n1.eq(n2)) => true,
|
|
||||||
_ => false
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn execute_ctrl_instr(&mut self, code_dir: &CodeDir, instr: &ControlInstruction)
|
fn execute_ctrl_instr(&mut self, code_dir: &CodeDir, instr: &ControlInstruction)
|
||||||
{
|
{
|
||||||
match instr {
|
match instr {
|
||||||
@@ -1838,26 +1835,18 @@ impl MachineState {
|
|||||||
&ControlInstruction::ThrowExecute => {
|
&ControlInstruction::ThrowExecute => {
|
||||||
self.goto_throw();
|
self.goto_throw();
|
||||||
},
|
},
|
||||||
&ControlInstruction::CompareNumberCall(cmp) => {
|
&ControlInstruction::IsCall(r, ref at) => {
|
||||||
self.handle_n_compare(cmp);
|
let a1 = self[r].clone();
|
||||||
|
let a2 = try_or_fail!(self, self.get_number(at));
|
||||||
|
|
||||||
|
self.unify(a1, Addr::Con(Constant::from(a2)));
|
||||||
self.p += 1;
|
self.p += 1;
|
||||||
},
|
},
|
||||||
&ControlInstruction::CompareNumberExecute(cmp) => {
|
&ControlInstruction::IsExecute(r, ref at) => {
|
||||||
self.handle_n_compare(cmp);
|
|
||||||
self.p = self.cp;
|
|
||||||
},
|
|
||||||
&ControlInstruction::IsCall(r) => {
|
|
||||||
let a1 = self[r].clone();
|
let a1 = self[r].clone();
|
||||||
let a2 = Addr::Con(Constant::from(self.interms[0].clone()));
|
let a2 = try_or_fail!(self, self.get_number(at));
|
||||||
|
|
||||||
self.unify(a1, a2);
|
self.unify(a1, Addr::Con(Constant::from(a2)));
|
||||||
self.p += 1;
|
|
||||||
},
|
|
||||||
&ControlInstruction::IsExecute(r) => {
|
|
||||||
let a1 = self[r].clone();
|
|
||||||
let a2 = Addr::Con(Constant::from(self.interms[0].clone()));
|
|
||||||
|
|
||||||
self.unify(a1, a2);
|
|
||||||
self.p = self.cp;
|
self.p = self.cp;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -16,9 +16,21 @@ macro_rules! deallocate {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! move_at {
|
macro_rules! compare_number {
|
||||||
($at:expr, $r:expr) => (
|
($cmp: expr, $terms: expr) => (
|
||||||
Line::Query(vec![QueryInstruction::MoveArithmeticTerm($at, $r)])
|
QueryTerm::Inlined(InlinedQueryTerm::CompareNumber($cmp, $terms))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! compare_number_instr {
|
||||||
|
($cmp: expr, $at_1: expr, $at_2: expr) => (
|
||||||
|
Line::BuiltIn(BuiltInInstruction::CompareNumber($cmp, $at_1, $at_2))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! interm {
|
||||||
|
($n: expr) => (
|
||||||
|
ArithmeticTerm::Interm($n)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,12 +62,6 @@ macro_rules! fact {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! compare_number_call {
|
|
||||||
($cmp: expr) => (
|
|
||||||
Line::Control(ControlInstruction::CompareNumberCall($cmp))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! temp_v {
|
macro_rules! temp_v {
|
||||||
($x:expr) => (
|
($x:expr) => (
|
||||||
RegType::Temp($x)
|
RegType::Temp($x)
|
||||||
@@ -216,8 +222,8 @@ macro_rules! unify {
|
|||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! is_call {
|
macro_rules! is_call {
|
||||||
($r:expr) => (
|
($r:expr, $at:expr) => (
|
||||||
Line::Control(ControlInstruction::IsCall($r))
|
Line::Control(ControlInstruction::IsCall($r, $at))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Submodule src/prolog/parser updated: c105852843...8723085780
Reference in New Issue
Block a user