From: Mark Thom Date: Mon, 2 Dec 2019 21:06:12 +0000 (-0400) Subject: correct copying of cyclic lists in copier.rs X-Git-Tag: v0.8.118~36^2~6^2~1 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=fc8e55c582a3be6c929356a20b035ef1cbb10c12;p=scryer-prolog.git correct copying of cyclic lists in copier.rs --- diff --git a/src/prolog/machine/copier.rs b/src/prolog/machine/copier.rs index 34c1bfe6..51a56dd2 100644 --- a/src/prolog/machine/copier.rs +++ b/src/prolog/machine/copier.rs @@ -51,13 +51,16 @@ impl CopyTermState { } fn copied_list(&mut self, addr: usize) -> bool { - if let HeapCellValue::Addr(Addr::Lis(addr)) = self.target[addr].clone() { - if addr >= self.old_h { - *self.value_at_scan() = HeapCellValue::Addr(Addr::Lis(addr)); - self.scan += 1; - return true; + match self.target[addr].clone() { + HeapCellValue::Addr(Addr::Lis(addr)) | HeapCellValue::Addr(Addr::HeapCell(addr)) => { + if addr >= self.old_h { + *self.value_at_scan() = HeapCellValue::Addr(Addr::Lis(addr)); + self.scan += 1; + return true; + } } - } + _ => {} + }; false } @@ -71,13 +74,31 @@ impl CopyTermState { *self.value_at_scan() = HeapCellValue::Addr(Addr::Lis(threshold)); let hcv = self.target[addr].clone(); - self.target.push(hcv); + let ra = hcv.as_addr(threshold); + let rd = self.target.store(self.target.deref(ra)); + + self.target.push(hcv); + let hcv = self.target[addr + 1].clone(); self.target.push(hcv); - self.trail.push((Ref::HeapCell(addr), self.target[addr].clone())); - self.target[addr] = HeapCellValue::Addr(Addr::Lis(threshold)); + match rd.clone() { + Addr::AttrVar(h) | Addr::HeapCell(h) if h >= self.old_h => { + self.target[threshold] = HeapCellValue::Addr(rd) + } + ra @ Addr::AttrVar(_) | ra @ Addr::HeapCell(..) | ra @ Addr::StackCell(..) => { + if ra == rd { + self.reinstantiate_var(ra, threshold); + } else { + self.target[threshold] = HeapCellValue::Addr(ra); + } + } + _ => { + self.trail.push((Ref::HeapCell(addr), self.target[addr].clone())); + self.target[addr] = HeapCellValue::Addr(Addr::Lis(threshold)) + } + }; self.scan += 1; }