From 61fe42a2add243721558532902bc383993122c03 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Sun, 16 Sep 2018 01:37:42 -0600 Subject: [PATCH] fix copier --- Cargo.lock | 8 ++-- src/prolog/copier.rs | 70 +++++++++++++++++++++-------- src/prolog/machine/machine_state.rs | 27 +++++++++-- src/tests.rs | 6 ++- 4 files changed, 85 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5829a529..0e312715 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -86,7 +86,8 @@ dependencies = [ [[package]] name = "prolog_parser" -version = "0.7.12" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -107,12 +108,12 @@ dependencies = [ [[package]] name = "rusty-wam" -version = "0.7.11" +version = "0.7.12" dependencies = [ "downcast 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "prolog_parser 0.7.12", + "prolog_parser 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)", "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -151,6 +152,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070" "checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe" "checksum ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "58d25b6c0e47b20d05226d288ff434940296e7e2f8b877975da32f862152241f" +"checksum prolog_parser 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e6180d11b22e5ad469413211521123d4e83597ee8af0d047c31b5fdc59226e56" "checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" diff --git a/src/prolog/copier.rs b/src/prolog/copier.rs index ffb689a3..7d15cb5d 100644 --- a/src/prolog/copier.rs +++ b/src/prolog/copier.rs @@ -3,12 +3,20 @@ use prolog::instructions::*; use std::ops::IndexMut; +//type ListTrail = HashMap; type Trail = Vec<(Ref, HeapCellValue)>; pub(crate) struct RedirectInfo { + //list_trail: ListTrail, trail: Trail } - +/* +impl RedirectInfo { + fn new() -> Self { + RedirectInfo { list_trail: ListTrail::new(), trail: Trail::new() } + } +} +*/ pub(crate) trait CopierTarget { fn source(&self) -> usize; @@ -29,12 +37,29 @@ pub(crate) trait CopierTarget } } + fn reinstantiate_var(&mut self, ra: Addr, scan: usize, trail: &mut Trail) + where Self: IndexMut + { + self[scan] = HeapCellValue::Addr(Addr::HeapCell(scan)); + + if let Addr::HeapCell(hc) = ra.clone() { + self[hc] = HeapCellValue::Addr(Addr::HeapCell(scan)); + trail.push((Ref::HeapCell(hc), + HeapCellValue::Addr(Addr::HeapCell(hc)))); + } else if let Addr::StackCell(fr, sc) = ra { + self.stack()[fr][sc] = Addr::HeapCell(scan); + trail.push((Ref::StackCell(fr, sc), + HeapCellValue::Addr(Addr::StackCell(fr, sc)))); + } + } + // duplicate_term_impl(L1, L2) uses Cheney's algorithm to copy the term // at L1 to L2. trail is kept to restore the innards of L1 after // it's been copied to L2. fn duplicate_term_impl(&mut self, addr: Addr) -> RedirectInfo where Self: IndexMut { + // let mut redirect_info = RedirectInfo::new(); let mut trail = Trail::new(); let mut scan = self.source(); let old_h = self.threshold(); @@ -58,16 +83,36 @@ pub(crate) trait CopierTarget let threshold = self.threshold(); self[scan] = HeapCellValue::Addr(Addr::Lis(threshold)); - + let hcv = self[a].clone(); - self.push(hcv); + self.push(hcv.clone()); + + let ra = hcv.as_addr(threshold); + let rd = self.store(self.deref(ra)); + + match rd.clone() { + Addr::HeapCell(hc) if hc >= old_h => { + self[threshold] = HeapCellValue::Addr(rd); + scan += 1; + }, + addr @ Addr::HeapCell(..) | addr @ Addr::StackCell(..) => { + if rd == addr { + self.reinstantiate_var(addr, threshold, &mut trail); + } else { + self[threshold] = HeapCellValue::Addr(addr); + } + + scan += 1; + }, + _ => { + trail.push((Ref::HeapCell(a), self[a].clone())); + self[a] = HeapCellValue::Addr(Addr::Lis(threshold)) + } + }; let hcv = self[a+1].clone(); self.push(hcv); - trail.push((Ref::HeapCell(a), self[a].clone())); - self[a] = HeapCellValue::Addr(Addr::Lis(threshold)); - scan += 1; }, Addr::HeapCell(_) | Addr::StackCell(_, _) => { @@ -80,18 +125,7 @@ pub(crate) trait CopierTarget scan += 1; }, _ if ra == rd => { - self[scan] = HeapCellValue::Addr(Addr::HeapCell(scan)); - - if let Addr::HeapCell(hc) = ra.clone() { - self[hc] = HeapCellValue::Addr(Addr::HeapCell(scan)); - trail.push((Ref::HeapCell(hc), - HeapCellValue::Addr(Addr::HeapCell(hc)))); - } else if let Addr::StackCell(fr, sc) = ra { - self.stack()[fr][sc] = Addr::HeapCell(scan); - trail.push((Ref::StackCell(fr, sc), - HeapCellValue::Addr(Addr::StackCell(fr, sc)))); - } - + self.reinstantiate_var(ra, scan, &mut trail); scan += 1; }, _ => self[scan] = HeapCellValue::Addr(rd) diff --git a/src/prolog/machine/machine_state.rs b/src/prolog/machine/machine_state.rs index c48748b8..83eff7f2 100644 --- a/src/prolog/machine/machine_state.rs +++ b/src/prolog/machine/machine_state.rs @@ -168,12 +168,31 @@ impl<'a> CopierTarget for DuplicateBallTerm<'a> { self.state.ball.stub.push(hcv); } - fn store(&self, a: Addr) -> Addr { - self.state.store(a) + fn store(&self, addr: Addr) -> Addr { + match addr { + Addr::HeapCell(hc) if hc < self.heap_boundary => + self.state.heap[hc].as_addr(hc), + Addr::HeapCell(hc) => { + let index = hc - self.heap_boundary; + self.state.ball.stub[index].as_addr(hc) + }, + Addr::StackCell(fr, sc) => + self.state.and_stack[fr][sc].clone(), + addr => addr + } } - fn deref(&self, a: Addr) -> Addr { - self.state.deref(a) + fn deref(&self, mut addr: Addr) -> Addr { + loop { + let value = self.store(addr.clone()); + + if value.is_ref() && value != addr { + addr = value; + continue; + } + + return addr; + }; } fn stack(&mut self) -> &mut AndStack { diff --git a/src/tests.rs b/src/tests.rs index 34e2c284..01ba96ec 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1491,7 +1491,11 @@ fn test_queries_on_builtins() [["Y = f(g(X, Y))", "X = g(X, f(X))", "Z = g(Z, f(Z))"]]); assert_prolog_success!(&mut wam, "?- X = g(X, Y), Y = f(X), duplicate_term(Y, V).", [["Y = f(g(X, Y))", "X = g(X, f(X))", "V = f(g(_9, V))"]]); - + assert_prolog_success!(&mut wam, "?- f(Y,Y,[X,a,[],Y]) = Term, duplicate_term(Term, NewTerm).", + [["NewTerm = f(_16, _16, [_19, a, [], _16])", + "Term = f(_0, Y, [_6, a, [], Y])", + "X = _6", "Y = _0"]]); + assert_prolog_success!(&mut wam, "?- float(3.14159269)."); assert_prolog_failure!(&mut wam, "?- float(3)."); assert_prolog_failure!(&mut wam, "?- float(\"sdfsa\")."); -- 2.54.0