]> Repositorios git - scryer-prolog.git/commitdiff
preliminary cont work
authorMark Thom <[email protected]>
Fri, 20 Dec 2019 00:02:10 +0000 (20:02 -0400)
committerMark Thom <[email protected]>
Fri, 20 Dec 2019 00:02:10 +0000 (20:02 -0400)
1  2 
src/prolog/clause_types.rs
src/prolog/lib/cont.pl
src/prolog/machine/compile.rs
src/prolog/machine/copier.rs
src/prolog/machine/machine_state.rs
src/prolog/machine/machine_state_impl.rs
src/prolog/machine/system_calls.rs

index 82bd8cde6076d538af3a6d21e654182a05e194e0,006ea3d48bf148431766fda48babe9e73b3cc0ba..10a0ebfd56ca116307b5ad5752cbccf60fa5c1aa
@@@ -162,6 -162,6 +162,7 @@@ pub enum SystemClauseType 
      AtomChars,
      AtomCodes,
      AtomLength,
++    BindFromRegister,
      CallAttributeGoals,
      CharCode,
      CharsToNumber,
      REPL(REPLCodePtr),
      ReadQueryTerm,
      ReadTerm,
-     RedoAttrVarBindings,
+     RedoAttrVarBinding,
      RemoveCallPolicyCheck,
      RemoveInferenceCounter,
++    ResetContinuationMarker,
      ResetGlobalVarAtKey,
      ResetGlobalVarAtOffset,
      RetractClause,
@@@ -260,6 -264,6 +266,7 @@@ impl SystemClauseType 
              &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),
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..6fc0118bd88d4f3c786df7f8506f7e617176e91d
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,29 @@@
++
++:- 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'(_, _, _, _).
++
Simple merge
index e7cb9e6e7f52c638f073f96c5af9e5e58d917ddc,13e21ee360c3c734501205b560d526f60aca9fb2..8fe112662ac4a3e1cd9a1fe90a70e0e2bfd74da5
@@@ -10,12 -16,13 +16,13 @@@ pub(crate) trait CopierTarget: IndexMut
      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> {
@@@ -114,9 -108,49 +108,49 @@@ impl<T: CopierTarget> CopyTermState<T> 
          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()));
  
index 64c761cd1f6856ccae2bd7a325b6b3bf05e5302b,fddfb264626322c3428902eaf9da145cf32f18d8..49feac7dd14b93e004e7806ef6d28cee67a53afe
@@@ -439,12 -441,15 +439,15 @@@ pub(crate) trait CallPolicy: Any 
  
          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;
  
index a56da366f02205023375cde48cab4cc75bd22bbe,63ace01f2c7caee48518a857d601ebb539af9b79..a23a43579d6fe4ba821001e4b0dee834796c7cd9
@@@ -2005,11 -2037,15 +2005,15 @@@ impl MachineState 
      }
  
      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,
          );
      }
  
index 89fbde2d9e437a57bf46a4c02252505f2051468a,2fb652d40ce3d9b883c5d364472e1f9b8deba171..7d32b50004803f24c0276c415df4df086f9a1390
@@@ -594,6 -604,6 +604,25 @@@ impl MachineState 
                  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);