add compare predicate.

This commit is contained in:
Mark Thom
2018-02-21 23:21:18 -07:00
parent 5de03444eb
commit 9aac3cb086
10 changed files with 146 additions and 7 deletions

View File

@@ -421,6 +421,7 @@ pub enum QueryTerm {
CallN(Vec<Box<Term>>),
CallWithInferenceLimit(Vec<Box<Term>>),
Catch(Vec<Box<Term>>),
Compare(Vec<Box<Term>>),
CompareTerm(CompareTermQT, Vec<Box<Term>>),
Cut,
Display(Vec<Box<Term>>),
@@ -442,6 +443,7 @@ impl QueryTerm {
match self {
&QueryTerm::Arg(_) => 3,
&QueryTerm::Catch(_) => 3,
&QueryTerm::Compare(_) => 3,
&QueryTerm::CompareTerm(..) => 2,
&QueryTerm::Display(_) => 1,
&QueryTerm::Throw(_) => 1,
@@ -473,6 +475,7 @@ pub enum ClauseType<'a> {
CallN,
CallWithInferenceLimit,
Catch,
Compare,
CompareNumber(CompareNumberQT),
CompareTerm(CompareTermQT),
Deep(Level, &'a Cell<RegType>, &'a TabledRc<Atom>, Option<Fixity>),
@@ -495,6 +498,7 @@ impl<'a> ClauseType<'a> {
&ClauseType::CallN => "call",
&ClauseType::CallWithInferenceLimit => "call_with_inference_limit",
&ClauseType::Catch => "catch",
&ClauseType::Compare => "compare",
&ClauseType::CompareNumber(qt) => qt.name(),
&ClauseType::CompareTerm(qt) => qt.name(),
&ClauseType::Display => "display",
@@ -921,7 +925,9 @@ pub enum ControlInstruction {
CallN(usize), // arity.
CatchCall,
CatchExecute,
CheckCpExecute,
CheckCpExecute,
CompareCall,
CompareExecute,
CompareTermCall(CompareTermQT),
CompareTermExecute(CompareTermQT),
DisplayCall,
@@ -987,6 +993,8 @@ impl ControlInstruction {
&ControlInstruction::IsExecute(..) => true,
&ControlInstruction::JmpByCall(..) => true,
&ControlInstruction::JmpByExecute(..) => true,
&ControlInstruction::CompareCall => true,
&ControlInstruction::CompareExecute => true,
_ => false
}
}

View File

@@ -632,7 +632,8 @@ fn get_builtins(atom_tbl: TabledData<Atom>) -> Code {
install_inference_counter!(temp_v!(1), temp_v!(2), temp_v!(4)),
query![put_value!(temp_v!(3), 1)],
reset_block!(),
fail!()
fail!(),
compare_execute!() // compare/3, 454.
]
}
@@ -748,6 +749,7 @@ pub fn build_code_dir(atom_tbl: TabledData<Atom>) -> (Code, CodeDir, OpDir)
code_dir.insert((tabled_rc!("@<", atom_tbl), 2), (PredicateKeyType::BuiltIn, 390));
code_dir.insert((tabled_rc!("=@=", atom_tbl), 2), (PredicateKeyType::BuiltIn, 391));
code_dir.insert((tabled_rc!("\\=@=", atom_tbl), 2), (PredicateKeyType::BuiltIn, 392));
code_dir.insert((tabled_rc!("compare", atom_tbl), 3), (PredicateKeyType::BuiltIn, 454));
(builtin_code, code_dir, op_dir)
}

View File

@@ -259,6 +259,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
},
&QueryTerm::Catch(_) =>
code.push(Line::Control(ControlInstruction::CatchCall)),
&QueryTerm::Compare(_) =>
code.push(Line::Control(ControlInstruction::CompareCall)),
&QueryTerm::CompareTerm(qt, _) =>
code.push(Line::Control(ControlInstruction::CompareTermCall(qt))),
&QueryTerm::Display(_) =>
@@ -307,6 +309,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
*ctrl = ControlInstruction::Execute(name, arity),
ControlInstruction::CallN(arity) =>
*ctrl = ControlInstruction::ExecuteN(arity),
ControlInstruction::CompareCall =>
*ctrl = ControlInstruction::CompareExecute,
ControlInstruction::CompareTermCall(qt) =>
*ctrl = ControlInstruction::CompareTermExecute(qt),
ControlInstruction::DisplayCall =>

View File

@@ -129,6 +129,10 @@ impl fmt::Display for ControlInstruction {
write!(f, "catch_execute"),
&ControlInstruction::CheckCpExecute =>
write!(f, "check_cp_execute"),
&ControlInstruction::CompareCall =>
write!(f, "compare_call"),
&ControlInstruction::CompareExecute =>
write!(f, "compare_execute"),
&ControlInstruction::CompareTermCall(qt) =>
write!(f, "compare_term_call {}", qt),
&ControlInstruction::CompareTermExecute(qt) =>

View File

@@ -78,6 +78,10 @@ impl<'a> QueryIterator<'a> {
let state = TermIterState::Clause(0, ClauseType::CompareNumber(qt), terms);
QueryIterator { state_stack: vec![state] }
},
&QueryTerm::Compare(ref terms) => {
let state = TermIterState::Clause(0, ClauseType::Compare, terms);
QueryIterator { state_stack: vec![state] }
},
&QueryTerm::CompareTerm(qt, ref terms) => {
let state = TermIterState::Clause(0, ClauseType::CompareTerm(qt), terms);
QueryIterator { state_stack: vec![state] }
@@ -329,7 +333,7 @@ impl<'a> ChunkedIterator<'a>
break;
}
},
&QueryTerm::SetupCallCleanup(_) => {
&QueryTerm::SetupCallCleanup(_) | &QueryTerm::Compare(_) => {
result.push(term);
arity = 3;
break;

View File

@@ -1020,7 +1020,11 @@ impl MachineState {
}
pub(super) fn copy_and_align_ball_to_heap(&mut self) {
let diff = self.ball.0 - self.heap.h;
let diff = if self.ball.0 > self.heap.h {
self.ball.0 - self.heap.h
} else {
self.heap.h - self.ball.0
};
for heap_value in self.ball.1.iter().cloned() {
self.heap.push(match heap_value {
@@ -1830,6 +1834,36 @@ impl MachineState {
}
};
},
&ControlInstruction::CompareCall => {
let a1 = self[temp_v!(1)].clone();
let a2 = self[temp_v!(2)].clone();
let a3 = self[temp_v!(3)].clone();
let c = Addr::Con(match self.compare_term_test(a2, a3) {
Ordering::Greater => atom!(">", self.atom_tbl),
Ordering::Equal => atom!("=", self.atom_tbl),
Ordering::Less => atom!("<", self.atom_tbl)
});
self.unify(a1, c);
self.p += 1;
},
&ControlInstruction::CompareExecute => {
let a1 = self[temp_v!(1)].clone();
let a2 = self[temp_v!(2)].clone();
let a3 = self[temp_v!(3)].clone();
let c = Addr::Con(match self.compare_term_test(a2, a3) {
Ordering::Greater => atom!(">", self.atom_tbl),
Ordering::Equal => atom!("=", self.atom_tbl),
Ordering::Less => atom!("<", self.atom_tbl)
});
self.unify(a1, c);
self.p = self.cp;
},
&ControlInstruction::CompareTermCall(qt) => {
match qt {
CompareTermQT::Equal =>

View File

@@ -658,3 +658,9 @@ macro_rules! remove_call_policy_check {
Line::BuiltIn(BuiltInInstruction::RemoveCallPolicyCheck)
)
}
macro_rules! compare_execute {
() => (
Line::Control(ControlInstruction::CompareExecute)
)
}