From ca5138ccea04e55662ae20ef422e61b910c320f5 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Sun, 24 Mar 2019 09:55:20 -0600 Subject: [PATCH] fix toplevel heap view --- Cargo.toml | 2 +- src/prolog/machine/mod.rs | 34 ++++++++++++++++++++++------------ src/prolog/write.rs | 34 +++++++++++++++------------------- src/tests.rs | 8 ++++---- 4 files changed, 42 insertions(+), 36 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index bee4e8c4..3e537a6b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "scryer-prolog" -version = "0.8.15" +version = "0.8.16" authors = ["Mark Thom "] repository = "https://github.com/mthom/scryer-prolog" description = "A modern Prolog implementation written mostly in Rust." diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index 01e8527e..ccdb2623 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -249,17 +249,7 @@ impl Machine { Ok(()) } - - pub fn remove_unbound_vars(&self, orig_heap_locs: &HeapVarDict, heap_locs: &mut HeapVarDict) { - for (var, addr) in orig_heap_locs.iter() { - match self.machine_st.store(self.machine_st.deref(addr.clone())) { - new_addr => if new_addr.is_ref() { - heap_locs.remove(var); - } - } - } - } - + pub fn add_batched_code(&mut self, code: Code, code_dir: CodeDir) { // error detection has finished, so update the master index of keys. @@ -422,7 +412,27 @@ impl Machine { } } - pub fn heap_view(&self, var_dir: &HeapVarDict, mut output: Outputter) -> Outputter + pub fn toplevel_heap_view(&self, var_dir: &HeapVarDict, mut output: Outputter) -> Outputter + where Outputter: HCValueOutputter + { + let mut sorted_vars: Vec<(&Rc, &Addr)> = var_dir.iter().collect(); + sorted_vars.sort_by_key(|ref v| v.0); + + for (var, addr) in sorted_vars { + let addr = self.machine_st.store(self.machine_st.deref(addr.clone())); + + if addr.is_ref() { + continue; + } + + output = self.machine_st.print_var_eq(var.clone(), addr, var_dir, output); + } + + output + } + + #[cfg(test)] + pub fn test_heap_view(&self, var_dir: &HeapVarDict, mut output: Outputter) -> Outputter where Outputter: HCValueOutputter { let mut sorted_vars: Vec<(&Rc, &Addr)> = var_dir.iter().collect(); diff --git a/src/prolog/write.rs b/src/prolog/write.rs index c7da956e..721394d9 100644 --- a/src/prolog/write.rs +++ b/src/prolog/write.rs @@ -371,15 +371,11 @@ fn next_step(mut stdout: RawTerminal) -> ContinueResult pub fn print(wam: &mut Machine, result: EvalSession) { match result { - EvalSession::InitialQuerySuccess(alloc_locs, mut heap_locs) => { - let orig_heap_locs = heap_locs.clone(); - + EvalSession::InitialQuerySuccess(alloc_locs, mut heap_locs) => loop { - wam.remove_unbound_vars(&orig_heap_locs, &mut heap_locs); - if wam.or_stack_is_empty() { if heap_locs.is_empty() { - let attr_goals = wam.attribute_goals(&orig_heap_locs); + let attr_goals = wam.attribute_goals(&heap_locs); if !attr_goals.is_empty() { println!("{}.", attr_goals); @@ -389,29 +385,30 @@ pub fn print(wam: &mut Machine, result: EvalSession) { return; } - } else if heap_locs.is_empty() && orig_heap_locs.is_empty() { + } else if heap_locs.is_empty() { print!("true"); stdout().flush().unwrap(); } let mut raw_stdout = stdout().into_raw_mode().unwrap(); - if !heap_locs.is_empty() { + let bindings = if !heap_locs.is_empty() { let mut output = PrinterOutputter::new(); - let bindings = wam.heap_view(&heap_locs, output).result(); - - write!(raw_stdout, "{}", bindings).unwrap(); - raw_stdout.flush().unwrap(); - } + wam.toplevel_heap_view(&heap_locs, output).result() + } else { + "".to_string() + }; - let attr_goals = wam.attribute_goals(&orig_heap_locs); + let attr_goals = wam.attribute_goals(&heap_locs); if !attr_goals.is_empty() { - if heap_locs.is_empty() { + if bindings.is_empty() { write!(raw_stdout, "{}", attr_goals).unwrap(); } else { - write!(raw_stdout, ", {}", attr_goals).unwrap(); + write!(raw_stdout, "{}, {}", bindings, attr_goals).unwrap(); } + } else { + write!(raw_stdout, "{}", bindings).unwrap(); } if !wam.or_stack_is_empty() { @@ -440,7 +437,7 @@ pub fn print(wam: &mut Machine, result: EvalSession) { return; } } else { - if heap_locs.is_empty() && attr_goals.is_empty() { + if bindings.is_empty() && attr_goals.is_empty() { write!(raw_stdout, "true.\r\n").unwrap(); } else { write!(raw_stdout, ".\r\n").unwrap(); @@ -448,8 +445,7 @@ pub fn print(wam: &mut Machine, result: EvalSession) { break; } - } - }, + }, EvalSession::Error(e) => println!("{}", e), _ => {} }; diff --git a/src/tests.rs b/src/tests.rs index 1804324f..c499f091 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -86,12 +86,12 @@ pub fn collect_test_output(wam: &mut Machine, alloc_locs: AllocVarDict, mut heap { let mut output = TestOutputter::new(); - output = wam.heap_view(&heap_locs, output); + output = wam.test_heap_view(&heap_locs, output); output.cache(); while let EvalSession::SubsequentQuerySuccess = wam.continue_query(&alloc_locs, &mut heap_locs) { - output = wam.heap_view(&heap_locs, output); + output = wam.test_heap_view(&heap_locs, output); output.cache(); } @@ -104,7 +104,7 @@ pub fn collect_test_output_with_limit(wam: &mut Machine, alloc_locs: AllocVarDic { let mut output = TestOutputter::new(); - output = wam.heap_view(&heap_locs, output); + output = wam.test_heap_view(&heap_locs, output); output.cache(); let mut count = 1; @@ -115,7 +115,7 @@ pub fn collect_test_output_with_limit(wam: &mut Machine, alloc_locs: AllocVarDic while let EvalSession::SubsequentQuerySuccess = wam.continue_query(&alloc_locs, &mut heap_locs) { - output = wam.heap_view(&heap_locs, output); + output = wam.test_heap_view(&heap_locs, output); output.cache(); count += 1; -- 2.54.0