From: Mark Thom Date: Sun, 5 May 2019 04:58:56 +0000 (-0400) Subject: add variable_names as a write option X-Git-Tag: v0.8.110~69 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=bf8a2ab6a6f96c3bb6e69a7ec309008f3c412dfa;p=scryer-prolog.git add variable_names as a write option --- diff --git a/src/prolog/clause_types.rs b/src/prolog/clause_types.rs index f5c504df..5a5c67b2 100644 --- a/src/prolog/clause_types.rs +++ b/src/prolog/clause_types.rs @@ -410,7 +410,7 @@ impl SystemClauseType { ("$unwind_stack", 0) => Some(SystemClauseType::UnwindStack), ("$unify_with_occurs_check", 2) => Some(SystemClauseType::UnifyWithOccursCheck), ("$variant", 2) => Some(SystemClauseType::Variant), - ("$write_term", 4) => Some(SystemClauseType::WriteTerm), + ("$write_term", 5) => Some(SystemClauseType::WriteTerm), _ => None } } diff --git a/src/prolog/heap_print.rs b/src/prolog/heap_print.rs index 286631e6..0f1229a6 100644 --- a/src/prolog/heap_print.rs +++ b/src/prolog/heap_print.rs @@ -290,15 +290,16 @@ impl MachineState { type ReverseHeapVarDict = HashMap>; pub struct HCPrinter<'a, Outputter> { - outputter: Outputter, - machine_st: &'a MachineState, + outputter: Outputter, + machine_st: &'a MachineState, op_dir: &'a OpDir, - state_stack: Vec, + state_stack: Vec, toplevel_spec: Option, - heap_locs: ReverseHeapVarDict, + heap_locs: ReverseHeapVarDict, printed_vars: HashSet, last_item_idx: usize, cyclic_terms: HashMap, + pub(crate) var_names: HashMap, pub(crate) numbervars_offset: BigInt, pub(crate) numbervars: bool, pub(crate) quoted: bool, @@ -341,10 +342,9 @@ pub fn requires_space(atom: &str, op: &str) -> bool { } } -fn reverse_heap_locs<'a>(machine_st: &'a MachineState, heap_locs: &'a HeapVarDict) - -> ReverseHeapVarDict +fn reverse_heap_locs<'a>(machine_st: &'a MachineState) -> ReverseHeapVarDict { - heap_locs.iter().map(|(var, var_addr)| { + machine_st.heap_locs.iter().map(|(var, var_addr)| { (machine_st.store(machine_st.deref(var_addr.clone())), var.clone()) }).collect() } @@ -414,17 +414,17 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> numbervars_offset: BigInt::zero(), quoted: false, ignore_ops: false, - cyclic_terms: HashMap::new() } + cyclic_terms: HashMap::new(), + var_names: HashMap::new() } } - pub fn from_heap_locs(machine_st: &'a MachineState, op_dir: &'a OpDir, output: Outputter, - heap_locs: &'a HeapVarDict) + pub fn from_heap_locs(machine_st: &'a MachineState, op_dir: &'a OpDir, output: Outputter) -> Self { let mut printer = Self::new(machine_st, op_dir, output); printer.toplevel_spec = Some(DirectedOp::Right(clause_name!("="), SharedOpDesc::new(700, XFX))); - printer.heap_locs = reverse_heap_locs(machine_st, heap_locs); + printer.heap_locs = reverse_heap_locs(machine_st); printer } @@ -577,8 +577,18 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> self.last_item_idx = self.outputter.len(); self.outputter.append(s); } + + fn offset_as_string(&self, iter: &mut HCPreOrderIterator, addr: Addr) -> Option + { + if let Some(var) = self.var_names.get(&addr) { + if addr.as_var().is_some() { + return Some(format!("{}", var)); + } else { + iter.stack().push(addr); + return None; + } + } - fn offset_as_string(&self, addr: Addr) -> Option { match addr { Addr::AttrVar(h) => Some(format!("_{}", h + 1)), @@ -894,7 +904,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> self.push_list(); }, HeapCellValue::Addr(addr) => - if let Some(offset_str) = self.offset_as_string(addr) { + if let Some(offset_str) = self.offset_as_string(iter, addr) { push_space_if_amb!(self, &offset_str, { self.append_str(offset_str.as_str()); }) diff --git a/src/prolog/lib/builtins.pl b/src/prolog/lib/builtins.pl index f1f986bf..d573e3ea 100644 --- a/src/prolog/lib/builtins.pl +++ b/src/prolog/lib/builtins.pl @@ -220,22 +220,41 @@ is_write_option(Functor) :- Functor =.. [Name, Arg], ( Arg == true -> true ; Arg == false -> true + ; Name == variable_names -> must_be_var_names_list(Arg) ; var(Arg) -> throw(error(instantiation_error, write_term/2)) ; throw(error(domain_error(write_option, Functor), write_term/2)) ), % 8.14.2.3 e) ( Name == ignore_ops -> true ; Name == quoted -> true ; Name == numbervars -> true + ; Name == variable_names -> true ; throw(error(domain_error(write_option, Functor), write_term/2)) ). % 8.14.2.3 e) -inst_member_or([X|Xs], Y, _) :- +inst_member_or([X|Xs], Y, Z) :- ( var(X) -> throw(error(instantiation_error, write_term/2)) - ; is_write_option(X) -> ( Y = X, ! ; inst_member_or(Xs, Y, _) ) + ; is_write_option(X) -> ( Y = X, ! ; inst_member_or(Xs, Y, Z) ) ; throw(error(domain_error(write_option, X), write_term/2)) ). inst_member_or([], Y, Y). +must_be_var_names_list(VarNames) :- + '$skip_max_list'(_, -1, VarNames, Tail), + ( Tail == [] -> must_be_var_names_list_(VarNames) + ; var(Tail) -> throw(error(instantiation_error, write_term/2)) + ; throw(error(domain_error(write_options, variable_names(VarNames)), write_term/2)) + ). + +must_be_var_names_list_([]). +must_be_var_names_list_([VarName | VarNames]) :- + ( nonvar(VarName), VarName = (Atom = _) -> + ( atom(Atom) -> must_be_var_names_list_(VarNames) + ; var(Atom) -> throw(error(instantiation_error, write_term/2)) + ; throw(error(domain_error(write_options, variable_names(VarName)), write_term/2)) + ) + ; throw(error(instantiation_error, write_term/2)) + ). + write_term(_, Options) :- var(Options), throw(error(instantiation_error, write_term/2)). write_term(Term, Options) :- @@ -247,7 +266,8 @@ write_term(Term, Options) :- inst_member_or(Options, ignore_ops(IgnoreOps), ignore_ops(false)), inst_member_or(Options, numbervars(NumberVars), numbervars(false)), inst_member_or(Options, quoted(Quoted), quoted(false)), - '$write_term'(Term, IgnoreOps, NumberVars, Quoted). + inst_member_or(Options, variable_names(VarNames), variable_names([])), + '$write_term'(Term, IgnoreOps, NumberVars, Quoted, VarNames). write(Term) :- write_term(Term, [numbervars(true)]). @@ -605,8 +625,8 @@ module_abolish(Pred, Module) :- ( var(Name) -> throw(error(instantiation_error, abolish/1)) ; integer(Arity) -> ( \+ atom(Name) -> throw(error(type_error(atom, Name), abolish/1)) - ; Arity < 0 -> throw(domain_error(not_less_than_zero, Arity), abolish/1) - ; max_arity(N), Arity > N -> throw(representation_error(max_arity), abolish/1) + ; Arity < 0 -> throw(error(domain_error(not_less_than_zero, Arity), abolish/1)) + ; max_arity(N), Arity > N -> throw(error(representation_error(max_arity), abolish/1)) ; functor(Head, Name, Arity) -> ( '$module_head_is_dynamic'(Head, Module) -> '$abolish_module_clause'(Name, Arity, Module) @@ -626,8 +646,8 @@ abolish(Pred) :- ; var(Arity) -> throw(error(instantiation_error, abolish/1)) ; integer(Arity) -> ( \+ atom(Name) -> throw(error(type_error(atom, Name), abolish/1)) - ; Arity < 0 -> throw(domain_error(not_less_than_zero, Arity), abolish/1) - ; max_arity(N), Arity > N -> throw(representation_error(max_arity), abolish/1) + ; Arity < 0 -> throw(error(domain_error(not_less_than_zero, Arity), abolish/1)) + ; max_arity(N), Arity > N -> throw(error(representation_error(max_arity), abolish/1)) ; functor(Head, Name, Arity) -> ( '$no_such_predicate'(Head) -> true ; '$head_is_dynamic'(Head) -> '$abolish_clause'(Name, Arity) diff --git a/src/prolog/machine/attributed_variables.rs b/src/prolog/machine/attributed_variables.rs index ba21dd43..600d2173 100644 --- a/src/prolog/machine/attributed_variables.rs +++ b/src/prolog/machine/attributed_variables.rs @@ -85,12 +85,12 @@ impl MachineState { attr_vars.into_iter() } - fn populate_project_attr_lists(&mut self, var_dict: &HeapVarDict) -> (Addr, Addr) + fn populate_project_attr_lists(&mut self) -> (Addr, Addr) { let mut query_vars = HashSet::new(); let attr_vars = self.gather_attr_vars_created_since(0); - for (_, addr) in var_dict { + for (_, addr) in self.heap_locs.iter() { let iter = self.acyclic_pre_order_iter(addr.clone()); for value in iter { @@ -140,7 +140,7 @@ impl MachineState { self.p = CodePtr::Local(LocalCodePtr::DirEntry(p)); } - fn print_attribute_goals_string(&mut self, op_dir: &OpDir, var_dict: &HeapVarDict) -> String + fn print_attribute_goals_string(&mut self, op_dir: &OpDir) -> String { let mut attr_goals = mem::replace(&mut self.attr_var_init.attribute_goals, vec![]); @@ -154,7 +154,7 @@ impl MachineState { let mut output = PrinterOutputter::new(); for goal_addr in attr_goals { - let mut printer = HCPrinter::from_heap_locs(&self, op_dir, output, var_dict); + let mut printer = HCPrinter::from_heap_locs(&self, op_dir, output); printer.see_all_locs(); printer.numbervars = false; @@ -174,10 +174,10 @@ impl MachineState { impl Machine { pub - fn attribute_goals(&mut self, var_dict: &HeapVarDict) -> String + fn attribute_goals(&mut self) -> String { let p = self.machine_st.attr_var_init.project_attrs_loc; - let (query_vars, attr_vars) = self.machine_st.populate_project_attr_lists(var_dict); + let (query_vars, attr_vars) = self.machine_st.populate_project_attr_lists(); self.machine_st.allocate(0); @@ -188,6 +188,6 @@ impl Machine { self.machine_st.query_stepper(&mut self.indices, &mut self.policies, &mut self.code_repo, &mut readline::input_stream()); - self.machine_st.print_attribute_goals_string(&self.indices.op_dir, var_dict) + self.machine_st.print_attribute_goals_string(&self.indices.op_dir) } } diff --git a/src/prolog/machine/machine_errors.rs b/src/prolog/machine/machine_errors.rs index e9eb56f3..c2a7e336 100644 --- a/src/prolog/machine/machine_errors.rs +++ b/src/prolog/machine/machine_errors.rs @@ -391,7 +391,7 @@ pub enum SessionError { pub enum EvalSession { EntrySuccess, Error(SessionError), - InitialQuerySuccess(AllocVarDict, HeapVarDict), + InitialQuerySuccess(AllocVarDict), QueryFailure, SubsequentQuerySuccess, } diff --git a/src/prolog/machine/machine_state.rs b/src/prolog/machine/machine_state.rs index 50eb4c11..82f8126f 100644 --- a/src/prolog/machine/machine_state.rs +++ b/src/prolog/machine/machine_state.rs @@ -235,6 +235,7 @@ pub struct MachineState { pub(super) lifted_heap: Vec, pub(super) interms: Vec, // intermediate numbers. pub(super) last_call: bool, + pub(crate) heap_locs: HeapVarDict, pub(crate) flags: MachineFlags } diff --git a/src/prolog/machine/machine_state_impl.rs b/src/prolog/machine/machine_state_impl.rs index 8bcfde78..f790b980 100644 --- a/src/prolog/machine/machine_state_impl.rs +++ b/src/prolog/machine/machine_state_impl.rs @@ -64,6 +64,7 @@ impl MachineState { lifted_heap: Vec::with_capacity(1024), interms: vec![Number::default(); 256], last_call: false, + heap_locs: HeapVarDict::new(), flags: MachineFlags::default() } } @@ -94,6 +95,7 @@ impl MachineState { lifted_heap: Vec::with_capacity(capacity), interms: vec![Number::default(); 0], last_call: false, + heap_locs: HeapVarDict::new(), flags: MachineFlags::default() } } @@ -187,8 +189,7 @@ impl MachineState { } pub(super) - fn print_var_eq(&self, var: Rc, addr: Addr, op_dir: &OpDir, var_dict: &HeapVarDict, - mut output: Outputter) + fn print_var_eq(&self, var: Rc, addr: Addr, op_dir: &OpDir, mut output: Outputter) -> Outputter where Outputter: HCValueOutputter { @@ -199,7 +200,7 @@ impl MachineState { output.append(var.as_str()); output.append(" = "); - let mut printer = HCPrinter::from_heap_locs(&self, op_dir, output, var_dict); + let mut printer = HCPrinter::from_heap_locs(&self, op_dir, output); printer.numbervars = false; printer.quoted = true; @@ -2816,6 +2817,7 @@ impl MachineState { self.block = 0; self.ball.reset(); + self.heap_locs.clear(); self.lifted_heap.clear(); } diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index d076ea8b..4b2a4e63 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -217,7 +217,7 @@ impl Machine { pub fn run_toplevel(&mut self) { self.machine_st.p = CodePtr::Local(LocalCodePtr::DirEntry(self.toplevel_idx)); - self.run_query(&AllocVarDict::new(), &mut HeapVarDict::new()); + self.run_query(&AllocVarDict::new()); } pub fn new(prolog_stream: PrologStream) -> Self { @@ -316,41 +316,13 @@ impl Machine { pub fn submit_query(&mut self, code: Code, alloc_locs: AllocVarDict) -> EvalSession { - let mut heap_locs = HeapVarDict::new(); - self.code_repo.cached_query = code; - self.run_query(&alloc_locs, &mut heap_locs); + self.run_query(&alloc_locs); if self.machine_st.fail { EvalSession::QueryFailure } else { - EvalSession::InitialQuerySuccess(alloc_locs, heap_locs) - } - } - - fn record_var_places(&self, chunk_num: usize, alloc_locs: &AllocVarDict, - heap_locs: &mut HeapVarDict) - { - for (var, var_data) in alloc_locs { - match var_data { - &VarData::Perm(p) if p > 0 => - if !heap_locs.contains_key(var) { - let e = self.machine_st.e; - let r = var_data.as_reg_type().reg_num(); - let addr = self.machine_st.and_stack[e][r].clone(); - - heap_locs.insert(var.clone(), addr); - }, - &VarData::Temp(cn, _, _) if cn == chunk_num => { - let r = var_data.as_reg_type(); - - if r.reg_num() != 0 { - let addr = self.machine_st[r].clone(); - heap_locs.insert(var.clone(), addr); - } - }, - _ => {} - } + EvalSession::InitialQuerySuccess(alloc_locs) } } @@ -413,8 +385,9 @@ impl Machine { }; } - let term_output = self.machine_st.print_query(term, &self.indices.op_dir, - &var_dict); + self.machine_st.heap_locs = var_dict; + let term_output = self.machine_st.print_query(term, &self.indices.op_dir); + term_output.result() }, Err(err_stub) => { @@ -454,14 +427,14 @@ impl Machine { fn handle_eval_session(&mut self, result: EvalSession, snapshot: MachineState) { match result { - EvalSession::InitialQuerySuccess(alloc_locs, mut heap_locs) => + EvalSession::InitialQuerySuccess(alloc_locs) => loop { let bindings = { let mut output = PrinterOutputter::new(); - self.toplevel_heap_view(&heap_locs, output).result() + self.toplevel_heap_view(output).result() }; - let attr_goals = self.attribute_goals(&heap_locs); + let attr_goals = self.attribute_goals(); if !(self.machine_st.b > 0) { if bindings.is_empty() { @@ -499,7 +472,7 @@ impl Machine { let result = match next_keypress() { ContinueResult::ContinueQuery => { write!(raw_stdout, " ;\r\n").unwrap(); - self.continue_query(&alloc_locs, &mut heap_locs) + self.continue_query(&alloc_locs) }, ContinueResult::Conclude => { write!(raw_stdout, " ...\r\n").unwrap(); @@ -563,7 +536,7 @@ impl Machine { } pub(super) - fn run_query(&mut self, alloc_locs: &AllocVarDict, heap_locs: &mut HeapVarDict) + fn run_query(&mut self, alloc_locs: &AllocVarDict) { let end_ptr = top_level_code_ptr!(0, self.code_repo.size_of_cached_query()); @@ -571,7 +544,7 @@ impl Machine { if let CodePtr::Local(LocalCodePtr::TopLevel(mut cn, p)) = self.machine_st.p { match &self.code_repo[LocalCodePtr::TopLevel(cn, p)] { &Line::Control(ref ctrl_instr) if ctrl_instr.is_jump_instr() => { - self.record_var_places(cn, alloc_locs, heap_locs); + self.machine_st.record_var_places(cn, alloc_locs); cn += 1; }, _ => {} @@ -595,8 +568,8 @@ impl Machine { self.dynamic_transaction(trans_type, p); if let CodePtr::Local(LocalCodePtr::TopLevel(_, 0)) = self.machine_st.p { - if heap_locs.is_empty() { - self.record_var_places(0, alloc_locs, heap_locs); + if self.machine_st.heap_locs.is_empty() { + self.machine_st.record_var_places(0, alloc_locs); } self.code_repo.cached_query = cached_query; @@ -606,8 +579,8 @@ impl Machine { self.code_repo.cached_query = cached_query; }, _ => { - if heap_locs.is_empty() { - self.record_var_places(0, alloc_locs, heap_locs); + if self.machine_st.heap_locs.is_empty() { + self.machine_st.record_var_places(0, alloc_locs); } break; @@ -616,7 +589,7 @@ impl Machine { } } - pub fn continue_query(&mut self, alloc_l: &AllocVarDict, heap_l: &mut HeapVarDict) -> EvalSession + pub fn continue_query(&mut self, alloc_locs: &AllocVarDict) -> EvalSession { if !self.or_stack_is_empty() { let b = self.machine_st.b - 1; @@ -627,7 +600,7 @@ impl Machine { return EvalSession::QueryFailure; } - self.run_query(alloc_l, heap_l); + self.run_query(alloc_locs); if self.machine_st.fail { EvalSession::QueryFailure @@ -639,15 +612,15 @@ impl Machine { } } - pub fn toplevel_heap_view(&self, var_dir: &HeapVarDict, mut output: Outputter) -> Outputter + pub fn toplevel_heap_view(&self, mut output: Outputter) -> Outputter where Outputter: HCValueOutputter { - let mut sorted_vars: Vec<_> = var_dir.iter().collect(); + let mut sorted_vars: Vec<_> = self.machine_st.heap_locs.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())); - output = self.machine_st.print_var_eq(var.clone(), addr, &self.indices.op_dir, var_dir, + output = self.machine_st.print_var_eq(var.clone(), addr, &self.indices.op_dir, output); } @@ -655,16 +628,15 @@ impl Machine { } #[cfg(test)] - pub fn test_heap_view(&self, var_dir: &HeapVarDict, mut output: Outputter) - -> Outputter + pub fn test_heap_view(&self, mut output: Outputter) -> Outputter where Outputter: HCValueOutputter { - let mut sorted_vars: Vec<(&Rc, &Addr)> = var_dir.iter().collect(); + let mut sorted_vars: Vec<(&Rc, &Addr)> = self.machine_st.heap_locs.iter().collect(); sorted_vars.sort_by_key(|ref v| v.0); for (var, addr) in sorted_vars { output = self.machine_st.print_var_eq(var.clone(), addr.clone(), &self.indices.op_dir, - var_dir, output); + output); } output @@ -677,7 +649,32 @@ impl Machine { impl MachineState { - fn print_query(&mut self, addr: Addr, op_dir: &OpDir, var_dict: &HeapVarDict) -> PrinterOutputter + fn record_var_places(&mut self, chunk_num: usize, alloc_locs: &AllocVarDict) + { + for (var, var_data) in alloc_locs { + match var_data { + &VarData::Perm(p) if p > 0 => + if !self.heap_locs.contains_key(var) { + let e = self.e; + let r = var_data.as_reg_type().reg_num(); + let addr = self.and_stack[e][r].clone(); + + self.heap_locs.insert(var.clone(), addr); + }, + &VarData::Temp(cn, _, _) if cn == chunk_num => { + let r = var_data.as_reg_type(); + + if r.reg_num() != 0 { + let addr = self[r].clone(); + self.heap_locs.insert(var.clone(), addr); + } + }, + _ => {} + } + } + } + + fn print_query(&mut self, addr: Addr, op_dir: &OpDir) -> PrinterOutputter { let flags = self.flags; @@ -685,7 +682,7 @@ impl MachineState { self.flags = MachineFlags { double_quotes: DoubleQuotes::Atom }; let output = PrinterOutputter::new(); - let mut printer = HCPrinter::from_heap_locs(&self, op_dir, output, var_dict); + let mut printer = HCPrinter::from_heap_locs(&self, op_dir, output); printer.quoted = true; printer.numbervars = false; diff --git a/src/prolog/machine/system_calls.rs b/src/prolog/machine/system_calls.rs index 8230950c..a9cd571b 100644 --- a/src/prolog/machine/system_calls.rs +++ b/src/prolog/machine/system_calls.rs @@ -18,7 +18,7 @@ use prolog::read::{PrologStream, readline}; use ref_thread_local::RefThreadLocal; -use std::collections::HashSet; +use std::collections::{HashMap, HashSet}; use std::io::{stdout, Write}; use std::iter::once; use std::mem; @@ -356,7 +356,7 @@ impl MachineState { -> CallResult { let nx = self[temp_v!(2)].clone(); - + if let Some(c) = string.chars().last() { if layout_char!(c) { let err = ParserError::UnexpectedChar(c); @@ -555,7 +555,7 @@ impl MachineState { self.unify(a2, Addr::Con(Constant::Number(len))); }, - &SystemClauseType::CharsToNumber => { + &SystemClauseType::CharsToNumber => { let stub = MachineError::functor_stub(clause_name!("number_chars"), 2); match self.try_from_list(temp_v!(1), stub.clone()) { @@ -585,7 +585,7 @@ impl MachineState { let char_list = Addr::HeapCell(self.heap.to_list(chars)); self.unify(char_list, chs); - }, + }, &SystemClauseType::NumberToCodes => { let n = self[temp_v!(1)].clone(); let chs = self[temp_v!(2)].clone(); @@ -1666,6 +1666,47 @@ impl MachineState { printer.quoted = name.as_str() == "true"; } + let stub = MachineError::functor_stub(clause_name!("write_term"), 2); + + match self.try_from_list(temp_v!(5), stub.clone()) { + Ok(addrs) => { + let mut var_names: HashMap = HashMap::new(); + + for addr in addrs { + match addr { + Addr::Str(s) => + match &self.heap[s] { + &HeapCellValue::NamedStr(2, ref name, _) + if name.as_str() == "=" => { + let atom = self.heap[s+1].as_addr(s+1); + let var = self.heap[s+2].as_addr(s+2); + + let atom = match self.store(self.deref(atom)) { + Addr::Con(Constant::Atom(atom, _)) => atom.to_string(), + Addr::Con(Constant::Char(c)) => c.to_string(), + _ => unreachable!() + }; + + let var = self.store(self.deref(var)); + + if var_names.contains_key(&var) { + continue; + } + + var_names.insert(var, atom); + }, + _ => unreachable!() + }, + _ => unreachable!() + } + } + + printer.var_names = var_names; + }, + Err(err) => + return Err(err) + } + let mut output = printer.print(addr); print!("{}", output.result()); stdout().flush().unwrap(); diff --git a/src/prolog/machine/term_expansion.rs b/src/prolog/machine/term_expansion.rs index f2d952ff..fdd28c57 100644 --- a/src/prolog/machine/term_expansion.rs +++ b/src/prolog/machine/term_expansion.rs @@ -289,13 +289,13 @@ impl<'a, R: Read> TermStream<'a, R> { impl MachineState { pub(super) - fn print_with_locs(&self, addr: Addr, op_dir: &OpDir, var_dict: &HeapVarDict) -> PrinterOutputter + fn print_with_locs(&self, addr: Addr, op_dir: &OpDir) -> PrinterOutputter { let output = PrinterOutputter::new(); - let mut printer = HCPrinter::from_heap_locs(&self, op_dir, output, var_dict); + let mut printer = HCPrinter::from_heap_locs(&self, op_dir, output); let mut max_var_length = 0; - for var in var_dict.keys() { + for var in self.heap_locs.keys() { max_var_length = std::cmp::max(var.len(), max_var_length); } @@ -337,8 +337,10 @@ impl MachineState { self.reset(); None } else { - let &TermWriteResult { heap_loc: _, ref var_dict } = &term_write_result; - let output = self.print_with_locs(Addr::HeapCell(h), &indices.op_dir, var_dict); + let TermWriteResult { var_dict, .. } = term_write_result; + + self.heap_locs = var_dict; + let output = self.print_with_locs(Addr::HeapCell(h), &indices.op_dir); self.reset(); Some(output.result()) diff --git a/src/tests.rs b/src/tests.rs index 338ff528..2df7406b 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -84,30 +84,27 @@ impl HCValueOutputter for TestOutputter { } } -pub fn collect_test_output(wam: &mut Machine, alloc_locs: AllocVarDict, mut heap_locs: HeapVarDict) - -> Vec> +pub fn collect_test_output(wam: &mut Machine, alloc_locs: AllocVarDict) -> Vec> { let mut output = TestOutputter::new(); - output = wam.test_heap_view(&heap_locs, output); + output = wam.test_heap_view(output); output.cache(); - while let EvalSession::SubsequentQuerySuccess = wam.continue_query(&alloc_locs, &mut heap_locs) - { - output = wam.test_heap_view(&heap_locs, output); + while let EvalSession::SubsequentQuerySuccess = wam.continue_query(&alloc_locs) { + output = wam.test_heap_view(output); output.cache(); } output.result() } -pub fn collect_test_output_with_limit(wam: &mut Machine, alloc_locs: AllocVarDict, - mut heap_locs: HeapVarDict, limit: usize) +pub fn collect_test_output_with_limit(wam: &mut Machine, alloc_locs: AllocVarDict, limit: usize) -> Vec> { let mut output = TestOutputter::new(); - output = wam.test_heap_view(&heap_locs, output); + output = wam.test_heap_view(output); output.cache(); let mut count = 1; @@ -116,9 +113,9 @@ pub fn collect_test_output_with_limit(wam: &mut Machine, alloc_locs: AllocVarDic return output.result(); } - while let EvalSession::SubsequentQuerySuccess = wam.continue_query(&alloc_locs, &mut heap_locs) + while let EvalSession::SubsequentQuerySuccess = wam.continue_query(&alloc_locs) { - output = wam.test_heap_view(&heap_locs, output); + output = wam.test_heap_view(output); output.cache(); count += 1; @@ -137,7 +134,7 @@ pub fn submit(wam: &mut Machine, buffer: &str) -> bool wam.reset(); match submit_code(wam, buffer) { - EvalSession::InitialQuerySuccess(_, _) | + EvalSession::InitialQuerySuccess(_) | EvalSession::EntrySuccess | EvalSession::SubsequentQuerySuccess => true, @@ -153,8 +150,8 @@ pub fn submit_query(wam: &mut Machine, buffer: &str, result: Vec match stream_to_toplevel(parsing_stream(buffer.as_bytes()), wam) { Ok(term) => match compile_term(wam, term) { - EvalSession::InitialQuerySuccess(alloc_locs, heap_locs) => - result == collect_test_output(wam, alloc_locs, heap_locs), + EvalSession::InitialQuerySuccess(alloc_locs) => + result == collect_test_output(wam, alloc_locs), EvalSession::EntrySuccess => true, _ => false }, @@ -188,9 +185,8 @@ pub fn submit_query_with_limit(wam: &mut Machine, buffer: &str, match stream_to_toplevel(parsing_stream(buffer.as_bytes()), wam) { Ok(term) => match compile_term(wam, term) { - EvalSession::InitialQuerySuccess(alloc_locs, heap_locs) => - result == collect_test_output_with_limit(wam, alloc_locs, - heap_locs, limit), + EvalSession::InitialQuerySuccess(alloc_locs) => + result == collect_test_output_with_limit(wam, alloc_locs, limit), EvalSession::EntrySuccess => true, _ => false }, @@ -1673,7 +1669,7 @@ fn test_queries_on_builtins() submit(&mut wam, ":- use_module(library(non_iso))."); - assert_prolog_success!(&mut wam, "call_with_inference_limit((setup_call_cleanup(S=1,(G=2;fail),writeq(S+G>B)),B=3,!),100,R).", + assert_prolog_success!(&mut wam, "call_with_inference_limit((setup_call_cleanup(S=1,(G=2;fail),writeq(S+G>B)),B=3,!),135,R).", [["G = 2","B = 3","R = !","S = 1"]]); assert_prolog_success!(&mut wam, "call_with_inference_limit((setup_call_cleanup(S=1,(G=2;fail),writeq(S+G>B)),B=3,!),10,R).", [["S = _1","G = _4","B = _14","R = inference_limit_exceeded"]]);