From: Mark Thom Date: Sun, 5 Apr 2020 00:44:16 +0000 (-0600) Subject: use copy_term/3 to print residual goals (#254) X-Git-Tag: v0.8.119~28 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=bbf1aa16685b5df187c322db48b8e29780182d89;p=scryer-prolog.git use copy_term/3 to print residual goals (#254) --- diff --git a/src/prolog/machine/copier.rs b/src/prolog/machine/copier.rs index 10b67d4e..baa1f2b9 100644 --- a/src/prolog/machine/copier.rs +++ b/src/prolog/machine/copier.rs @@ -53,13 +53,27 @@ impl CopyTermState { &mut self.target[scan] } + fn trail_list_cell(&mut self, addr: usize, threshold: usize) { + let trail_item = mem::replace( + &mut self.target[addr], + HeapCellValue::Addr(Addr::Lis(threshold)), + ); + + self.trail.push(( + Ref::HeapCell(addr), + trail_item, + )); + } + fn copy_list(&mut self, addr: usize) { - if let Addr::Lis(h) = self.target[addr + 1].as_addr(addr + 1) { - if h >= self.old_h { - *self.value_at_scan() = HeapCellValue::Addr(Addr::Lis(h)); - self.scan += 1; + for offset in 0 .. 2 { + if let Addr::Lis(h) = self.target[addr + offset].as_addr(addr + offset) { + if h >= self.old_h { + *self.value_at_scan() = HeapCellValue::Addr(Addr::Lis(h)); + self.scan += 1; - return; + return; + } } } @@ -74,15 +88,14 @@ impl CopyTermState { let cdr = self.target.store(self.target.deref(Addr::HeapCell(addr + 1))); - if let Addr::Lis(_) = cdr { - let tail_addr = self.target[addr + 1].as_addr(addr + 1); - - self.trail.push(( - Ref::HeapCell(addr + 1), - HeapCellValue::Addr(tail_addr), - )); + if !cdr.is_ref() { + self.trail_list_cell(addr + 1, threshold); + } else { + let car = self.target.store(self.target.deref(Addr::HeapCell(addr))); - self.target[addr + 1] = HeapCellValue::Addr(Addr::Lis(threshold)); + if !car.is_ref() { + self.trail_list_cell(addr, threshold); + } } self.scan += 1; @@ -163,7 +176,7 @@ impl CopyTermState { }; self.target[frontier] = HeapCellValue::Addr(Addr::HeapCell(threshold)); - self.target[h] = HeapCellValue::Addr(Addr::HeapCell(frontier)); + self.target[h] = HeapCellValue::Addr(Addr::HeapCell(threshold)); self.trail.push(( Ref::AttrVar(h), @@ -271,6 +284,9 @@ impl CopyTermState { *self.value_at_scan() = HeapCellValue::Addr(addr); } } + Addr::Lis(h) if h >= self.old_h => { + self.scan += 1; + } Addr::Lis(h) => { self.copy_list(h); }