correct faulty bind (two tests now fail: conjunctive_queries and lists)
This commit is contained in:
@@ -592,21 +592,6 @@ impl InlinedClauseType {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn arity(&self) -> usize {
|
||||
match self {
|
||||
&InlinedClauseType::CompareNumber(..) => 2,
|
||||
&InlinedClauseType::IsAtom(..) => 1,
|
||||
&InlinedClauseType::IsAtomic(..) => 1,
|
||||
&InlinedClauseType::IsCompound(..) => 1,
|
||||
&InlinedClauseType::IsInteger (..) => 1,
|
||||
&InlinedClauseType::IsRational(..) => 1,
|
||||
&InlinedClauseType::IsString(..) => 1,
|
||||
&InlinedClauseType::IsFloat (..) => 1,
|
||||
&InlinedClauseType::IsNonVar(..) => 1,
|
||||
&InlinedClauseType::IsVar(..) => 1
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from(name: &str, arity: usize) -> Option<Self> {
|
||||
let r1 = temp_v!(1);
|
||||
let r2 = temp_v!(2);
|
||||
@@ -738,31 +723,6 @@ pub enum SystemClauseType {
|
||||
}
|
||||
|
||||
impl SystemClauseType {
|
||||
pub fn arity(&self) -> usize {
|
||||
match self {
|
||||
&SystemClauseType::InstallCleaner => 1,
|
||||
&SystemClauseType::InstallInferenceCounter => 3,
|
||||
&SystemClauseType::RemoveCallPolicyCheck => 1,
|
||||
&SystemClauseType::RemoveInferenceCounter => 2,
|
||||
&SystemClauseType::RestoreCutPolicy => 0,
|
||||
&SystemClauseType::SetCutPoint(_) => 1,
|
||||
&SystemClauseType::GetArg => 3,
|
||||
&SystemClauseType::InferenceLevel => 2,
|
||||
&SystemClauseType::CleanUpBlock => 1,
|
||||
&SystemClauseType::EraseBall => 0,
|
||||
&SystemClauseType::Fail => 0,
|
||||
&SystemClauseType::GetBall => 1,
|
||||
&SystemClauseType::GetCurrentBlock => 1,
|
||||
&SystemClauseType::GetCutPoint => 1,
|
||||
&SystemClauseType::InstallNewBlock => 1,
|
||||
&SystemClauseType::ResetBlock => 1,
|
||||
&SystemClauseType::SetBall => 1,
|
||||
&SystemClauseType::SkipMaxList => 4,
|
||||
&SystemClauseType::Succeed => 0,
|
||||
&SystemClauseType::UnwindStack => 0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fixity(&self) -> Option<Fixity> {
|
||||
None
|
||||
}
|
||||
@@ -1502,6 +1462,38 @@ pub enum Addr {
|
||||
Str(usize)
|
||||
}
|
||||
|
||||
impl PartialEq<Ref> for Addr {
|
||||
fn eq(&self, r: &Ref) -> bool {
|
||||
self.as_var() == Some(*r)
|
||||
}
|
||||
}
|
||||
|
||||
// for use in MachineState::bind.
|
||||
impl PartialOrd<Ref> for Addr {
|
||||
fn partial_cmp(&self, r: &Ref) -> Option<Ordering> {
|
||||
match self {
|
||||
&Addr::StackCell(fr, sc) =>
|
||||
match *r {
|
||||
Ref::HeapCell(_) => Some(Ordering::Greater),
|
||||
Ref::StackCell(fr1, sc1) =>
|
||||
if fr1 < fr || (fr1 == fr && sc1 < sc) {
|
||||
Some(Ordering::Greater)
|
||||
} else if fr1 == fr && sc1 == sc {
|
||||
Some(Ordering::Equal)
|
||||
} else {
|
||||
Some(Ordering::Less)
|
||||
}
|
||||
},
|
||||
&Addr::HeapCell(h) =>
|
||||
match r {
|
||||
Ref::StackCell(..) => Some(Ordering::Less),
|
||||
Ref::HeapCell(h1) => h.partial_cmp(h1)
|
||||
},
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Addr {
|
||||
pub fn is_ref(&self) -> bool {
|
||||
match self {
|
||||
@@ -1520,7 +1512,7 @@ impl Addr {
|
||||
|
||||
pub fn is_protected(&self, e: usize) -> bool {
|
||||
match self {
|
||||
&Addr::StackCell(fr, _) if fr > e => false,
|
||||
&Addr::StackCell(addr, _) if addr >= e => false,
|
||||
_ => true
|
||||
}
|
||||
}
|
||||
@@ -1567,6 +1559,15 @@ pub enum Ref {
|
||||
StackCell(usize, usize)
|
||||
}
|
||||
|
||||
impl Ref {
|
||||
pub fn as_addr(self) -> Addr {
|
||||
match self {
|
||||
Ref::HeapCell(h) => Addr::HeapCell(h),
|
||||
Ref::StackCell(fr, sc) => Addr::StackCell(fr, sc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub enum HeapCellValue {
|
||||
Addr(Addr),
|
||||
|
||||
@@ -19,7 +19,7 @@ pub struct CodeGenerator<TermMarker> {
|
||||
pub struct ConjunctInfo<'a> {
|
||||
pub perm_vs: VariableFixtures<'a>,
|
||||
pub num_of_chunks: usize,
|
||||
pub has_deep_cut: bool
|
||||
pub has_deep_cut: bool,
|
||||
}
|
||||
|
||||
impl<'a> ConjunctInfo<'a>
|
||||
|
||||
@@ -10,41 +10,41 @@ pub(super) type MachineStub = Vec<HeapCellValue>;
|
||||
// from 7.12.2 b) of 13211-1:1995
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum ValidType {
|
||||
Atom,
|
||||
Atomic,
|
||||
Byte,
|
||||
// Atom,
|
||||
// Atomic,
|
||||
// Byte,
|
||||
Callable,
|
||||
Character,
|
||||
// Character,
|
||||
Compound,
|
||||
Evaluable,
|
||||
InByte,
|
||||
InCharacter,
|
||||
// Evaluable,
|
||||
// InByte,
|
||||
// InCharacter,
|
||||
Integer,
|
||||
List,
|
||||
Number,
|
||||
// Number,
|
||||
Pair,
|
||||
PredicateIndicator,
|
||||
Variable
|
||||
// PredicateIndicator,
|
||||
// Variable
|
||||
}
|
||||
|
||||
impl ValidType {
|
||||
pub fn as_str(self) -> &'static str {
|
||||
match self {
|
||||
ValidType::Atom => "atom",
|
||||
ValidType::Atomic => "atomic",
|
||||
ValidType::Byte => "byte",
|
||||
// ValidType::Atom => "atom",
|
||||
// ValidType::Atomic => "atomic",
|
||||
// ValidType::Byte => "byte",
|
||||
ValidType::Callable => "callable",
|
||||
ValidType::Character => "character",
|
||||
// ValidType::Character => "character",
|
||||
ValidType::Compound => "compound",
|
||||
ValidType::Evaluable => "evaluable",
|
||||
ValidType::InByte => "in_byte",
|
||||
ValidType::InCharacter => "in_character",
|
||||
// ValidType::Evaluable => "evaluable",
|
||||
// ValidType::InByte => "in_byte",
|
||||
// ValidType::InCharacter => "in_character",
|
||||
ValidType::Integer => "integer",
|
||||
ValidType::List => "list",
|
||||
ValidType::Number => "number",
|
||||
// ValidType::Number => "number",
|
||||
ValidType::Pair => "pair",
|
||||
ValidType::PredicateIndicator => "predicate_indicator",
|
||||
ValidType::Variable => "variable"
|
||||
// ValidType::PredicateIndicator => "predicate_indicator",
|
||||
// ValidType::Variable => "variable"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,23 +52,23 @@ impl ValidType {
|
||||
// from 7.12.2 f) of 13211-1:1995
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum RepFlag {
|
||||
Character,
|
||||
CharacterCode,
|
||||
InCharacterCode,
|
||||
// Character,
|
||||
// CharacterCode,
|
||||
// InCharacterCode,
|
||||
MaxArity,
|
||||
MaxInteger,
|
||||
MinInteger
|
||||
// MaxInteger,
|
||||
// MinInteger
|
||||
}
|
||||
|
||||
impl RepFlag {
|
||||
pub fn as_str(self) -> &'static str {
|
||||
match self {
|
||||
RepFlag::Character => "character",
|
||||
RepFlag::CharacterCode => "character_code",
|
||||
RepFlag::InCharacterCode => "in_character_code",
|
||||
// RepFlag::Character => "character",
|
||||
// RepFlag::CharacterCode => "character_code",
|
||||
// RepFlag::InCharacterCode => "in_character_code",
|
||||
RepFlag::MaxArity => "max_arity",
|
||||
RepFlag::MaxInteger => "max_integer",
|
||||
RepFlag::MinInteger => "min_integer"
|
||||
// RepFlag::MaxInteger => "max_integer",
|
||||
// RepFlag::MinInteger => "min_integer"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -76,20 +76,20 @@ impl RepFlag {
|
||||
// from 7.12.2 g) of 13211-1:1995
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum EvalError {
|
||||
FloatOverflow,
|
||||
IntOverflow,
|
||||
Undefined,
|
||||
Underflow,
|
||||
// FloatOverflow,
|
||||
// IntOverflow,
|
||||
// Undefined,
|
||||
// Underflow,
|
||||
ZeroDivisor
|
||||
}
|
||||
|
||||
impl EvalError {
|
||||
pub fn as_str(self) -> &'static str {
|
||||
match self {
|
||||
EvalError::FloatOverflow => "float_overflow",
|
||||
EvalError::IntOverflow => "int_overflow",
|
||||
EvalError::Undefined => "undefined",
|
||||
EvalError::Underflow => "underflow",
|
||||
// EvalError::FloatOverflow => "float_overflow",
|
||||
// EvalError::IntOverflow => "int_overflow",
|
||||
// EvalError::Undefined => "undefined",
|
||||
// EvalError::Underflow => "underflow",
|
||||
EvalError::ZeroDivisor => "zero_divisor"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,6 +222,7 @@ pub struct MachineState {
|
||||
pub(super) block: usize, // an offset into the OR stack.
|
||||
pub(super) ball: Ball,
|
||||
pub(super) interms: Vec<Number>, // intermediate numbers.
|
||||
pub(super) last_call: bool
|
||||
}
|
||||
|
||||
pub(crate) type CallResult = Result<(), Vec<HeapCellValue>>;
|
||||
@@ -323,8 +324,7 @@ pub(crate) trait CallPolicy: Any {
|
||||
let b = machine_st.b - 1;
|
||||
let n = machine_st.or_stack[b].num_args();
|
||||
|
||||
for i in 1 .. n + 1 {
|
||||
let addr = machine_st.store(machine_st.deref(machine_st.or_stack[b][i].clone()));
|
||||
for i in 1 .. n + 1 {
|
||||
machine_st.registers[i] = machine_st.or_stack[b][i].clone();
|
||||
}
|
||||
|
||||
@@ -352,10 +352,10 @@ pub(crate) trait CallPolicy: Any {
|
||||
}
|
||||
|
||||
fn context_call(&mut self, machine_st: &mut MachineState, name: ClauseName, arity: usize,
|
||||
idx: CodeIndex, lco: bool)
|
||||
idx: CodeIndex)
|
||||
-> CallResult
|
||||
{
|
||||
if lco {
|
||||
if machine_st.last_call {
|
||||
self.try_execute(machine_st, name, arity, idx)
|
||||
} else {
|
||||
self.try_call(machine_st, name, arity, idx)
|
||||
@@ -401,14 +401,14 @@ pub(crate) trait CallPolicy: Any {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn call_builtin<'a>(&mut self, machine_st: &mut MachineState, ct: &BuiltInClauseType, lco: bool)
|
||||
fn call_builtin<'a>(&mut self, machine_st: &mut MachineState, ct: &BuiltInClauseType)
|
||||
-> CallResult
|
||||
{
|
||||
match ct {
|
||||
&BuiltInClauseType::AcyclicTerm => {
|
||||
let addr = machine_st[temp_v!(1)].clone();
|
||||
machine_st.fail = machine_st.is_cyclic_term(addr);
|
||||
return_from_clause!(lco, machine_st)
|
||||
return_from_clause!(machine_st.last_call, machine_st)
|
||||
},
|
||||
&BuiltInClauseType::Compare => {
|
||||
let a1 = machine_st[temp_v!(1)].clone();
|
||||
@@ -422,7 +422,7 @@ pub(crate) trait CallPolicy: Any {
|
||||
});
|
||||
|
||||
machine_st.unify(a1, c);
|
||||
return_from_clause!(lco, machine_st)
|
||||
return_from_clause!(machine_st.last_call, machine_st)
|
||||
},
|
||||
&BuiltInClauseType::CompareTerm(qt) => {
|
||||
match qt {
|
||||
@@ -433,12 +433,12 @@ pub(crate) trait CallPolicy: Any {
|
||||
_ => machine_st.compare_term(qt)
|
||||
};
|
||||
|
||||
return_from_clause!(lco, machine_st)
|
||||
return_from_clause!(machine_st.last_call, machine_st)
|
||||
},
|
||||
&BuiltInClauseType::CyclicTerm => {
|
||||
let addr = machine_st[temp_v!(1)].clone();
|
||||
machine_st.fail = !machine_st.is_cyclic_term(addr);
|
||||
return_from_clause!(lco, machine_st)
|
||||
return_from_clause!(machine_st.last_call, machine_st)
|
||||
},
|
||||
&BuiltInClauseType::Display => {
|
||||
let output = machine_st.print_term(machine_st[temp_v!(1)].clone(),
|
||||
@@ -446,27 +446,27 @@ pub(crate) trait CallPolicy: Any {
|
||||
PrinterOutputter::new());
|
||||
|
||||
println!("{}", output.result());
|
||||
return_from_clause!(lco, machine_st)
|
||||
return_from_clause!(machine_st.last_call, machine_st)
|
||||
},
|
||||
&BuiltInClauseType::DuplicateTerm => {
|
||||
machine_st.duplicate_term();
|
||||
return_from_clause!(lco, machine_st)
|
||||
return_from_clause!(machine_st.last_call, machine_st)
|
||||
},
|
||||
&BuiltInClauseType::Eq => {
|
||||
machine_st.fail = machine_st.eq_test();
|
||||
return_from_clause!(lco, machine_st)
|
||||
return_from_clause!(machine_st.last_call, machine_st)
|
||||
},
|
||||
&BuiltInClauseType::Ground => {
|
||||
machine_st.fail = machine_st.ground_test();
|
||||
return_from_clause!(lco, machine_st)
|
||||
return_from_clause!(machine_st.last_call, machine_st)
|
||||
},
|
||||
&BuiltInClauseType::Functor => {
|
||||
machine_st.try_functor()?;
|
||||
return_from_clause!(lco, machine_st)
|
||||
return_from_clause!(machine_st.last_call, machine_st)
|
||||
},
|
||||
&BuiltInClauseType::NotEq => {
|
||||
machine_st.fail = !machine_st.eq_test();
|
||||
return_from_clause!(lco, machine_st)
|
||||
return_from_clause!(machine_st.last_call, machine_st)
|
||||
},
|
||||
&BuiltInClauseType::Sort => {
|
||||
machine_st.check_sort_errors()?;
|
||||
@@ -482,7 +482,7 @@ pub(crate) trait CallPolicy: Any {
|
||||
let r2 = machine_st[temp_v!(2)].clone();
|
||||
machine_st.unify(r2, heap_addr);
|
||||
|
||||
return_from_clause!(lco, machine_st)
|
||||
return_from_clause!(machine_st.last_call, machine_st)
|
||||
},
|
||||
&BuiltInClauseType::KeySort => {
|
||||
machine_st.check_keysort_errors()?;
|
||||
@@ -504,22 +504,19 @@ pub(crate) trait CallPolicy: Any {
|
||||
let r2 = machine_st[temp_v!(2)].clone();
|
||||
machine_st.unify(r2, heap_addr);
|
||||
|
||||
return_from_clause!(lco, machine_st)
|
||||
return_from_clause!(machine_st.last_call, machine_st)
|
||||
},
|
||||
&BuiltInClauseType::Is => {
|
||||
let a = machine_st[temp_v!(1)].clone();
|
||||
let result = machine_st.arith_eval_by_metacall(temp_v!(2))?;
|
||||
|
||||
machine_st.unify(a, Addr::Con(Constant::Number(result)));
|
||||
machine_st.p += 1; // TODO: change this!!
|
||||
|
||||
Ok(())
|
||||
return_from_clause!(machine_st.last_call, machine_st)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn call_n<'a>(&mut self, machine_st: &mut MachineState, arity: usize,
|
||||
code_dirs: CodeDirs<'a>, lco: bool)
|
||||
fn call_n<'a>(&mut self, machine_st: &mut MachineState, arity: usize, code_dirs: CodeDirs<'a>)
|
||||
-> CallResult
|
||||
{
|
||||
if let Some((name, arity)) = machine_st.setup_call_n(arity) {
|
||||
@@ -541,11 +538,11 @@ pub(crate) trait CallPolicy: Any {
|
||||
machine_st.execute_inlined(&inlined),
|
||||
ClauseType::Op(..) | ClauseType::Named(..) =>
|
||||
if let Some(idx) = code_dirs.get(name.clone(), arity, user) {
|
||||
self.context_call(machine_st, name, arity, idx, lco)?;
|
||||
self.context_call(machine_st, name, arity, idx)?;
|
||||
} else {
|
||||
return Err(machine_st.existence_error(name, arity));
|
||||
},
|
||||
ClauseType::System(ct) =>
|
||||
ClauseType::System(_) =>
|
||||
return Err(machine_st.type_error(ValidType::Callable,
|
||||
Addr::Con(Constant::Atom(name))))
|
||||
};
|
||||
@@ -557,10 +554,10 @@ pub(crate) trait CallPolicy: Any {
|
||||
|
||||
impl CallPolicy for CallWithInferenceLimitCallPolicy {
|
||||
fn context_call(&mut self, machine_st: &mut MachineState, name: ClauseName,
|
||||
arity: usize, idx: CodeIndex, lco: bool)
|
||||
arity: usize, idx: CodeIndex)
|
||||
-> CallResult
|
||||
{
|
||||
self.prev_policy.context_call(machine_st, name, arity, idx, lco)?;
|
||||
self.prev_policy.context_call(machine_st, name, arity, idx)?;
|
||||
self.increment()
|
||||
}
|
||||
|
||||
@@ -588,18 +585,17 @@ impl CallPolicy for CallWithInferenceLimitCallPolicy {
|
||||
self.increment()
|
||||
}
|
||||
|
||||
fn call_builtin<'a>(&mut self, machine_st: &mut MachineState, ct: &BuiltInClauseType, lco: bool)
|
||||
fn call_builtin<'a>(&mut self, machine_st: &mut MachineState, ct: &BuiltInClauseType)
|
||||
-> CallResult
|
||||
{
|
||||
self.prev_policy.call_builtin(machine_st, ct, lco)?;
|
||||
self.prev_policy.call_builtin(machine_st, ct)?;
|
||||
self.increment()
|
||||
}
|
||||
|
||||
fn call_n<'a>(&mut self, machine_st: &mut MachineState, arity: usize, code_dirs: CodeDirs<'a>,
|
||||
lco: bool)
|
||||
fn call_n<'a>(&mut self, machine_st: &mut MachineState, arity: usize, code_dirs: CodeDirs<'a>)
|
||||
-> CallResult
|
||||
{
|
||||
self.prev_policy.call_n(machine_st, arity, code_dirs, lco)?;
|
||||
self.prev_policy.call_n(machine_st, arity, code_dirs)?;
|
||||
self.increment()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,8 @@ impl MachineState {
|
||||
hb: 0,
|
||||
block: 0,
|
||||
ball: Ball::new(),
|
||||
interms: vec![Number::default(); 256]
|
||||
interms: vec![Number::default(); 256],
|
||||
last_call: false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,16 +81,31 @@ impl MachineState {
|
||||
}
|
||||
|
||||
pub(super) fn bind(&mut self, r1: Ref, a2: Addr) {
|
||||
let t2 = self.store(a2);
|
||||
let t1 = self.store(r1.as_addr());
|
||||
let t2 = self.store(a2.clone());
|
||||
|
||||
match r1 {
|
||||
Ref::StackCell(fr, sc) =>
|
||||
self.and_stack[fr][sc] = t2,
|
||||
Ref::HeapCell(hc) =>
|
||||
self.heap[hc] = HeapCellValue::Addr(t2)
|
||||
};
|
||||
if t1.is_ref() && (!t2.is_ref() || a2 < r1) {
|
||||
match r1 {
|
||||
Ref::StackCell(fr, sc) =>
|
||||
self.and_stack[fr][sc] = t2,
|
||||
Ref::HeapCell(h) =>
|
||||
self.heap[h] = HeapCellValue::Addr(t2)
|
||||
};
|
||||
|
||||
self.trail(r1);
|
||||
self.trail(r1);
|
||||
} else {
|
||||
match a2.as_var() {
|
||||
Some(Ref::StackCell(fr, sc)) => {
|
||||
self.and_stack[fr][sc] = t1;
|
||||
self.trail(Ref::StackCell(fr, sc));
|
||||
},
|
||||
Some(Ref::HeapCell(h)) => {
|
||||
self.heap[h] = HeapCellValue::Addr(t1);
|
||||
self.trail(Ref::HeapCell(h));
|
||||
},
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
@@ -711,9 +727,9 @@ impl MachineState {
|
||||
self.write_constant_to_var(addr, c.clone());
|
||||
},
|
||||
&FactInstruction::GetList(_, reg) => {
|
||||
let addr = self.deref(self[reg].clone());
|
||||
let addr = self.store(self.deref(self[reg].clone()));
|
||||
|
||||
match self.store(addr.clone()) {
|
||||
match addr {
|
||||
Addr::HeapCell(hc) => {
|
||||
let h = self.heap.h;
|
||||
|
||||
@@ -955,10 +971,8 @@ impl MachineState {
|
||||
self.registers[arg] = self.heap[h].as_addr(h);
|
||||
}
|
||||
},
|
||||
&QueryInstruction::PutValue(norm, arg) => {
|
||||
let addr = self.store(self.deref(self[norm].clone()));
|
||||
self.registers[arg] = self[norm].clone();
|
||||
},
|
||||
&QueryInstruction::PutValue(norm, arg) =>
|
||||
self.registers[arg] = self[norm].clone(),
|
||||
&QueryInstruction::PutVariable(norm, arg) => {
|
||||
match norm {
|
||||
RegType::Perm(n) => {
|
||||
@@ -1724,20 +1738,26 @@ impl MachineState {
|
||||
match instr {
|
||||
&ControlInstruction::Allocate(num_cells) =>
|
||||
self.allocate(num_cells),
|
||||
&ControlInstruction::CallClause(ClauseType::CallN, arity, _, lco) =>
|
||||
try_or_fail!(self, call_policy.call_n(self, arity, code_dirs, lco)),
|
||||
&ControlInstruction::CallClause(ClauseType::BuiltIn(ref ct), _, _, lco) =>
|
||||
try_or_fail!(self, call_policy.call_builtin(self, ct, lco)),
|
||||
&ControlInstruction::CallClause(ClauseType::CallN, arity, _, lco) => {
|
||||
self.last_call = lco;
|
||||
try_or_fail!(self, call_policy.call_n(self, arity, code_dirs));
|
||||
},
|
||||
&ControlInstruction::CallClause(ClauseType::BuiltIn(ref ct), _, _, lco) => {
|
||||
self.last_call = lco;
|
||||
try_or_fail!(self, call_policy.call_builtin(self, ct));
|
||||
},
|
||||
&ControlInstruction::CallClause(ClauseType::Inlined(ref ct), ..) =>
|
||||
self.execute_inlined(ct),
|
||||
&ControlInstruction::CallClause(ClauseType::Named(ref name, ref idx), arity, _, lco)
|
||||
| &ControlInstruction::CallClause(ClauseType::Op(ref name, _, ref idx), arity, _, lco) =>
|
||||
try_or_fail!(self, call_policy.context_call(self, name.clone(), arity, idx.clone(),
|
||||
lco)),
|
||||
&ControlInstruction::CallClause(ClauseType::System(ref ct), arity, _, lco) => {
|
||||
| &ControlInstruction::CallClause(ClauseType::Op(ref name, _, ref idx), arity, _, lco) => {
|
||||
self.last_call = lco;
|
||||
try_or_fail!(self, call_policy.context_call(self, name.clone(), arity, idx.clone()));
|
||||
},
|
||||
&ControlInstruction::CallClause(ClauseType::System(ref ct), _, _, lco) => {
|
||||
self.last_call = lco;
|
||||
try_or_fail!(self, self.system_call(ct, call_policy, cut_policy));
|
||||
|
||||
if lco {
|
||||
if self.last_call {
|
||||
self.p = CodePtr::Local(self.cp.clone());
|
||||
} else {
|
||||
self.p += 1;
|
||||
@@ -1785,11 +1805,13 @@ impl MachineState {
|
||||
self.fail = true;
|
||||
},
|
||||
&ControlInstruction::IsClause(lco, r, ref at) => {
|
||||
self.last_call = lco;
|
||||
|
||||
let a1 = self[r].clone();
|
||||
let a2 = try_or_fail!(self, self.get_number(at));
|
||||
|
||||
self.unify(a1, Addr::Con(Constant::Number(a2)));
|
||||
try_or_fail!(self, return_from_clause!(lco, self));
|
||||
try_or_fail!(self, return_from_clause!(self.last_call, self));
|
||||
},
|
||||
&ControlInstruction::JmpBy(arity, offset, _, lco) => {
|
||||
if !lco {
|
||||
|
||||
@@ -233,9 +233,10 @@ impl Machine {
|
||||
CodePtr::Local(LocalCodePtr::DirEntry(p, _)) =>
|
||||
Some(self.code[p].clone()),
|
||||
CodePtr::BuiltInClause(built_in, _) =>
|
||||
Some(call_clause!(ClauseType::BuiltIn(built_in), built_in.arity(), 0)),
|
||||
Some(call_clause!(ClauseType::BuiltIn(built_in), built_in.arity(),
|
||||
0, self.ms.last_call)),
|
||||
CodePtr::CallN(arity, _) =>
|
||||
Some(call_clause!(ClauseType::CallN, arity, 0))
|
||||
Some(call_clause!(ClauseType::CallN, arity, 0, self.ms.last_call))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -134,7 +134,10 @@ macro_rules! is_var {
|
||||
macro_rules! call_clause {
|
||||
($ct:expr, $arity:expr, $pvs:expr) => (
|
||||
Line::Control(ControlInstruction::CallClause($ct, $arity, $pvs, false))
|
||||
)
|
||||
);
|
||||
($ct:expr, $arity:expr, $pvs:expr, $lco:expr) => (
|
||||
Line::Control(ControlInstruction::CallClause($ct, $arity, $pvs, $lco))
|
||||
)
|
||||
}
|
||||
|
||||
macro_rules! proceed {
|
||||
@@ -144,9 +147,8 @@ macro_rules! proceed {
|
||||
}
|
||||
|
||||
macro_rules! is_call {
|
||||
($r:expr, $at:expr) => (
|
||||
($r:expr, $at:expr) => (
|
||||
Line::Control(ControlInstruction::IsClause(false, $r, $at))
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user