]> Repositorios git - scryer-prolog.git/commitdiff
ensure pdl is pushed/popped in pairs
authorSkgland <[email protected]>
Sun, 17 May 2026 17:45:55 +0000 (19:45 +0200)
committerSkgland <[email protected]>
Sun, 17 May 2026 17:48:52 +0000 (19:48 +0200)
src/machine/machine_state.rs
src/machine/unify.rs
src/macros.rs

index 3744da340a66197e5f4a3730c77be8eb9e30d727..860cfb79ae4cf2440de17ceb756bd37796cc4855 100644 (file)
@@ -115,7 +115,7 @@ impl OccursCheckImpl for StoError {
 pub struct MachineState {
     pub atom_tbl: Arc<AtomTable>,
     pub arena: Arena,
-    pub(super) pdl: Vec<HeapCellValue>,
+    pub(super) pdl: Vec<(HeapCellValue, HeapCellValue)>,
     pub(super) s: HeapPtr,
     pub(super) s_offset: usize,
     pub(super) p: usize,
index e1f73eaee25ff61978eb95520368e4eb232abc68..0957537c97eff9628e2614d171b85158b1f026b3 100644 (file)
@@ -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<Target = MachineState> {
 
                 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<Target = MachineState> {
             (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<Target = MachineState> {
         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<Target = MachineState> {
 
                 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<Target = MachineState> {
             (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<Target = MachineState> {
     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 {
index 3d88e437eab6bbd4741834b766bd475e0d02e791..d99f58f7682e7e3234c9516b09e014d0a51db195 100644 (file)
@@ -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()
     }};
 }