add numbered vars to writeq

This commit is contained in:
Mark Thom
2018-07-16 20:12:50 -06:00
parent c5e1a08214
commit 82ff377585
4 changed files with 72 additions and 32 deletions

View File

@@ -5,7 +5,7 @@ use std::collections::HashSet;
use std::vec::Vec; use std::vec::Vec;
pub struct HCPreOrderIterator<'a> { pub struct HCPreOrderIterator<'a> {
machine_st: &'a MachineState, pub(crate) machine_st: &'a MachineState,
state_stack: Vec<Addr> state_stack: Vec<Addr>
} }

View File

@@ -1,4 +1,5 @@
use prolog::ast::*; use prolog::ast::*;
use prolog::num::*;
use prolog::heap_iter::*; use prolog::heap_iter::*;
use prolog::machine::machine_state::MachineState; use prolog::machine::machine_state::MachineState;
use prolog::ordered_float::OrderedFloat; use prolog::ordered_float::OrderedFloat;
@@ -10,6 +11,7 @@ use std::rc::Rc;
#[derive(Clone)] #[derive(Clone)]
pub enum TokenOrRedirect { pub enum TokenOrRedirect {
Atom(ClauseName), Atom(ClauseName),
NumberedVar(String),
Redirect, Redirect,
Open, Open,
Close, Close,
@@ -40,7 +42,7 @@ pub trait HCValueFormatter {
// this can be overloaded to handle special cases, falling back on the default of // this can be overloaded to handle special cases, falling back on the default of
// format_struct when convenient. // format_struct when convenient.
fn format_clause(&self, usize, ClauseType, &mut Vec<TokenOrRedirect>); fn format_clause(&self, &mut HCPreOrderIterator, usize, ClauseType, &mut Vec<TokenOrRedirect>);
} }
pub trait HCValueOutputter { pub trait HCValueOutputter {
@@ -99,44 +101,81 @@ impl HCValueOutputter for PrinterOutputter {
} }
// the 'classic' display corresponding to the display predicate. // the 'classic' display corresponding to the display predicate.
pub struct DisplayFormatter {} pub struct WriteqFormatter {}
impl HCValueFormatter for DisplayFormatter { fn is_numbered_var(ct: &ClauseType, arity: usize) -> bool {
fn format_clause(&self, arity: usize, ct: ClauseType, state_stack: &mut Vec<TokenOrRedirect>) arity == 1 && if let &ClauseType::Named(ref name, _) = ct {
{ name.as_str() == "$VAR"
if ct.fixity().is_some() { } else {
let mut new_name = String::from("'"); false
new_name += ct.name().as_str(); }
new_name += "'"; }
self.format_struct(arity, ct.name(), state_stack); fn print_op(ct: ClauseType, fixity: Fixity, state_stack: &mut Vec<TokenOrRedirect>) {
} else { match fixity {
self.format_struct(arity, ct.name(), state_stack); Fixity::Post => {
state_stack.push(TokenOrRedirect::Atom(ct.name()));
state_stack.push(TokenOrRedirect::Redirect);
},
Fixity::Pre => {
state_stack.push(TokenOrRedirect::Redirect);
state_stack.push(TokenOrRedirect::Atom(ct.name()));
},
Fixity::In => {
state_stack.push(TokenOrRedirect::Redirect);
state_stack.push(TokenOrRedirect::Atom(ct.name()));
state_stack.push(TokenOrRedirect::Redirect);
} }
} }
} }
impl HCValueFormatter for WriteqFormatter {
fn format_clause(&self, iter: &mut HCPreOrderIterator, arity: usize,
ct: ClauseType, state_stack: &mut Vec<TokenOrRedirect>)
{
static CHAR_CODES: [char; 26] = ['A','B','C','D','E','F','G','H','I','J',
'K','L','M','N','O','P','Q','R','S','T',
'U','V','W','X','Y','Z'];
if let Some(fixity) = ct.fixity() {
return print_op(ct, fixity, state_stack);
} else if is_numbered_var(&ct, arity) {
let addr = iter.stack().last().cloned().unwrap();
// 7.10.4
match iter.machine_st.store(iter.machine_st.deref(addr)) {
Addr::Con(Constant::Number(Number::Integer(n))) => {
iter.stack().pop();
let i = n.mod_floor(&BigInt::from(26)).to_usize().unwrap();
let j = n.div_floor(&BigInt::from(26));
let mut result = if j.is_zero() {
CHAR_CODES[i].to_string()
} else {
format!("{}{}", CHAR_CODES[i], j)
};
state_stack.push(TokenOrRedirect::NumberedVar(result));
return;
}
_ => {}
};
}
self.format_struct(arity, ct.name(), state_stack);
}
}
pub struct TermFormatter {} pub struct TermFormatter {}
impl HCValueFormatter for TermFormatter { impl HCValueFormatter for TermFormatter {
fn format_clause(&self, arity: usize, ct: ClauseType, state_stack: &mut Vec<TokenOrRedirect>) fn format_clause(&self, _: &mut HCPreOrderIterator, arity: usize, ct: ClauseType,
state_stack: &mut Vec<TokenOrRedirect>)
{ {
if let Some(fixity) = ct.fixity() { if let Some(fixity) = ct.fixity() {
match fixity { print_op(ct, fixity, state_stack);
Fixity::Post => {
state_stack.push(TokenOrRedirect::Atom(ct.name()));
state_stack.push(TokenOrRedirect::Redirect);
},
Fixity::Pre => {
state_stack.push(TokenOrRedirect::Redirect);
state_stack.push(TokenOrRedirect::Atom(ct.name()));
},
Fixity::In => {
state_stack.push(TokenOrRedirect::Redirect);
state_stack.push(TokenOrRedirect::Atom(ct.name()));
state_stack.push(TokenOrRedirect::Redirect);
}
}
} else { } else {
self.format_struct(arity, ct.name(), state_stack); self.format_struct(arity, ct.name(), state_stack);
} }
@@ -303,7 +342,7 @@ impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter>
match heap_val { match heap_val {
HeapCellValue::NamedStr(arity, name, fixity) => { HeapCellValue::NamedStr(arity, name, fixity) => {
let ct = ClauseType::from(name, arity, fixity); let ct = ClauseType::from(name, arity, fixity);
self.formatter.format_clause(arity, ct, &mut self.state_stack) self.formatter.format_clause(iter, arity, ct, &mut self.state_stack)
}, },
HeapCellValue::Addr(Addr::Con(Constant::EmptyList)) => HeapCellValue::Addr(Addr::Con(Constant::EmptyList)) =>
if !self.at_cdr("") { if !self.at_cdr("") {
@@ -349,6 +388,8 @@ impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter>
// self.outputter.append(" "), // self.outputter.append(" "),
TokenOrRedirect::Atom(atom) => TokenOrRedirect::Atom(atom) =>
self.outputter.append(atom.as_str()), self.outputter.append(atom.as_str()),
TokenOrRedirect::NumberedVar(num_var) =>
self.outputter.append(num_var.as_str()),
TokenOrRedirect::Redirect => TokenOrRedirect::Redirect =>
self.handle_heap_term(&mut iter), self.handle_heap_term(&mut iter),
TokenOrRedirect::Close => TokenOrRedirect::Close =>

View File

@@ -1,7 +1,6 @@
use prolog::ast::*; use prolog::ast::*;
use prolog::heap_print::*; use prolog::heap_print::*;
use prolog::machine::*; use prolog::machine::*;
use prolog::ordered_float::OrderedFloat;
use termion::raw::IntoRawMode; use termion::raw::IntoRawMode;
use termion::input::TermRead; use termion::input::TermRead;

View File

@@ -494,7 +494,7 @@ pub(crate) trait CallPolicy: Any {
}, },
&BuiltInClauseType::Writeq => { &BuiltInClauseType::Writeq => {
let output = machine_st.print_term(machine_st[temp_v!(1)].clone(), let output = machine_st.print_term(machine_st[temp_v!(1)].clone(),
DisplayFormatter {}, WriteqFormatter {},
PrinterOutputter::new()); PrinterOutputter::new());
println!("{}", output.result()); println!("{}", output.result());