AtomChars,
AtomCodes,
AtomLength,
++ BindFromRegister,
CallAttributeGoals,
CharCode,
CharsToNumber,
REPL(REPLCodePtr),
ReadQueryTerm,
ReadTerm,
- RedoAttrVarBindings,
+ RedoAttrVarBinding,
RemoveCallPolicyCheck,
RemoveInferenceCounter,
++ ResetContinuationMarker,
ResetGlobalVarAtKey,
ResetGlobalVarAtOffset,
RetractClause,
&SystemClauseType::AtomChars => clause_name!("$atom_chars"),
&SystemClauseType::AtomCodes => clause_name!("$atom_codes"),
&SystemClauseType::AtomLength => clause_name!("$atom_length"),
++ &SystemClauseType::BindFromRegister => clause_name!("$bind_from_register"),
&SystemClauseType::CallAttributeGoals => clause_name!("$call_attribute_goals"),
&SystemClauseType::CharCode => clause_name!("$char_code"),
&SystemClauseType::CharsToNumber => clause_name!("$chars_to_number"),
&SystemClauseType::ResetGlobalVarAtOffset => clause_name!("$reset_global_var_at_offset"),
&SystemClauseType::RetractClause => clause_name!("$retract_clause"),
&SystemClauseType::ResetBlock => clause_name!("$reset_block"),
++ &SystemClauseType::ResetContinuationMarker => clause_name!("$reset_cont_marker"),
&SystemClauseType::ReturnFromVerifyAttr => clause_name!("$return_from_verify_attr"),
&SystemClauseType::SetBall => clause_name!("$set_ball"),
&SystemClauseType::SetCutPointByDefault(_) => clause_name!("$set_cp_by_default"),
("$atom_codes", 2) => Some(SystemClauseType::AtomCodes),
("$atom_length", 2) => Some(SystemClauseType::AtomLength),
("$abolish_module_clause", 3) => Some(SystemClauseType::AbolishModuleClause),
++ ("$bind_from_register", 2) => Some(SystemClauseType::BindFromRegister),
("$module_asserta", 5) => Some(SystemClauseType::ModuleAssertDynamicPredicateToFront),
("$module_assertz", 5) => Some(SystemClauseType::ModuleAssertDynamicPredicateToBack),
("$asserta", 4) => Some(SystemClauseType::AssertDynamicPredicateToFront),
("$read_query_term", 2) => Some(SystemClauseType::ReadQueryTerm),
("$read_term", 2) => Some(SystemClauseType::ReadTerm),
("$reset_block", 1) => Some(SystemClauseType::ResetBlock),
++ ("$reset_cont_marker", 0) => Some(SystemClauseType::ResetContinuationMarker),
("$reset_global_var_at_key", 1) => Some(SystemClauseType::ResetGlobalVarAtKey),
("$reset_global_var_at_offset", 3) => Some(SystemClauseType::ResetGlobalVarAtOffset),
("$retract_clause", 4) => Some(SystemClauseType::RetractClause),
--- /dev/null
--- /dev/null
++
++:- module(cont, [reset/3, shift/1]).
++
++reset(Goal, Cont, Term) :-
++ call(Goal),
++ '$reset_cont_marker',
++ '$bind_from_register'(Cont, 3),
++ '$bind_from_register'(Term, 4).
++
++shift(Term) :-
++ '$nextEP'(first, E, P),
++ get_chunks(E, P, L),
++ Cont = cont(call_continuation(L)),
++ '$write_cont_and_term'(_, _, Cont, Term),
++ '$unwind_environments'.
++
++get_chunks(E, P, L) :-
++ ( '$points_to_cont_reset_marker'(P) ->
++ L = []
++ ; '$get_chunk'(E,P,TB),
++ L = [TB|Rest],
++ '$nextEP'(E, NextE, NextP),
++ get_chunks(NextE, NextP, Rest)
++ ).
++
++call_continuation(L) :- '$call_continuation'(L).
++
++'$write_cont_and_term'(_, _, _, _).
++
fn push(&mut self, _: HeapCellValue);
fn store(&self, _: Addr) -> Addr;
fn deref(&self, _: Addr) -> Addr;
- fn stack(&mut self) -> &mut AndStack;
+ fn stack(&mut self) -> &mut Stack;
}
- pub(crate) fn copy_term<T: CopierTarget>(target: T, addr: Addr) {
- let mut copy_term_state = CopyTermState::new(target);
- copy_term_state.copy_term_impl(addr);
+ pub(crate)
+ fn copy_term<T: CopierTarget>(target: T, addr: Addr, attr_var_policy: AttrVarPolicy) {
+ let mut copy_term_state = CopyTermState::new(target, attr_var_policy);
+ copy_term_state.copy_term_impl(addr);
}
struct CopyTermState<T: CopierTarget> {
self.scan += 1;
}
- self.target.stack()[fr][sc] = Addr::HeapCell(frontier);
+ fn reinstantiate_var(&mut self, addr: Addr, frontier: usize) {
+ match addr {
+ Addr::HeapCell(h) => {
+ self.target[frontier] = HeapCellValue::Addr(Addr::HeapCell(frontier));
+ self.target[h] = HeapCellValue::Addr(Addr::HeapCell(frontier));
+ self.trail.push((
+ Ref::HeapCell(h),
+ HeapCellValue::Addr(Addr::HeapCell(h)),
+ ));
+ }
+ Addr::StackCell(fr, sc) => {
+ self.target[frontier] = HeapCellValue::Addr(Addr::HeapCell(frontier));
++ self.target.stack().index_and_frame_mut(fr)[sc] = Addr::HeapCell(frontier);
+ self.trail.push((
+ Ref::StackCell(fr, sc),
+ HeapCellValue::Addr(Addr::StackCell(fr, sc)),
+ ));
+ }
+ Addr::AttrVar(h) => {
+ let threshold = if let AttrVarPolicy::DeepCopy = self.attr_var_policy {
+ self.target.threshold()
+ } else {
+ frontier
+ };
+
+ self.target[frontier] = HeapCellValue::Addr(Addr::HeapCell(threshold));
+ self.target[h] = HeapCellValue::Addr(Addr::HeapCell(threshold));
+ self.trail.push((
+ Ref::AttrVar(h),
+ HeapCellValue::Addr(Addr::AttrVar(h)),
+ ));
+
+ if let AttrVarPolicy::DeepCopy = self.attr_var_policy {
+ self.target.push(HeapCellValue::Addr(Addr::AttrVar(threshold)));
+
+ let list_val = self.target[h + 1].clone();
+ self.target.push(list_val);
+ }
+ }
+ _ => unreachable!()
+ }
+ }
+
fn copy_var(&mut self, addr: Addr) {
let rd = self.target.store(self.target.deref(addr.clone()));
machine_st.pstr_trail.truncate(machine_st.pstr_tr);
- machine_st.heap.truncate(machine_st.or_stack[b].h);
+ machine_st.heap.truncate(machine_st.stack.index_or_frame(b).prelude.h);
- let attr_var_init_queue_b = machine_st.or_stack[b].attr_var_init_queue_b;
- let attr_var_init_bindings_b = machine_st.or_stack[b].attr_var_init_bindings_b;
+ let attr_var_init_queue_b = machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
+ let attr_var_init_bindings_b = machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b;
- machine_st.attr_var_init.backtrack(attr_var_init_queue_b, attr_var_init_bindings_b);
+ machine_st.attr_var_init.backtrack(
+ attr_var_init_queue_b,
+ attr_var_init_bindings_b,
+ );
machine_st.hb = machine_st.heap.h;
machine_st.p += 1;
let curr_pstr_tr = machine_st.pstr_tr;
machine_st.unwind_pstr_trail(old_pstr_tr, curr_pstr_tr);
- machine_st.pstr_tr = machine_st.or_stack[b].pstr_tr;
+ machine_st.pstr_tr = machine_st.stack.index_or_frame(b).prelude.pstr_tr;
machine_st.pstr_trail.truncate(machine_st.pstr_tr);
-
- machine_st.heap.truncate(machine_st.or_stack[b].h);
+ machine_st.heap.truncate(machine_st.stack.index_or_frame(b).prelude.h);
- let attr_var_init_queue_b = machine_st.or_stack[b].attr_var_init_queue_b;
- let attr_var_init_bindings_b = machine_st.or_stack[b].attr_var_init_bindings_b;
+ let attr_var_init_queue_b = machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
+ let attr_var_init_bindings_b = machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b;
- machine_st.attr_var_init.backtrack(
- attr_var_init_queue_b,
- attr_var_init_bindings_b,
- );
+ machine_st.attr_var_init.backtrack(attr_var_init_queue_b, attr_var_init_bindings_b);
machine_st.hb = machine_st.heap.h;
machine_st.p += offset;
}
fn trust(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
- let b = machine_st.b - 1;
- let n = machine_st.or_stack[b].num_args();
+ let b = machine_st.b;
+ let n = machine_st.stack.index_or_frame(b).prelude.univ_prelude.num_cells;
- for i in 1..n + 1 {
- machine_st.registers[i] = machine_st.or_stack[b][i].clone();
+ for i in 1 .. n + 1 {
+ machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i-1].clone();
}
--
- let old_e = machine_st.e;
+
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.e = machine_st.stack.index_or_frame(b).prelude.e;
+ machine_st.cp = machine_st.stack.index_or_frame(b).prelude.cp;
- let old_tr = machine_st.or_stack[b].tr;
+ let old_tr = machine_st.stack.index_or_frame(b).prelude.tr;
let curr_tr = machine_st.tr;
machine_st.unwind_trail(old_tr, curr_tr);
let curr_pstr_tr = machine_st.pstr_tr;
machine_st.unwind_pstr_trail(old_pstr_tr, curr_pstr_tr);
- machine_st.pstr_tr = machine_st.or_stack[b].pstr_tr;
+ machine_st.pstr_tr = machine_st.stack.index_or_frame(b).prelude.pstr_tr;
machine_st.pstr_trail.truncate(machine_st.pstr_tr);
-
- machine_st.heap.truncate(machine_st.or_stack[b].h);
+ machine_st.heap.truncate(machine_st.stack.index_or_frame(b).prelude.h);
- let attr_var_init_queue_b = machine_st.or_stack[b].attr_var_init_queue_b;
- let attr_var_init_bindings_b = machine_st.or_stack[b].attr_var_init_bindings_b;
+ let attr_var_init_queue_b = machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
+ let attr_var_init_bindings_b = machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b;
- machine_st.attr_var_init.backtrack(attr_var_init_queue_b, attr_var_init_bindings_b);
+ machine_st.attr_var_init.backtrack(
+ attr_var_init_queue_b,
- attr_var_init_bindings_b,
- );
++ attr_var_init_bindings_b);
- machine_st.b = machine_st.or_stack[b].b;
- machine_st.or_stack.truncate(machine_st.b);
+ machine_st.b = machine_st.stack.index_or_frame(b).prelude.b;
+ machine_st.truncate_stack();
machine_st.hb = machine_st.heap.h;
machine_st.p += offset;
let curr_pstr_tr = machine_st.pstr_tr;
machine_st.unwind_pstr_trail(old_pstr_tr, curr_pstr_tr);
+ machine_st.pstr_tr = machine_st.stack.index_or_frame(b).prelude.pstr_tr;
- machine_st.pstr_tr = machine_st.or_stack[b].pstr_tr;
++ machine_st.pstr_tr = machine_st.stack.index_or_frame(b).prelude.pstr_tr;
machine_st.pstr_trail.truncate(machine_st.pstr_tr);
- machine_st.heap.truncate(machine_st.or_stack[b].h);
+ machine_st.heap.truncate(machine_st.stack.index_or_frame(b).prelude.h);
- let attr_var_init_queue_b = machine_st.or_stack[b].attr_var_init_queue_b;
- let attr_var_init_bindings_b = machine_st.or_stack[b].attr_var_init_bindings_b;
+ let attr_var_init_queue_b = machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
+ let attr_var_init_bindings_b = machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b;
- machine_st.attr_var_init.backtrack(attr_var_init_queue_b, attr_var_init_bindings_b);
+ machine_st.attr_var_init.backtrack(
+ attr_var_init_queue_b,
- attr_var_init_bindings_b,
++ attr_var_init_bindings_b
+ );
- machine_st.b = machine_st.or_stack[b].b;
- machine_st.or_stack.truncate(machine_st.b);
-
+ machine_st.b = machine_st.stack.index_or_frame(b).prelude.b;
+ machine_st.truncate_stack();
+
machine_st.hb = machine_st.heap.h;
machine_st.p += 1;
}
pub(super) fn set_ball(&mut self) {
+ self.ball.reset();
+
let addr = self[temp_v!(1)].clone();
self.ball.boundary = self.heap.h;
+
copy_term(
- CopyBallTerm::new(&mut self.and_stack, &mut self.heap, &mut self.ball.stub),
+ CopyBallTerm::new(&mut self.stack, &mut self.heap, &mut self.ball.stub),
addr,
+ AttrVarPolicy::DeepCopy,
);
}
self.p = CodePtr::DynamicTransaction(trans_type, p);
return Ok(());
}
++ &SystemClauseType::BindFromRegister => {
++ let reg = self.store(self.deref(self[temp_v!(2)].clone()));
++ let n = match reg {
++ Addr::Con(Constant::Integer(n)) => n.to_usize(),
++ _ => unreachable!()
++ };
++
++ if let Some(n) = n {
++ if n <= MAX_ARITY {
++ let target = self[temp_v!(n)].clone();
++ let addr = self[temp_v!(1)].clone();
++
++ self.unify(addr, target);
++ return return_from_clause!(self.last_call, self);
++ }
++ }
++
++ self.fail = true;
++ }
&SystemClauseType::AssertDynamicPredicateToFront => {
let p = self.cp;
let trans_type = DynamicTransactionType::Assert(DynamicAssertPlace::Front);
ball.boundary = h;
copy_term(
- CopyBallTerm::new(&mut self.and_stack, &mut self.heap, &mut ball.stub),
+ CopyBallTerm::new(&mut self.stack, &mut self.heap, &mut ball.stub),
value,
+ AttrVarPolicy::DeepCopy,
);
let offset = self[temp_v!(3)].clone();
&SystemClauseType::ReadTerm => {
readline::set_prompt(false);
self.read_term(current_input_stream, indices)?;
-- },
++ }
&SystemClauseType::ResetBlock => {
let addr = self.deref(self[temp_v!(1)].clone());
self.reset_block(addr);
}
++ &SystemClauseType::ResetContinuationMarker => {
++ }
&SystemClauseType::SetBall =>
self.set_ball(),
&SystemClauseType::SetSeed => {
ball.boundary = self.heap.h;
copy_term(
- CopyBallTerm::new(&mut self.and_stack, &mut self.heap, &mut ball.stub),
+ CopyBallTerm::new(&mut self.stack, &mut self.heap, &mut ball.stub),
value,
+ AttrVarPolicy::DeepCopy,
);
indices.global_variables.insert(key, (ball, None));
ball.boundary = h;
copy_term(
- CopyBallTerm::new(&mut self.and_stack, &mut self.heap, &mut ball.stub),
+ CopyBallTerm::new(&mut self.stack, &mut self.heap, &mut ball.stub),
value.clone(),
+ AttrVarPolicy::DeepCopy,
);
let stub = ball.copy_and_align(h);