From: Skgland Date: Sun, 17 May 2026 17:45:55 +0000 (+0200) Subject: ensure pdl is pushed/popped in pairs X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=d50d42509903dc3cc1841eb757a703753de84754;p=scryer-prolog.git ensure pdl is pushed/popped in pairs --- diff --git a/src/machine/machine_state.rs b/src/machine/machine_state.rs index 3744da34..860cfb79 100644 --- a/src/machine/machine_state.rs +++ b/src/machine/machine_state.rs @@ -115,7 +115,7 @@ impl OccursCheckImpl for StoError { pub struct MachineState { pub atom_tbl: Arc, pub arena: Arena, - pub(super) pdl: Vec, + pub(super) pdl: Vec<(HeapCellValue, HeapCellValue)>, pub(super) s: HeapPtr, pub(super) s_offset: usize, pub(super) p: usize, diff --git a/src/machine/unify.rs b/src/machine/unify.rs index e1f73eae..0957537c 100644 --- a/src/machine/unify.rs +++ b/src/machine/unify.rs @@ -17,11 +17,9 @@ impl MachineState { pub(crate) fn partial_string_to_pdl(&mut self, pstr_loc: usize, l: usize) { let (c, succ_cell) = self.heap.last_str_char_and_tail(pstr_loc); - self.pdl.push(heap_loc_as_cell!(l + 1)); - self.pdl.push(succ_cell); + self.pdl.push((heap_loc_as_cell!(l + 1), succ_cell)); - self.pdl.push(heap_loc_as_cell!(l)); - self.pdl.push(char_as_cell!(c)); + self.pdl.push((heap_loc_as_cell!(l), char_as_cell!(c))); } } @@ -37,8 +35,7 @@ pub(crate) trait Unifier: DerefMut { if n1 == n2 && a1 == a2 { for idx in (0..a1).rev() { - self.pdl.push(heap_loc_as_cell!(s2+1+idx)); - self.pdl.push(heap_loc_as_cell!(s1+1+idx)); + self.pdl.push((heap_loc_as_cell!(s2+1+idx), heap_loc_as_cell!(s1+1+idx))); } } else { self.fail = true; @@ -47,8 +44,7 @@ pub(crate) trait Unifier: DerefMut { (HeapCellValueTag::Lis, l2) => { if a1 == 2 && n1 == atom!(".") { for idx in (0..2).rev() { - self.pdl.push(heap_loc_as_cell!(l2+1+idx)); - self.pdl.push(heap_loc_as_cell!(s1+1+idx)); + self.pdl.push((heap_loc_as_cell!(l2+1+idx), heap_loc_as_cell!(s1+1+idx))); } } else { self.fail = true; @@ -76,8 +72,7 @@ pub(crate) trait Unifier: DerefMut { read_heap_cell!(value, (HeapCellValueTag::Lis, l2) => { for idx in (0..2).rev() { - self.pdl.push(heap_loc_as_cell!(l2 + idx)); - self.pdl.push(heap_loc_as_cell!(l1 + idx)); + self.pdl.push((heap_loc_as_cell!(l2 + idx), heap_loc_as_cell!(l1 + idx))); } } (HeapCellValueTag::Str, s2) => { @@ -86,8 +81,7 @@ pub(crate) trait Unifier: DerefMut { if a2 == 2 && n2 == atom!(".") { for idx in (0..2).rev() { - self.pdl.push(heap_loc_as_cell!(s2+1+idx)); - self.pdl.push(heap_loc_as_cell!(l1+idx)); + self.pdl.push((heap_loc_as_cell!(s2+1+idx), heap_loc_as_cell!(l1+idx))); } } else { self.fail = true; @@ -136,8 +130,7 @@ pub(crate) trait Unifier: DerefMut { (HeapCellValueTag::PStrLoc, other_pstr_loc) => { match machine_st.heap.compare_pstr_segments(pstr_loc, other_pstr_loc) { PStrSegmentCmpResult::Continue(v1, v2) => { - machine_st.pdl.push(v1.offset_by(pstr_loc)); - machine_st.pdl.push(v2.offset_by(other_pstr_loc)); + machine_st.pdl.push((v1.offset_by(pstr_loc), v2.offset_by(other_pstr_loc))); } _ => { machine_st.fail = true; @@ -357,11 +350,13 @@ pub(crate) trait Unifier: DerefMut { fn unify_internal(&mut self) { let mut tabu_list = IndexSet::with_hasher(FxBuildHasher::default()); - while !(self.pdl.is_empty() || self.fail) { - let s1 = self.pdl.pop().unwrap(); - let s1 = (self.deref() as &MachineState).deref(s1); + while let Some((s1, s2)) = self.pdl.pop() { + if self.fail { + // FIXME(msrv) FIXME(edition2024) use let chain to move this to check this in the while condition + break; + } - let s2 = self.pdl.pop().unwrap(); + let s1 = (self.deref() as &MachineState).deref(s1); let s2 = (self.deref() as &MachineState).deref(s2); if s1 != s2 { diff --git a/src/macros.rs b/src/macros.rs index 3d88e437..d99f58f7 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -406,22 +406,22 @@ macro_rules! index_store { } macro_rules! unify { - ($machine_st:expr, $($value:expr),*) => {{ - $($machine_st.pdl.push($value);)* + ($machine_st:expr, $($v1:expr, $v2:expr),*) => {{ + $($machine_st.pdl.push(($v1, $v2));)* $machine_st.unify() }}; } macro_rules! unify_fn { - ($machine_st:expr, $($value:expr),*) => {{ - $($machine_st.pdl.push($value);)* + ($machine_st:expr, $($v1:expr, $v2: expr),*) => {{ + $($machine_st.pdl.push(($v1, $v2));)* $machine_st.occurs_check.unify(&mut $machine_st) }}; } macro_rules! unify_with_occurs_check { - ($machine_st:expr, $($value:expr),*) => {{ - $($machine_st.pdl.push($value);)* + ($machine_st:expr, $($v1:expr, $v2:expr),*) => {{ + $($machine_st.pdl.push(($v1, $v2));)* $machine_st.unify_with_occurs_check() }}; }