move SGC and call inference instructions over to SystemClauseType
This commit is contained in:
@@ -702,7 +702,9 @@ pub struct Rule {
|
|||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq)]
|
#[derive(Copy, Clone, PartialEq)]
|
||||||
pub enum SystemClauseType {
|
pub enum SystemClauseType {
|
||||||
InstallCleaner,
|
CheckCutPoint,
|
||||||
|
GetSCCCleaner,
|
||||||
|
InstallSCCCleaner,
|
||||||
InstallInferenceCounter,
|
InstallInferenceCounter,
|
||||||
RemoveCallPolicyCheck,
|
RemoveCallPolicyCheck,
|
||||||
RemoveInferenceCounter,
|
RemoveInferenceCounter,
|
||||||
@@ -730,7 +732,9 @@ impl SystemClauseType {
|
|||||||
|
|
||||||
pub fn name(&self) -> ClauseName {
|
pub fn name(&self) -> ClauseName {
|
||||||
match self {
|
match self {
|
||||||
&SystemClauseType::InstallCleaner => clause_name!("$install_cleaner"),
|
&SystemClauseType::CheckCutPoint => clause_name!("$check_cp"),
|
||||||
|
&SystemClauseType::GetSCCCleaner => clause_name!("$get_scc_cleaner"),
|
||||||
|
&SystemClauseType::InstallSCCCleaner => clause_name!("$install_scc_cleaner"),
|
||||||
&SystemClauseType::InstallInferenceCounter =>
|
&SystemClauseType::InstallInferenceCounter =>
|
||||||
clause_name!("$install_inference_counter"),
|
clause_name!("$install_inference_counter"),
|
||||||
&SystemClauseType::RemoveCallPolicyCheck =>
|
&SystemClauseType::RemoveCallPolicyCheck =>
|
||||||
@@ -757,8 +761,10 @@ impl SystemClauseType {
|
|||||||
|
|
||||||
pub fn from(name: &str, arity: usize) -> Option<SystemClauseType> {
|
pub fn from(name: &str, arity: usize) -> Option<SystemClauseType> {
|
||||||
match (name, arity) {
|
match (name, arity) {
|
||||||
("$install_cleaner", 1) =>
|
("$check_cp", 1) => Some(SystemClauseType::CheckCutPoint),
|
||||||
Some(SystemClauseType::InstallCleaner),
|
("$get_scc_cleaner", 1) => Some(SystemClauseType::GetSCCCleaner),
|
||||||
|
("$install_scc_cleaner", 1) =>
|
||||||
|
Some(SystemClauseType::InstallSCCCleaner),
|
||||||
("$install_inference_counter", 3) =>
|
("$install_inference_counter", 3) =>
|
||||||
Some(SystemClauseType::InstallInferenceCounter),
|
Some(SystemClauseType::InstallInferenceCounter),
|
||||||
("$remove_call_policy_check", 1) =>
|
("$remove_call_policy_check", 1) =>
|
||||||
@@ -1362,18 +1368,11 @@ pub enum ArithmeticInstruction {
|
|||||||
Neg(ArithmeticTerm, usize)
|
Neg(ArithmeticTerm, usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
// call and cut policy exempt instructions.
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub enum PEInstruction {
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum ControlInstruction {
|
pub enum ControlInstruction {
|
||||||
Allocate(usize), // num_frames.
|
Allocate(usize), // num_frames.
|
||||||
CallClause(ClauseType, usize, usize, bool), // name, arity, perm_vars after threshold, last call.
|
CallClause(ClauseType, usize, usize, bool), // name, arity, perm_vars after threshold, last call.
|
||||||
CheckCpExecute,
|
|
||||||
Deallocate,
|
Deallocate,
|
||||||
GetCleanerCall,
|
|
||||||
JmpBy(usize, usize, usize, bool), // arity, global_offset, perm_vars after threshold, last call.
|
JmpBy(usize, usize, usize, bool), // arity, global_offset, perm_vars after threshold, last call.
|
||||||
Proceed
|
Proceed
|
||||||
}
|
}
|
||||||
@@ -1382,7 +1381,6 @@ impl ControlInstruction {
|
|||||||
pub fn is_jump_instr(&self) -> bool {
|
pub fn is_jump_instr(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
&ControlInstruction::CallClause(..) => true,
|
&ControlInstruction::CallClause(..) => true,
|
||||||
&ControlInstruction::GetCleanerCall => true,
|
|
||||||
&ControlInstruction::JmpBy(..) => true,
|
&ControlInstruction::JmpBy(..) => true,
|
||||||
_ => false
|
_ => false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,12 +133,8 @@ impl fmt::Display for ControlInstruction {
|
|||||||
write!(f, "execute {}/{}, {}", ct, arity, pvs),
|
write!(f, "execute {}/{}, {}", ct, arity, pvs),
|
||||||
&ControlInstruction::CallClause(ref ct, arity, pvs, false) =>
|
&ControlInstruction::CallClause(ref ct, arity, pvs, false) =>
|
||||||
write!(f, "call {}/{}, {}", ct, arity, pvs),
|
write!(f, "call {}/{}, {}", ct, arity, pvs),
|
||||||
&ControlInstruction::CheckCpExecute =>
|
|
||||||
write!(f, "check_cp_execute"),
|
|
||||||
&ControlInstruction::Deallocate =>
|
&ControlInstruction::Deallocate =>
|
||||||
write!(f, "deallocate"),
|
write!(f, "deallocate"),
|
||||||
&ControlInstruction::GetCleanerCall =>
|
|
||||||
write!(f, "get_cleaner_call"),
|
|
||||||
&ControlInstruction::JmpBy(arity, offset, pvs, false) =>
|
&ControlInstruction::JmpBy(arity, offset, pvs, false) =>
|
||||||
write!(f, "jmp_by_call {}/{}, {}", offset, arity, pvs),
|
write!(f, "jmp_by_call {}/{}, {}", offset, arity, pvs),
|
||||||
&ControlInstruction::JmpBy(arity, offset, pvs, true) =>
|
&ControlInstruction::JmpBy(arity, offset, pvs, true) =>
|
||||||
|
|||||||
@@ -701,14 +701,14 @@ impl CutPolicy for DefaultCutPolicy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct SetupCallCleanupCutPolicy {
|
pub(crate) struct SCCCutPolicy {
|
||||||
// locations of cleaners, cut points, the previous block
|
// locations of cleaners, cut points, the previous block
|
||||||
cont_pts: Vec<(Addr, usize, usize)>
|
cont_pts: Vec<(Addr, usize, usize)>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SetupCallCleanupCutPolicy {
|
impl SCCCutPolicy {
|
||||||
pub(crate) fn new() -> Self {
|
pub(crate) fn new() -> Self {
|
||||||
SetupCallCleanupCutPolicy { cont_pts: vec![] }
|
SCCCutPolicy { cont_pts: vec![] }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn out_of_cont_pts(&self) -> bool {
|
pub(crate) fn out_of_cont_pts(&self) -> bool {
|
||||||
@@ -724,7 +724,7 @@ impl SetupCallCleanupCutPolicy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CutPolicy for SetupCallCleanupCutPolicy {
|
impl CutPolicy for SCCCutPolicy {
|
||||||
fn cut(&mut self, machine_st: &mut MachineState, r: RegType) {
|
fn cut(&mut self, machine_st: &mut MachineState, r: RegType) {
|
||||||
let b = machine_st.b;
|
let b = machine_st.b;
|
||||||
|
|
||||||
|
|||||||
@@ -1838,47 +1838,7 @@ impl MachineState {
|
|||||||
self.p += 1;
|
self.p += 1;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
&ControlInstruction::CheckCpExecute => {
|
|
||||||
let a = self.store(self.deref(self[temp_v!(2)].clone()));
|
|
||||||
|
|
||||||
match a {
|
|
||||||
Addr::Con(Constant::Usize(old_b)) if self.b > old_b + 1 => {
|
|
||||||
self.p = CodePtr::Local(self.cp.clone());
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
self.num_of_args = 2;
|
|
||||||
self.b0 = self.b;
|
|
||||||
// goto sgc_on_success/2, 382.
|
|
||||||
self.p = dir_entry!(382, clause_name!("builtin"));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
},
|
|
||||||
&ControlInstruction::Deallocate => self.deallocate(),
|
&ControlInstruction::Deallocate => self.deallocate(),
|
||||||
&ControlInstruction::GetCleanerCall => {
|
|
||||||
let dest = self[temp_v!(1)].clone();
|
|
||||||
|
|
||||||
match cut_policy.downcast_mut::<SetupCallCleanupCutPolicy>().ok() {
|
|
||||||
Some(sgc_policy) =>
|
|
||||||
if let Some((addr, b_cutoff, prev_block)) = sgc_policy.pop_cont_pt()
|
|
||||||
{
|
|
||||||
self.p += 1;
|
|
||||||
|
|
||||||
if self.b <= b_cutoff + 1 {
|
|
||||||
self.block = prev_block;
|
|
||||||
|
|
||||||
if let Some(r) = dest.as_var() {
|
|
||||||
self.bind(r, addr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sgc_policy.push_cont_pt(addr, b_cutoff, prev_block);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
None => panic!("expected SetupCallCleanupCutPolicy trait object.")
|
|
||||||
};
|
|
||||||
|
|
||||||
self.fail = true;
|
|
||||||
},
|
|
||||||
&ControlInstruction::JmpBy(arity, offset, _, lco) => {
|
&ControlInstruction::JmpBy(arity, offset, _, lco) => {
|
||||||
if !lco {
|
if !lco {
|
||||||
self.cp.assign_if_local(self.p.clone() + 1);
|
self.cp.assign_if_local(self.p.clone() + 1);
|
||||||
|
|||||||
@@ -157,20 +157,43 @@ impl MachineState {
|
|||||||
-> CallResult
|
-> CallResult
|
||||||
{
|
{
|
||||||
match ct {
|
match ct {
|
||||||
&SystemClauseType::InstallCleaner => {
|
&SystemClauseType::CheckCutPoint => {},
|
||||||
|
&SystemClauseType::GetSCCCleaner => {
|
||||||
|
let dest = self[temp_v!(1)].clone();
|
||||||
|
|
||||||
|
match cut_policy.downcast_mut::<SCCCutPolicy>().ok() {
|
||||||
|
Some(sgc_policy) =>
|
||||||
|
if let Some((addr, b_cutoff, prev_block)) = sgc_policy.pop_cont_pt() {
|
||||||
|
if self.b <= b_cutoff + 1 {
|
||||||
|
self.block = prev_block;
|
||||||
|
|
||||||
|
if let Some(r) = dest.as_var() {
|
||||||
|
self.bind(r, addr);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sgc_policy.push_cont_pt(addr, b_cutoff, prev_block);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => panic!("expected SCCCutPolicy trait object.")
|
||||||
|
};
|
||||||
|
|
||||||
|
self.fail = true;
|
||||||
|
},
|
||||||
|
&SystemClauseType::InstallSCCCleaner => {
|
||||||
let addr = self[temp_v!(1)].clone();
|
let addr = self[temp_v!(1)].clone();
|
||||||
let b = self.b;
|
let b = self.b;
|
||||||
let block = self.block;
|
let block = self.block;
|
||||||
|
|
||||||
if cut_policy.downcast_ref::<SetupCallCleanupCutPolicy>().is_err() {
|
if cut_policy.downcast_ref::<SCCCutPolicy>().is_err() {
|
||||||
*cut_policy = Box::new(SetupCallCleanupCutPolicy::new());
|
*cut_policy = Box::new(SCCCutPolicy::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
match cut_policy.downcast_mut::<SetupCallCleanupCutPolicy>().ok()
|
match cut_policy.downcast_mut::<SCCCutPolicy>().ok()
|
||||||
{
|
{
|
||||||
Some(cut_policy) => cut_policy.push_cont_pt(addr, b, block),
|
Some(cut_policy) => cut_policy.push_cont_pt(addr, b, block),
|
||||||
None => panic!("install_cleaner: should have installed \\
|
None => panic!("install_cleaner: should have installed \\
|
||||||
SetupCallCleanupCutPolicy.")
|
SCCCutPolicy.")
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
&SystemClauseType::InstallInferenceCounter => { // A1 = B, A2 = L
|
&SystemClauseType::InstallInferenceCounter => { // A1 = B, A2 = L
|
||||||
@@ -242,7 +265,7 @@ impl MachineState {
|
|||||||
},
|
},
|
||||||
&SystemClauseType::RestoreCutPolicy => {
|
&SystemClauseType::RestoreCutPolicy => {
|
||||||
let restore_default =
|
let restore_default =
|
||||||
if let Ok(cut_policy) = cut_policy.downcast_ref::<SetupCallCleanupCutPolicy>() {
|
if let Ok(cut_policy) = cut_policy.downcast_ref::<SCCCutPolicy>() {
|
||||||
cut_policy.out_of_cont_pts()
|
cut_policy.out_of_cont_pts()
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
|||||||
Reference in New Issue
Block a user