machine_st.registers[i] = machine_st.or_stack[b][i].clone();
}
- // necessary because of restore_snapshot. similarly for other choice instructions.
machine_st.num_of_args = n;
machine_st.e = machine_st.or_stack[b].e;
machine_st.cp = machine_st.or_stack[b].cp.clone();
+ machine_st.pop_stack_frames();
+
machine_st.or_stack[b].bp = machine_st.p.clone() + offset;
let old_tr = machine_st.or_stack[b].tr;
machine_st.e = machine_st.or_stack[b].e;
machine_st.cp = machine_st.or_stack[b].cp.clone();
+ machine_st.pop_stack_frames();
+
machine_st.or_stack[b].bp = machine_st.p.clone() + 1;
let old_tr = machine_st.or_stack[b].tr;
machine_st.b = machine_st.or_stack[b].b;
machine_st.or_stack.truncate(machine_st.b);
+ machine_st.pop_stack_frames();
+
machine_st.hb = machine_st.heap.h;
machine_st.p += offset;
machine_st.b = machine_st.or_stack[b].b;
machine_st.or_stack.truncate(machine_st.b);
+ machine_st.pop_stack_frames();
+
machine_st.hb = machine_st.heap.h;
machine_st.p += 1;
}
_ => {
self.push_attr_var_binding(h, addr.clone());
- self.heap[h] = HeapCellValue::Addr(addr);
+ self.heap[h] = HeapCellValue::Addr(addr);
self.trail(TrailRef::Ref(Ref::AttrVar(h)));
}
}
} else if s.is_expandable() {
self.heap
.push(HeapCellValue::Addr(Addr::Con(Constant::String(s.clone()))));
-
+
self.s = h;
self.mode = MachineMode::Read;
} else {
_ => self.fail = true,
},
addr @ Addr::AttrVar(_)
- | addr @ Addr::StackCell(..)
- | addr @ Addr::HeapCell(_) => {
+ | addr @ Addr::StackCell(..)
+ | addr @ Addr::HeapCell(_) => {
let h = self.heap.h;
self.heap.push(HeapCellValue::Addr(Addr::Lis(h + 1)));
let offset = match addr {
Addr::HeapCell(_) | Addr::StackCell(..) | Addr::AttrVar(..) => v,
Addr::Con(Constant::String(ref s)) if !self.flags.double_quotes.is_atom() => {
- if s.is_empty() && !s.is_expandable() {
- c
+ if s.is_empty() {
+ if s.is_expandable() {
+ v
+ } else {
+ c
+ }
} else {
l
}
&IndexingInstruction::SwitchOnConstant(_, ref hm) => {
let a1 = self.registers[1].clone();
let addr = self.store(self.deref(a1));
-
+
let offset = match addr {
Addr::Con(constant) => match hm.get(&constant) {
Some(offset) => *offset,
for i in 1..narity + 1 {
self.registers[i] = self.heap[a + i].as_addr(a + i);
}
-
+
(name, narity)
} else {
self.fail = true;
(HeapCellValue::Addr(a1), HeapCellValue::Addr(a2)) =>
if a1 != a2 {
return true;
- },
+ },
_ => return true,
}
}
let gi = self.next_global_index();
self.p += 1;
-
+
if self.e + 1 < self.and_stack.len() {
let and_gi = self.and_stack[self.e].global_index;
let or_gi = self
self.p += 1;
}
+ pub(super) fn pop_stack_frames(&mut self) {
+ if self.and_stack.len() > self.e {
+ let and_gi = self.and_stack[self.e].global_index;
+ let or_gi = self
+ .or_stack
+ .top()
+ .map(|or_fr| or_fr.global_index)
+ .unwrap_or(0);
+
+ if and_gi > or_gi {
+ self.and_stack.truncate(self.e + 1);
+ }
+ }
+ }
+
fn handle_call_clause(
&mut self,
indices: &mut IndexStore,
self.fail = true;
return;
}
-
+
let mut default_call_policy: Box<dyn CallPolicy> = Box::new(DefaultCallPolicy {});
let call_policy = if use_default_cp {
&mut default_call_policy