}
let b = self.b - 1;
- let mut i = self.or_stack[b].tr;
+ let hb = self.hb;
+ let mut offset = 0;
- while i < self.tr {
- let tr_i = self.trail[i];
- let hb = self.hb;
-
- match tr_i {
+ for i in self.or_stack[b].tr .. self.tr {
+ match self.trail[i] {
TrailRef::Ref(Ref::AttrVar(tr_i))
| TrailRef::Ref(Ref::HeapCell(tr_i))
| TrailRef::AttrVarHeapLink(tr_i)
- | TrailRef::AttrVarListLink(tr_i, _) => {
- if tr_i < hb {
- i += 1;
- } else {
- let tr = self.tr;
- let val = self.trail[tr - 1].clone();
- self.trail[i] = val;
- self.trail.pop();
- self.tr -= 1;
- }
- }
+ | TrailRef::AttrVarListLink(tr_i, _) =>
+ if tr_i >= hb {
+ offset += 1;
+ } else {
+ self.trail[i - offset] = self.trail[i];
+ },
TrailRef::Ref(Ref::StackCell(fr, _)) => {
- let b = self.b - 1;
let fr_gi = self.and_stack[fr].global_index;
let b_gi = if !self.or_stack.is_empty() {
self.or_stack[b].global_index
0
};
- if fr_gi < b_gi {
- i += 1;
+ if fr_gi >= b_gi {
+ offset += 1;
} else {
- let tr = self.tr;
- let val = self.trail[tr - 1];
- self.trail[i] = val;
- self.trail.pop();
- self.tr -= 1;
+ self.trail[i - offset] = self.trail[i];
}
}
- };
+ }
}
- }
+ self.tr -= offset;
+ self.trail.truncate(self.tr);
+ }
+
#[inline]
fn write_char_to_string(&mut self, s: &mut StringList, c: char) -> bool {
self.pstr_trail(s.clone());
} 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.heap_locs.clear();
self.lifted_heap.clear();
}
-
- pub(super) fn sink_to_snapshot(&mut self) -> MachineState {
- let mut snapshot = MachineState::with_capacity(0);
-
- snapshot.hb = self.hb;
- snapshot.e = self.e;
- snapshot.b = self.b;
- snapshot.b0 = self.b0;
- snapshot.s = self.s;
- snapshot.tr = self.tr;
- snapshot.pstr_tr = self.pstr_tr;
- snapshot.num_of_args = self.num_of_args;
-
- snapshot.fail = self.fail;
- snapshot.trail = mem::replace(&mut self.trail, vec![]);
- snapshot.pstr_trail = mem::replace(&mut self.pstr_trail, vec![]);
- snapshot.heap = self.heap.take();
- snapshot.mode = self.mode;
- snapshot.and_stack = self.and_stack.take();
- snapshot.or_stack = self.or_stack.take();
- snapshot.registers = mem::replace(&mut self.registers, vec![]);
- snapshot.block = self.block;
-
- snapshot.ball = self.ball.take();
- snapshot.lifted_heap = mem::replace(&mut self.lifted_heap, vec![]);
-
- snapshot
- }
-
- pub(super) fn absorb_snapshot(&mut self, mut snapshot: MachineState) {
- self.hb = snapshot.hb;
- self.e = snapshot.e;
- self.b = snapshot.b;
- self.b0 = snapshot.b0;
- self.s = snapshot.s;
- self.tr = snapshot.tr;
- self.pstr_tr = snapshot.pstr_tr;
- self.num_of_args = snapshot.num_of_args;
-
- self.fail = snapshot.fail;
- self.trail = mem::replace(&mut snapshot.trail, vec![]);
- self.pstr_trail = mem::replace(&mut snapshot.pstr_trail, vec![]);
- self.heap = snapshot.heap.take();
- self.mode = snapshot.mode;
- self.and_stack = snapshot.and_stack.take();
- self.or_stack = snapshot.or_stack.take();
- self.registers = mem::replace(&mut snapshot.registers, vec![]);
- self.block = snapshot.block;
-
- self.ball = snapshot.ball.take();
- self.lifted_heap = mem::replace(&mut snapshot.lifted_heap, vec![]);
- }
}
use crate::prolog::forms::*;
use crate::prolog::heap_print::*;
use crate::prolog::instructions::*;
+use crate::prolog::machine::heap::Heap;
use crate::prolog::read::*;
use crate::prolog::write::{next_keypress, ContinueResult};
pub struct Machine {
pub(super) machine_st: MachineState,
+ pub(super) inner_heap: Heap,
pub(super) policies: MachinePolicies,
pub(super) indices: IndexStore,
pub(super) code_repo: CodeRepo,
}
pub fn run_init_code(&mut self, code: Code) {
- let old_machine_st = self.machine_st.sink_to_snapshot();
+ let old_machine_st = self.sink_to_snapshot();
self.machine_st.reset();
self.code_repo.cached_query = code;
self.run_query(&AllocVarDict::new());
- self.machine_st.absorb_snapshot(old_machine_st);
+ self.absorb_snapshot(old_machine_st);
}
pub fn run_top_level(&mut self) {
pub fn new(prolog_stream: PrologStream) -> Self {
let mut wam = Machine {
machine_st: MachineState::new(),
+ inner_heap: Heap::with_capacity(256 * 256),
policies: MachinePolicies::new(),
indices: IndexStore::new(),
code_repo: CodeRepo::new(),
};
let stream = parsing_stream(s.as_bytes());
+ let snapshot = self.sink_to_snapshot();
+ let policies = mem::replace(&mut self.policies, MachinePolicies::new());
- let snapshot = self.machine_st.sink_to_snapshot();
self.machine_st.reset();
+ self.machine_st.heap = mem::replace(
+ &mut self.inner_heap,
+ Heap::with_capacity(0),
+ );
let result = match stream_to_toplevel(stream, self) {
Ok(packet) => compile_term(self, packet),
};
self.handle_eval_session(result, snapshot);
+ self.indices.reset_global_variable_offsets();
+ self.policies = policies;
}
REPLCodePtr::UseModule =>
self.use_module(ModuleSource::Library),
self.machine_st.p = CodePtr::Local(p);
}
+ fn sink_to_snapshot(&mut self) -> MachineState {
+ let mut snapshot = MachineState::with_capacity(0);
+
+ snapshot.hb = self.machine_st.hb;
+ snapshot.e = self.machine_st.e;
+ snapshot.b = self.machine_st.b;
+ snapshot.b0 = self.machine_st.b0;
+ snapshot.s = self.machine_st.s;
+ snapshot.tr = self.machine_st.tr;
+ snapshot.pstr_tr = self.machine_st.pstr_tr;
+ snapshot.num_of_args = self.machine_st.num_of_args;
+
+ snapshot.fail = self.machine_st.fail;
+ snapshot.trail = mem::replace(&mut self.machine_st.trail, vec![]);
+ snapshot.pstr_trail = mem::replace(&mut self.machine_st.pstr_trail, vec![]);
+ snapshot.heap = self.machine_st.heap.take();
+ snapshot.mode = self.machine_st.mode;
+ snapshot.and_stack = self.machine_st.and_stack.take();
+ snapshot.or_stack = self.machine_st.or_stack.take();
+ snapshot.registers = mem::replace(&mut self.machine_st.registers, vec![]);
+ snapshot.block = self.machine_st.block;
+
+ snapshot.ball = self.machine_st.ball.take();
+ snapshot.lifted_heap = mem::replace(&mut self.machine_st.lifted_heap, vec![]);
+
+ snapshot
+ }
+
+ fn absorb_snapshot(&mut self, mut snapshot: MachineState) {
+ self.machine_st.hb = snapshot.hb;
+ self.machine_st.e = snapshot.e;
+ self.machine_st.b = snapshot.b;
+ self.machine_st.b0 = snapshot.b0;
+ self.machine_st.s = snapshot.s;
+ self.machine_st.tr = snapshot.tr;
+ self.machine_st.pstr_tr = snapshot.pstr_tr;
+ self.machine_st.num_of_args = snapshot.num_of_args;
+
+ self.machine_st.fail = snapshot.fail;
+ self.machine_st.trail = mem::replace(&mut snapshot.trail, vec![]);
+ self.machine_st.pstr_trail = mem::replace(&mut snapshot.pstr_trail, vec![]);
+
+ self.inner_heap = self.machine_st.heap.take();
+ self.inner_heap.truncate(0);
+
+ self.machine_st.heap = snapshot.heap.take();
+ self.machine_st.mode = snapshot.mode;
+ self.machine_st.and_stack = snapshot.and_stack.take();
+ self.machine_st.or_stack = snapshot.or_stack.take();
+ self.machine_st.registers = mem::replace(&mut snapshot.registers, vec![]);
+ self.machine_st.block = snapshot.block;
+
+ self.machine_st.ball = snapshot.ball.take();
+ self.machine_st.lifted_heap = mem::replace(&mut snapshot.lifted_heap, vec![]);
+ }
+
fn propagate_exception_to_toplevel(&mut self, snapshot: MachineState) {
let ball = self.machine_st.ball.take();
- self.machine_st.absorb_snapshot(snapshot);
+ self.absorb_snapshot(snapshot);
self.machine_st.ball = ball;
let h = self.machine_st.heap.h;
};
let attr_goals = self.attribute_goals();
-
+
if !(self.machine_st.b > 0) {
if bindings.is_empty() {
let space = if requires_space(&attr_goals, ".") {
println!("true.");
}
- self.machine_st.absorb_snapshot(snapshot);
+ self.absorb_snapshot(snapshot);
return;
}
} else if bindings.is_empty() && attr_goals.is_empty() {
}
ContinueResult::Conclude => {
print!(" ...\r\n");
- self.machine_st.absorb_snapshot(snapshot);
+ self.absorb_snapshot(snapshot);
return;
}
};
return;
} else {
print!("false.\r\n");
- self.machine_st.absorb_snapshot(snapshot);
+ self.absorb_snapshot(snapshot);
return;
}
}
EvalSession::Error(err) => {
- self.machine_st.absorb_snapshot(snapshot);
+ self.absorb_snapshot(snapshot);
self.throw_session_error(err, (clause_name!("repl"), 0));
return;
}
}
},
EvalSession::Error(err) => {
- self.machine_st.absorb_snapshot(snapshot);
+ self.absorb_snapshot(snapshot);
self.throw_session_error(err, (clause_name!("repl"), 0));
return;
}
_ => println!("true.")
}
- self.machine_st.absorb_snapshot(snapshot);
+ self.absorb_snapshot(snapshot);
}
pub(super) fn run_query(&mut self, alloc_locs: &AllocVarDict) {
CodePtr::VerifyAttrInterrupt(_) => {
self.p = CodePtr::Local(self.attr_var_init.cp);
- if !self.verify_attr_stepper(indices, policies, code_repo, prolog_stream) {
+ let instigating_p = CodePtr::Local(self.attr_var_init.instigating_p);
+ let instigating_instr = code_repo.lookup_instr(false, &instigating_p).unwrap();
+
+ if instigating_instr.as_ref().is_head_instr() {
+ let cp = self.p.local();
+ self.run_verify_attr_interrupt(cp);
+ } else if !self.verify_attr_stepper(indices, policies, code_repo, prolog_stream) {
if self.fail {
break;
}