add variable_names as a write option
This commit is contained in:
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -391,7 +391,7 @@ pub enum SessionError {
|
||||
pub enum EvalSession {
|
||||
EntrySuccess,
|
||||
Error(SessionError),
|
||||
InitialQuerySuccess(AllocVarDict, HeapVarDict),
|
||||
InitialQuerySuccess(AllocVarDict),
|
||||
QueryFailure,
|
||||
SubsequentQuerySuccess,
|
||||
}
|
||||
|
||||
@@ -235,6 +235,7 @@ pub struct MachineState {
|
||||
pub(super) lifted_heap: Vec<HeapCellValue>,
|
||||
pub(super) interms: Vec<Number>, // intermediate numbers.
|
||||
pub(super) last_call: bool,
|
||||
pub(crate) heap_locs: HeapVarDict,
|
||||
pub(crate) flags: MachineFlags
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Outputter>(&self, var: Rc<Var>, addr: Addr, op_dir: &OpDir, var_dict: &HeapVarDict,
|
||||
mut output: Outputter)
|
||||
fn print_var_eq<Outputter>(&self, var: Rc<Var>, 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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Outputter>(&self, var_dir: &HeapVarDict, mut output: Outputter) -> Outputter
|
||||
pub fn toplevel_heap_view<Outputter>(&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<Outputter>(&self, var_dir: &HeapVarDict, mut output: Outputter)
|
||||
-> Outputter
|
||||
pub fn test_heap_view<Outputter>(&self, mut output: Outputter) -> Outputter
|
||||
where Outputter: HCValueOutputter
|
||||
{
|
||||
let mut sorted_vars: Vec<(&Rc<Var>, &Addr)> = var_dir.iter().collect();
|
||||
let mut sorted_vars: Vec<(&Rc<Var>, &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;
|
||||
|
||||
@@ -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<Addr, String> = 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();
|
||||
|
||||
@@ -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())
|
||||
|
||||
Reference in New Issue
Block a user