Format code using 'cargo fmt'
This commit is contained in:
@@ -7,7 +7,7 @@ use prolog::heap_iter::*;
|
||||
use prolog::machine::machine_indices::*;
|
||||
use prolog::machine::machine_state::*;
|
||||
use prolog::ordered_float::OrderedFloat;
|
||||
use prolog::rug::{Integer};
|
||||
use prolog::rug::Integer;
|
||||
|
||||
use indexmap::{IndexMap, IndexSet};
|
||||
|
||||
@@ -20,23 +20,23 @@ use std::rc::Rc;
|
||||
#[derive(Clone)]
|
||||
pub enum DirectedOp {
|
||||
Left(ClauseName, SharedOpDesc),
|
||||
Right(ClauseName, SharedOpDesc)
|
||||
Right(ClauseName, SharedOpDesc),
|
||||
}
|
||||
|
||||
impl DirectedOp {
|
||||
#[inline]
|
||||
fn as_str(&self) -> &str {
|
||||
match self {
|
||||
&DirectedOp::Left(ref name, _) | &DirectedOp::Right(ref name, _) =>
|
||||
name.as_str()
|
||||
&DirectedOp::Left(ref name, _) | &DirectedOp::Right(ref name, _) => name.as_str(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_negative_sign(&self) -> bool {
|
||||
match self {
|
||||
&DirectedOp::Left(ref name, ref cell) | &DirectedOp::Right(ref name, ref cell) =>
|
||||
&DirectedOp::Left(ref name, ref cell) | &DirectedOp::Right(ref name, ref cell) => {
|
||||
name.as_str() == "-" && is_prefix!(cell.assoc())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,8 +50,7 @@ impl DirectedOp {
|
||||
}
|
||||
}
|
||||
|
||||
fn needs_bracketing(child_spec: &SharedOpDesc, op: &DirectedOp) -> bool
|
||||
{
|
||||
fn needs_bracketing(child_spec: &SharedOpDesc, op: &DirectedOp) -> bool {
|
||||
match op {
|
||||
&DirectedOp::Left(ref name, ref cell) => {
|
||||
let (priority, spec) = cell.get();
|
||||
@@ -65,7 +64,7 @@ fn needs_bracketing(child_spec: &SharedOpDesc, op: &DirectedOp) -> bool
|
||||
|
||||
let is_strict_right = is_yfx!(spec) || is_xfx!(spec) || is_fx!(spec);
|
||||
child_spec.prec() > priority || (child_spec.prec() == priority && is_strict_right)
|
||||
},
|
||||
}
|
||||
&DirectedOp::Right(_, ref cell) => {
|
||||
let (priority, spec) = cell.get();
|
||||
let is_strict_left = is_xfx!(spec) || is_xfy!(spec) || is_xf!(spec);
|
||||
@@ -89,53 +88,51 @@ impl<'a> HCPreOrderIterator<'a> {
|
||||
* by brackets.
|
||||
*/
|
||||
fn leftmost_leaf_has_property<P>(&self, property_check: P) -> bool
|
||||
where P: Fn(Constant) -> bool
|
||||
where
|
||||
P: Fn(Constant) -> bool,
|
||||
{
|
||||
let mut addr = match self.state_stack.last().cloned() {
|
||||
Some(addr) => addr,
|
||||
None => return false
|
||||
None => return false,
|
||||
};
|
||||
|
||||
let mut parent_spec = DirectedOp::Left(clause_name!("-"), SharedOpDesc::new(200, FY));
|
||||
|
||||
loop {
|
||||
match self.machine_st.store(self.machine_st.deref(addr)) {
|
||||
Addr::Str(s) =>
|
||||
match &self.machine_st.heap[s] {
|
||||
&HeapCellValue::NamedStr(_, ref name, Some(ref spec))
|
||||
if is_postfix!(spec.assoc()) || is_infix!(spec.assoc()) =>
|
||||
if needs_bracketing(spec, &parent_spec) {
|
||||
return false;
|
||||
} else {
|
||||
addr = Addr::HeapCell(s+1);
|
||||
parent_spec = DirectedOp::Right(name.clone(), spec.clone());
|
||||
},
|
||||
_ =>
|
||||
return false
|
||||
},
|
||||
Addr::Con(Constant::Integer(n)) =>
|
||||
return property_check(Constant::Integer(n)),
|
||||
Addr::Con(Constant::Float(n)) =>
|
||||
return property_check(Constant::Float(n)),
|
||||
Addr::Con(Constant::Rational(n)) =>
|
||||
return property_check(Constant::Rational(n)),
|
||||
_ =>
|
||||
return false
|
||||
Addr::Str(s) => match &self.machine_st.heap[s] {
|
||||
&HeapCellValue::NamedStr(_, ref name, Some(ref spec))
|
||||
if is_postfix!(spec.assoc()) || is_infix!(spec.assoc()) =>
|
||||
{
|
||||
if needs_bracketing(spec, &parent_spec) {
|
||||
return false;
|
||||
} else {
|
||||
addr = Addr::HeapCell(s + 1);
|
||||
parent_spec = DirectedOp::Right(name.clone(), spec.clone());
|
||||
}
|
||||
}
|
||||
_ => return false,
|
||||
},
|
||||
Addr::Con(Constant::Integer(n)) => return property_check(Constant::Integer(n)),
|
||||
Addr::Con(Constant::Float(n)) => return property_check(Constant::Float(n)),
|
||||
Addr::Con(Constant::Rational(n)) => return property_check(Constant::Rational(n)),
|
||||
_ => return false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn immediate_leaf_has_property<P>(&self, property_check: P) -> bool
|
||||
where P: Fn(Constant) -> bool
|
||||
where
|
||||
P: Fn(Constant) -> bool,
|
||||
{
|
||||
let addr = match self.state_stack.last().cloned() {
|
||||
Some(addr) => addr,
|
||||
None => return false
|
||||
None => return false,
|
||||
};
|
||||
|
||||
match self.machine_st.store(self.machine_st.deref(addr)) {
|
||||
Addr::Con(c) => property_check(c),
|
||||
_ => false
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -150,8 +147,8 @@ fn char_to_string(c: char) -> String {
|
||||
'\u{0c}' => "\\f".to_string(), // UTF-8 form feed
|
||||
'\u{08}' => "\\b".to_string(), // UTF-8 backspace
|
||||
'\u{07}' => "\\a".to_string(), // UTF-8 alert
|
||||
'\x20' ... '\x7e' => c.to_string(),
|
||||
_ => format!("\\x{:x}\\", c as u32)
|
||||
'\x20'...'\x7e' => c.to_string(),
|
||||
_ => format!("\\x{:x}\\", c as u32),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,14 +187,16 @@ pub trait HCValueOutputter {
|
||||
}
|
||||
|
||||
pub struct PrinterOutputter {
|
||||
contents: String
|
||||
contents: String,
|
||||
}
|
||||
|
||||
impl HCValueOutputter for PrinterOutputter {
|
||||
type Output = String;
|
||||
|
||||
fn new() -> Self {
|
||||
PrinterOutputter { contents: String::new() }
|
||||
PrinterOutputter {
|
||||
contents: String::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn append(&mut self, contents: &str) {
|
||||
@@ -253,17 +252,15 @@ fn is_numbered_var(ct: &ClauseType, arity: usize) -> bool {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn negated_op_needs_bracketing(iter: &HCPreOrderIterator, op: &Option<DirectedOp>) -> bool
|
||||
{
|
||||
fn negated_op_needs_bracketing(iter: &HCPreOrderIterator, op: &Option<DirectedOp>) -> bool {
|
||||
if let &Some(ref op) = op {
|
||||
op.is_negative_sign() && iter.leftmost_leaf_has_property(|c| {
|
||||
match c {
|
||||
op.is_negative_sign()
|
||||
&& iter.leftmost_leaf_has_property(|c| match c {
|
||||
Constant::Integer(n) => n > 0,
|
||||
Constant::Float(f) => f > OrderedFloat(0f64),
|
||||
Constant::Rational(r) => r > 0,
|
||||
_ => false
|
||||
}
|
||||
})
|
||||
_ => false,
|
||||
})
|
||||
} else {
|
||||
false
|
||||
}
|
||||
@@ -271,26 +268,26 @@ fn negated_op_needs_bracketing(iter: &HCPreOrderIterator, op: &Option<DirectedOp
|
||||
|
||||
impl MachineState {
|
||||
pub fn numbervar(&self, offset: &Integer, addr: Addr) -> Option<Var> {
|
||||
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'];
|
||||
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',
|
||||
];
|
||||
|
||||
match self.store(self.deref(addr)) {
|
||||
Addr::Con(Constant::Integer(ref n))
|
||||
if n >= &0 => {
|
||||
let n = Integer::from(offset + n);
|
||||
Addr::Con(Constant::Integer(ref n)) if n >= &0 => {
|
||||
let n = Integer::from(offset + n);
|
||||
|
||||
let i = n.mod_u(26) as usize;
|
||||
let j = n.div_rem_floor(Integer::from(26));
|
||||
let j = <(Integer, Integer)>::from(j).1;
|
||||
|
||||
Some(if j == 0 {
|
||||
CHAR_CODES[i].to_string()
|
||||
} else {
|
||||
format!("{}{}", CHAR_CODES[i], j)
|
||||
})
|
||||
},
|
||||
_ => None
|
||||
let i = n.mod_u(26) as usize;
|
||||
let j = n.div_rem_floor(Integer::from(26));
|
||||
let j = <(Integer, Integer)>::from(j).1;
|
||||
|
||||
Some(if j == 0 {
|
||||
CHAR_CODES[i].to_string()
|
||||
} else {
|
||||
format!("{}{}", CHAR_CODES[i], j)
|
||||
})
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -309,80 +306,94 @@ pub struct HCPrinter<'a, Outputter> {
|
||||
cyclic_terms: IndexMap<Addr, usize>,
|
||||
pub(crate) var_names: IndexMap<Addr, String>,
|
||||
pub(crate) numbervars_offset: Integer,
|
||||
pub(crate) numbervars: bool,
|
||||
pub(crate) quoted: bool,
|
||||
pub(crate) ignore_ops: bool
|
||||
pub(crate) numbervars: bool,
|
||||
pub(crate) quoted: bool,
|
||||
pub(crate) ignore_ops: bool,
|
||||
}
|
||||
|
||||
macro_rules! push_space_if_amb {
|
||||
($self:expr, $atom:expr, $action:block) => (
|
||||
($self:expr, $atom:expr, $action:block) => {
|
||||
if $self.ambiguity_check($atom) {
|
||||
$self.outputter.push_char(' ');
|
||||
$action;
|
||||
} else {
|
||||
$action;
|
||||
}
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
pub fn requires_space(atom: &str, op: &str) -> bool {
|
||||
match atom.chars().last() {
|
||||
Some(ac) => op.chars().next().map(|oc| {
|
||||
if ac == '0' {
|
||||
oc == 'b' || oc == 'x' || oc == 'o' || oc == '\''
|
||||
} else if alpha_numeric_char!(ac) {
|
||||
oc == '(' || alpha_numeric_char!(oc)
|
||||
} else if graphic_token_char!(ac) {
|
||||
graphic_token_char!(oc)
|
||||
} else if variable_indicator_char!(ac) {
|
||||
alpha_numeric_char!(oc)
|
||||
} else if capital_letter_char!(ac) {
|
||||
alpha_numeric_char!(oc)
|
||||
} else if sign_char!(ac) {
|
||||
sign_char!(oc) || decimal_digit_char!(oc)
|
||||
} else if single_quote_char!(ac) {
|
||||
single_quote_char!(oc)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}).unwrap_or(false),
|
||||
_ => false
|
||||
Some(ac) => op
|
||||
.chars()
|
||||
.next()
|
||||
.map(|oc| {
|
||||
if ac == '0' {
|
||||
oc == 'b' || oc == 'x' || oc == 'o' || oc == '\''
|
||||
} else if alpha_numeric_char!(ac) {
|
||||
oc == '(' || alpha_numeric_char!(oc)
|
||||
} else if graphic_token_char!(ac) {
|
||||
graphic_token_char!(oc)
|
||||
} else if variable_indicator_char!(ac) {
|
||||
alpha_numeric_char!(oc)
|
||||
} else if capital_letter_char!(ac) {
|
||||
alpha_numeric_char!(oc)
|
||||
} else if sign_char!(ac) {
|
||||
sign_char!(oc) || decimal_digit_char!(oc)
|
||||
} else if single_quote_char!(ac) {
|
||||
single_quote_char!(oc)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
.unwrap_or(false),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn reverse_heap_locs<'a>(machine_st: &'a MachineState) -> ReverseHeapVarDict
|
||||
{
|
||||
machine_st.heap_locs.iter().map(|(var, var_addr)| {
|
||||
(machine_st.store(machine_st.deref(var_addr.clone())), var.clone())
|
||||
}).collect()
|
||||
fn reverse_heap_locs<'a>(machine_st: &'a MachineState) -> ReverseHeapVarDict {
|
||||
machine_st
|
||||
.heap_locs
|
||||
.iter()
|
||||
.map(|(var, var_addr)| {
|
||||
(
|
||||
machine_st.store(machine_st.deref(var_addr.clone())),
|
||||
var.clone(),
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn non_quoted_graphic_token<Iter: Iterator<Item=char>>(mut iter: Iter, c: char) -> bool {
|
||||
fn non_quoted_graphic_token<Iter: Iterator<Item = char>>(mut iter: Iter, c: char) -> bool {
|
||||
if c == '/' {
|
||||
return match iter.next() {
|
||||
None => true,
|
||||
Some('*') => false, // if we start with comment token, we must quote.
|
||||
Some(c) => if graphic_token_char!(c) {
|
||||
iter.all(|c| graphic_token_char!(c))
|
||||
} else {
|
||||
false
|
||||
Some(c) => {
|
||||
if graphic_token_char!(c) {
|
||||
iter.all(|c| graphic_token_char!(c))
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
} else if c == '.' {
|
||||
return match iter.next() {
|
||||
None => false,
|
||||
Some(c) => if graphic_token_char!(c) {
|
||||
iter.all(|c| graphic_token_char!(c))
|
||||
} else {
|
||||
false
|
||||
Some(c) => {
|
||||
if graphic_token_char!(c) {
|
||||
iter.all(|c| graphic_token_char!(c))
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
} else {
|
||||
iter.all(|c| graphic_token_char!(c))
|
||||
}
|
||||
}
|
||||
|
||||
fn non_quoted_token<Iter: Iterator<Item=char>>(mut iter: Iter) -> bool {
|
||||
fn non_quoted_token<Iter: Iterator<Item = char>>(mut iter: Iter) -> bool {
|
||||
if let Some(c) = iter.next() {
|
||||
if small_letter_char!(c) {
|
||||
iter.all(|c| alpha_numeric_char!(c))
|
||||
@@ -406,32 +417,37 @@ fn non_quoted_token<Iter: Iterator<Item=char>>(mut iter: Iter) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
|
||||
{
|
||||
pub fn new(machine_st: &'a MachineState, op_dir: &'a OpDir, output: Outputter) -> Self
|
||||
{
|
||||
HCPrinter { outputter: output,
|
||||
machine_st,
|
||||
op_dir,
|
||||
state_stack: vec![],
|
||||
heap_locs: ReverseHeapVarDict::new(),
|
||||
toplevel_spec: None,
|
||||
printed_vars: IndexSet::new(),
|
||||
last_item_idx: 0,
|
||||
numbervars: false,
|
||||
numbervars_offset: Integer::from(0),
|
||||
quoted: false,
|
||||
ignore_ops: false,
|
||||
cyclic_terms: IndexMap::new(),
|
||||
var_names: IndexMap::new() }
|
||||
impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
pub fn new(machine_st: &'a MachineState, op_dir: &'a OpDir, output: Outputter) -> Self {
|
||||
HCPrinter {
|
||||
outputter: output,
|
||||
machine_st,
|
||||
op_dir,
|
||||
state_stack: vec![],
|
||||
heap_locs: ReverseHeapVarDict::new(),
|
||||
toplevel_spec: None,
|
||||
printed_vars: IndexSet::new(),
|
||||
last_item_idx: 0,
|
||||
numbervars: false,
|
||||
numbervars_offset: Integer::from(0),
|
||||
quoted: false,
|
||||
ignore_ops: false,
|
||||
cyclic_terms: IndexMap::new(),
|
||||
var_names: IndexMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_heap_locs(machine_st: &'a MachineState, op_dir: &'a OpDir, output: Outputter)
|
||||
-> Self
|
||||
{
|
||||
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.toplevel_spec = Some(DirectedOp::Right(
|
||||
clause_name!("="),
|
||||
SharedOpDesc::new(700, XFX),
|
||||
));
|
||||
printer.heap_locs = reverse_heap_locs(machine_st);
|
||||
|
||||
printer
|
||||
@@ -449,9 +465,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn ambiguity_check(&self, atom: &str) -> bool
|
||||
{
|
||||
let tail = self.outputter.range_from(self.last_item_idx ..);
|
||||
fn ambiguity_check(&self, atom: &str) -> bool {
|
||||
let tail = self.outputter.range_from(self.last_item_idx..);
|
||||
requires_space(tail, atom)
|
||||
}
|
||||
|
||||
@@ -460,7 +475,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
|
||||
let right_directed_op = DirectedOp::Right(ct.name(), spec.clone());
|
||||
|
||||
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
|
||||
self.state_stack.push(TokenOrRedirect::CompositeRedirect(right_directed_op));
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::CompositeRedirect(right_directed_op));
|
||||
} else if is_prefix!(spec.assoc()) {
|
||||
match ct.name().as_str() {
|
||||
"-" | "\\" => {
|
||||
@@ -472,31 +488,34 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
|
||||
|
||||
let left_directed_op = DirectedOp::Left(ct.name(), spec.clone());
|
||||
|
||||
self.state_stack.push(TokenOrRedirect::CompositeRedirect(left_directed_op));
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::CompositeRedirect(left_directed_op));
|
||||
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
|
||||
} else { // if is_infix!(spec.assoc())
|
||||
} else {
|
||||
// if is_infix!(spec.assoc())
|
||||
match ct.name().as_str() {
|
||||
"|" => {
|
||||
self.format_bar_separator_op(ct.name(), spec);
|
||||
return;
|
||||
},
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
let left_directed_op = DirectedOp::Left(ct.name(), spec.clone());
|
||||
let left_directed_op = DirectedOp::Left(ct.name(), spec.clone());
|
||||
let right_directed_op = DirectedOp::Right(ct.name(), spec.clone());
|
||||
|
||||
self.state_stack.push(TokenOrRedirect::CompositeRedirect(left_directed_op));
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::CompositeRedirect(left_directed_op));
|
||||
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
|
||||
self.state_stack.push(TokenOrRedirect::CompositeRedirect(right_directed_op));
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::CompositeRedirect(right_directed_op));
|
||||
}
|
||||
}
|
||||
|
||||
fn format_struct(&mut self, arity: usize, name: ClauseName)
|
||||
{
|
||||
fn format_struct(&mut self, arity: usize, name: ClauseName) {
|
||||
self.state_stack.push(TokenOrRedirect::Close);
|
||||
|
||||
for _ in 0 .. arity {
|
||||
for _ in 0..arity {
|
||||
self.state_stack.push(TokenOrRedirect::FunctorRedirect);
|
||||
self.state_stack.push(TokenOrRedirect::Comma);
|
||||
}
|
||||
@@ -507,34 +526,33 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
|
||||
self.state_stack.push(TokenOrRedirect::Atom(name));
|
||||
}
|
||||
|
||||
fn format_prefix_op_with_space(&mut self, name: ClauseName, spec: SharedOpDesc)
|
||||
{
|
||||
fn format_prefix_op_with_space(&mut self, name: ClauseName, spec: SharedOpDesc) {
|
||||
let op = DirectedOp::Left(name.clone(), spec);
|
||||
|
||||
self.state_stack.push(TokenOrRedirect::CompositeRedirect(op));
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::CompositeRedirect(op));
|
||||
self.state_stack.push(TokenOrRedirect::Space);
|
||||
self.state_stack.push(TokenOrRedirect::Atom(name));
|
||||
}
|
||||
|
||||
fn format_bar_separator_op(&mut self, name: ClauseName, spec: SharedOpDesc)
|
||||
{
|
||||
let left_directed_op = DirectedOp::Left(name.clone(), spec.clone());
|
||||
fn format_bar_separator_op(&mut self, name: ClauseName, spec: SharedOpDesc) {
|
||||
let left_directed_op = DirectedOp::Left(name.clone(), spec.clone());
|
||||
let right_directed_op = DirectedOp::Right(name.clone(), spec.clone());
|
||||
|
||||
self.state_stack.push(TokenOrRedirect::CompositeRedirect(left_directed_op));
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::CompositeRedirect(left_directed_op));
|
||||
self.state_stack.push(TokenOrRedirect::HeadTailSeparator);
|
||||
self.state_stack.push(TokenOrRedirect::CompositeRedirect(right_directed_op));
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::CompositeRedirect(right_directed_op));
|
||||
}
|
||||
|
||||
fn format_curly_braces(&mut self)
|
||||
{
|
||||
fn format_curly_braces(&mut self) {
|
||||
self.state_stack.push(TokenOrRedirect::RightCurly);
|
||||
self.state_stack.push(TokenOrRedirect::FunctorRedirect);
|
||||
self.state_stack.push(TokenOrRedirect::LeftCurly);
|
||||
}
|
||||
|
||||
fn format_numbered_vars(&mut self, iter: &mut HCPreOrderIterator) -> bool
|
||||
{
|
||||
fn format_numbered_vars(&mut self, iter: &mut HCPreOrderIterator) -> bool {
|
||||
let addr = iter.stack().last().cloned().unwrap();
|
||||
|
||||
// 7.10.4
|
||||
@@ -547,8 +565,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
|
||||
false
|
||||
}
|
||||
|
||||
fn format_clause(&mut self, iter: &mut HCPreOrderIterator, arity: usize, ct: ClauseType)
|
||||
{
|
||||
fn format_clause(&mut self, iter: &mut HCPreOrderIterator, arity: usize, ct: ClauseType) {
|
||||
if self.numbervars && is_numbered_var(&ct, arity) {
|
||||
if self.format_numbered_vars(iter) {
|
||||
return;
|
||||
@@ -570,7 +587,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
|
||||
|
||||
match (ct.name().as_str(), arity) {
|
||||
("{}", 1) if !self.ignore_ops => self.format_curly_braces(),
|
||||
_ => self.format_struct(arity, ct.name())
|
||||
_ => self.format_struct(arity, ct.name()),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -586,8 +603,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
|
||||
self.outputter.append(s);
|
||||
}
|
||||
|
||||
fn offset_as_string(&self, iter: &mut HCPreOrderIterator, addr: Addr) -> Option<String>
|
||||
{
|
||||
fn offset_as_string(&self, iter: &mut HCPreOrderIterator, addr: Addr) -> Option<String> {
|
||||
if let Some(var) = self.var_names.get(&addr) {
|
||||
if addr.as_var().is_some() {
|
||||
return Some(format!("{}", var));
|
||||
@@ -598,55 +614,56 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
|
||||
}
|
||||
|
||||
match addr {
|
||||
Addr::AttrVar(h) =>
|
||||
Some(format!("_{}", h + 1)),
|
||||
Addr::HeapCell(h) | Addr::Lis(h) | Addr::Str(h) =>
|
||||
Some(format!("_{}", h)),
|
||||
Addr::StackCell(fr, sc) =>
|
||||
Some(format!("_s_{}_{}", fr, sc)),
|
||||
_ => None
|
||||
Addr::AttrVar(h) => Some(format!("_{}", h + 1)),
|
||||
Addr::HeapCell(h) | Addr::Lis(h) | Addr::Str(h) => Some(format!("_{}", h)),
|
||||
Addr::StackCell(fr, sc) => Some(format!("_s_{}_{}", fr, sc)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn check_for_seen(&mut self, iter: &mut HCPreOrderIterator) -> Option<HeapCellValue>
|
||||
{
|
||||
fn check_for_seen(&mut self, iter: &mut HCPreOrderIterator) -> Option<HeapCellValue> {
|
||||
iter.stack().last().cloned().and_then(|addr| {
|
||||
let addr = self.machine_st.store(self.machine_st.deref(addr));
|
||||
|
||||
match self.heap_locs.get(&addr).cloned() {
|
||||
Some(var) => if !self.printed_vars.contains(&addr) {
|
||||
self.printed_vars.insert(addr);
|
||||
return iter.next();
|
||||
} else {
|
||||
iter.stack().pop();
|
||||
push_space_if_amb!(self, &var, {
|
||||
self.append_str(&var);
|
||||
});
|
||||
Some(var) => {
|
||||
if !self.printed_vars.contains(&addr) {
|
||||
self.printed_vars.insert(addr);
|
||||
return iter.next();
|
||||
} else {
|
||||
iter.stack().pop();
|
||||
push_space_if_amb!(self, &var, {
|
||||
self.append_str(&var);
|
||||
});
|
||||
|
||||
return None;
|
||||
},
|
||||
None => if self.machine_st.is_cyclic_term(addr.clone()) {
|
||||
match self.cyclic_terms.get(&addr).cloned() {
|
||||
Some(reps) =>
|
||||
if reps > 0 {
|
||||
self.cyclic_terms.insert(addr, reps - 1);
|
||||
iter.next()
|
||||
} else {
|
||||
push_space_if_amb!(self, "...", {
|
||||
self.append_str("...");
|
||||
});
|
||||
|
||||
iter.stack().pop();
|
||||
self.cyclic_terms.remove(&addr);
|
||||
None
|
||||
},
|
||||
None => {
|
||||
self.cyclic_terms.insert(addr, 2);
|
||||
iter.next()
|
||||
}
|
||||
return None;
|
||||
}
|
||||
}
|
||||
None => {
|
||||
if self.machine_st.is_cyclic_term(addr.clone()) {
|
||||
match self.cyclic_terms.get(&addr).cloned() {
|
||||
Some(reps) => {
|
||||
if reps > 0 {
|
||||
self.cyclic_terms.insert(addr, reps - 1);
|
||||
iter.next()
|
||||
} else {
|
||||
push_space_if_amb!(self, "...", {
|
||||
self.append_str("...");
|
||||
});
|
||||
|
||||
iter.stack().pop();
|
||||
self.cyclic_terms.remove(&addr);
|
||||
None
|
||||
}
|
||||
}
|
||||
None => {
|
||||
self.cyclic_terms.insert(addr, 2);
|
||||
iter.next()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
iter.next()
|
||||
}
|
||||
} else {
|
||||
iter.next()
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -708,7 +725,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
|
||||
}
|
||||
|
||||
match n {
|
||||
Number::Float(fl) =>
|
||||
Number::Float(fl) => {
|
||||
if &fl == &OrderedFloat(0f64) {
|
||||
push_space_if_amb!(self, "0", {
|
||||
self.append_str("0");
|
||||
@@ -720,7 +737,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
|
||||
push_space_if_amb!(self, &output_str, {
|
||||
self.append_str(&output_str.trim());
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
n => {
|
||||
let output_str = format!("{}", n);
|
||||
|
||||
@@ -737,7 +755,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
|
||||
|
||||
fn print_constant(&mut self, c: Constant, op: &Option<DirectedOp>) {
|
||||
match c {
|
||||
Constant::Atom(atom, spec) =>
|
||||
Constant::Atom(atom, spec) => {
|
||||
if let Some(_) = fetch_atom_op_spec(atom.clone(), spec, self.op_dir) {
|
||||
let mut result = String::new();
|
||||
|
||||
@@ -762,14 +780,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
|
||||
push_space_if_amb!(self, atom.as_str(), {
|
||||
self.print_atom(&atom);
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
Constant::Char(c) if non_quoted_token(once(c)) => {
|
||||
let c = char_to_string(c);
|
||||
|
||||
push_space_if_amb!(self, &c, {
|
||||
self.append_str(c.as_str());
|
||||
});
|
||||
},
|
||||
}
|
||||
Constant::Char(c) => {
|
||||
let mut result = String::new();
|
||||
|
||||
@@ -784,27 +803,20 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
|
||||
push_space_if_amb!(self, &result, {
|
||||
self.append_str(result.as_str());
|
||||
});
|
||||
},
|
||||
Constant::CharCode(c) =>
|
||||
self.append_str(&format!("{}", c)),
|
||||
Constant::EmptyList =>
|
||||
self.append_str("[]"),
|
||||
Constant::Integer(n) =>
|
||||
self.print_number(Number::Integer(n), op),
|
||||
Constant::Float(n) =>
|
||||
self.print_number(Number::Float(n), op),
|
||||
Constant::Rational(n) =>
|
||||
self.print_number(Number::Rational(n), op),
|
||||
Constant::String(s) =>
|
||||
self.print_string(s),
|
||||
Constant::Usize(i) =>
|
||||
self.append_str(&format!("u{}", i))
|
||||
}
|
||||
Constant::CharCode(c) => self.append_str(&format!("{}", c)),
|
||||
Constant::EmptyList => self.append_str("[]"),
|
||||
Constant::Integer(n) => self.print_number(Number::Integer(n), op),
|
||||
Constant::Float(n) => self.print_number(Number::Float(n), op),
|
||||
Constant::Rational(n) => self.print_number(Number::Rational(n), op),
|
||||
Constant::String(s) => self.print_string(s),
|
||||
Constant::Usize(i) => self.append_str(&format!("u{}", i)),
|
||||
}
|
||||
}
|
||||
|
||||
fn print_string(&mut self, s: StringList) {
|
||||
match self.machine_st.machine_flags().double_quotes {
|
||||
DoubleQuotes::Chars | DoubleQuotes::Codes =>
|
||||
DoubleQuotes::Chars | DoubleQuotes::Codes => {
|
||||
if !s.is_empty() {
|
||||
if self.ignore_ops {
|
||||
self.format_struct(2, clause_name!("."));
|
||||
@@ -817,12 +829,13 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
|
||||
}
|
||||
} else if !self.at_cdr("") {
|
||||
self.append_str("[]");
|
||||
},
|
||||
}
|
||||
}
|
||||
DoubleQuotes::Atom => {
|
||||
let borrowed_str = s.borrow();
|
||||
let mut atom = String::new();
|
||||
|
||||
for c in borrowed_str[s.cursor() ..].chars() {
|
||||
for c in borrowed_str[s.cursor()..].chars() {
|
||||
atom += &char_to_string(c);
|
||||
}
|
||||
|
||||
@@ -836,7 +849,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
|
||||
fn push_list(&mut self) {
|
||||
let cell = Rc::new(Cell::new(true));
|
||||
|
||||
self.state_stack.push(TokenOrRedirect::CloseList(cell.clone()));
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::CloseList(cell.clone()));
|
||||
|
||||
self.state_stack.push(TokenOrRedirect::FunctorRedirect);
|
||||
self.state_stack.push(TokenOrRedirect::HeadTailSeparator); // bar
|
||||
@@ -845,27 +859,32 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
|
||||
self.state_stack.push(TokenOrRedirect::OpenList(cell));
|
||||
}
|
||||
|
||||
fn handle_op_as_struct(&mut self, name: ClauseName, arity: usize, iter: &mut HCPreOrderIterator,
|
||||
op: &Option<DirectedOp>, is_functor_redirect: bool, spec: SharedOpDesc,
|
||||
negated_operand: bool)
|
||||
{
|
||||
fn handle_op_as_struct(
|
||||
&mut self,
|
||||
name: ClauseName,
|
||||
arity: usize,
|
||||
iter: &mut HCPreOrderIterator,
|
||||
op: &Option<DirectedOp>,
|
||||
is_functor_redirect: bool,
|
||||
spec: SharedOpDesc,
|
||||
negated_operand: bool,
|
||||
) {
|
||||
let add_brackets = if !self.ignore_ops {
|
||||
negated_operand || if let Some(ref op) = op {
|
||||
if self.numbervars && arity == 1 && name.as_str() == "$VAR" {
|
||||
!iter.immediate_leaf_has_property(|c| {
|
||||
match c {
|
||||
negated_operand
|
||||
|| if let Some(ref op) = op {
|
||||
if self.numbervars && arity == 1 && name.as_str() == "$VAR" {
|
||||
!iter.immediate_leaf_has_property(|c| match c {
|
||||
Constant::Integer(n) => n >= 0,
|
||||
Constant::Float(f) => f >= OrderedFloat(0f64),
|
||||
Constant::Rational(r) => r >= 0,
|
||||
_ => false
|
||||
}
|
||||
}) && needs_bracketing(&spec, op)
|
||||
_ => false,
|
||||
}) && needs_bracketing(&spec, op)
|
||||
} else {
|
||||
needs_bracketing(&spec, op)
|
||||
}
|
||||
} else {
|
||||
needs_bracketing(&spec, op)
|
||||
is_functor_redirect && spec.prec() >= 1000
|
||||
}
|
||||
} else {
|
||||
is_functor_redirect && spec.prec() >= 1000
|
||||
}
|
||||
} else {
|
||||
false
|
||||
};
|
||||
@@ -888,46 +907,58 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn handle_heap_term(&mut self, iter: &mut HCPreOrderIterator, op: Option<DirectedOp>,
|
||||
is_functor_redirect: bool)
|
||||
{
|
||||
fn handle_heap_term(
|
||||
&mut self,
|
||||
iter: &mut HCPreOrderIterator,
|
||||
op: Option<DirectedOp>,
|
||||
is_functor_redirect: bool,
|
||||
) {
|
||||
let negated_operand = negated_op_needs_bracketing(iter, &op);
|
||||
|
||||
let heap_val = match self.check_for_seen(iter) {
|
||||
Some(heap_val) => heap_val,
|
||||
None => return
|
||||
None => return,
|
||||
};
|
||||
|
||||
match heap_val {
|
||||
HeapCellValue::NamedStr(arity, name, spec) =>
|
||||
HeapCellValue::NamedStr(arity, name, spec) => {
|
||||
if let Some(spec) = fetch_op_spec(name.clone(), arity, spec.clone(), self.op_dir) {
|
||||
self.handle_op_as_struct(name, arity, iter, &op, is_functor_redirect, spec,
|
||||
negated_operand);
|
||||
self.handle_op_as_struct(
|
||||
name,
|
||||
arity,
|
||||
iter,
|
||||
&op,
|
||||
is_functor_redirect,
|
||||
spec,
|
||||
negated_operand,
|
||||
);
|
||||
} else {
|
||||
push_space_if_amb!(self, name.as_str(), {
|
||||
let ct = ClauseType::from(name, arity, spec);
|
||||
self.format_clause(iter, arity, ct);
|
||||
});
|
||||
},
|
||||
HeapCellValue::Addr(Addr::Con(Constant::EmptyList)) =>
|
||||
}
|
||||
}
|
||||
HeapCellValue::Addr(Addr::Con(Constant::EmptyList)) => {
|
||||
if !self.at_cdr("") {
|
||||
self.append_str("[]");
|
||||
},
|
||||
HeapCellValue::Addr(Addr::Con(c)) =>
|
||||
self.print_constant(c, &op),
|
||||
HeapCellValue::Addr(Addr::Lis(_)) =>
|
||||
}
|
||||
}
|
||||
HeapCellValue::Addr(Addr::Con(c)) => self.print_constant(c, &op),
|
||||
HeapCellValue::Addr(Addr::Lis(_)) => {
|
||||
if self.ignore_ops {
|
||||
self.format_struct(2, clause_name!("."));
|
||||
} else {
|
||||
self.push_list();
|
||||
},
|
||||
HeapCellValue::Addr(addr) =>
|
||||
}
|
||||
}
|
||||
HeapCellValue::Addr(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());
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -950,40 +981,34 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
|
||||
loop {
|
||||
if let Some(loc_data) = self.state_stack.pop() {
|
||||
match loc_data {
|
||||
TokenOrRedirect::Atom(atom) =>
|
||||
self.print_atom(&atom),
|
||||
TokenOrRedirect::Op(atom, _) =>
|
||||
self.print_op(atom.as_str()),
|
||||
TokenOrRedirect::NumberedVar(num_var) =>
|
||||
self.append_str(num_var.as_str()),
|
||||
TokenOrRedirect::CompositeRedirect(op) =>
|
||||
self.handle_heap_term(&mut iter, Some(op), false),
|
||||
TokenOrRedirect::FunctorRedirect =>
|
||||
self.handle_heap_term(&mut iter, None, true),
|
||||
TokenOrRedirect::Close =>
|
||||
self.push_char(')'),
|
||||
TokenOrRedirect::Open =>
|
||||
self.push_char('('),
|
||||
TokenOrRedirect::OpenList(delimit) =>
|
||||
TokenOrRedirect::Atom(atom) => self.print_atom(&atom),
|
||||
TokenOrRedirect::Op(atom, _) => self.print_op(atom.as_str()),
|
||||
TokenOrRedirect::NumberedVar(num_var) => self.append_str(num_var.as_str()),
|
||||
TokenOrRedirect::CompositeRedirect(op) => {
|
||||
self.handle_heap_term(&mut iter, Some(op), false)
|
||||
}
|
||||
TokenOrRedirect::FunctorRedirect => {
|
||||
self.handle_heap_term(&mut iter, None, true)
|
||||
}
|
||||
TokenOrRedirect::Close => self.push_char(')'),
|
||||
TokenOrRedirect::Open => self.push_char('('),
|
||||
TokenOrRedirect::OpenList(delimit) => {
|
||||
if !self.at_cdr(",") {
|
||||
self.push_char('[');
|
||||
} else {
|
||||
delimit.set(false);
|
||||
},
|
||||
TokenOrRedirect::CloseList(delimit) =>
|
||||
}
|
||||
}
|
||||
TokenOrRedirect::CloseList(delimit) => {
|
||||
if delimit.get() {
|
||||
self.push_char(']');
|
||||
},
|
||||
TokenOrRedirect::HeadTailSeparator =>
|
||||
self.append_str("|"),
|
||||
TokenOrRedirect::Comma =>
|
||||
self.append_str(","),
|
||||
TokenOrRedirect::Space =>
|
||||
self.push_char(' '),
|
||||
TokenOrRedirect::LeftCurly =>
|
||||
self.push_char('{'),
|
||||
TokenOrRedirect::RightCurly =>
|
||||
self.push_char('}'),
|
||||
}
|
||||
}
|
||||
TokenOrRedirect::HeadTailSeparator => self.append_str("|"),
|
||||
TokenOrRedirect::Comma => self.append_str(","),
|
||||
TokenOrRedirect::Space => self.push_char(' '),
|
||||
TokenOrRedirect::LeftCurly => self.push_char('{'),
|
||||
TokenOrRedirect::RightCurly => self.push_char('}'),
|
||||
}
|
||||
} else if !iter.stack().is_empty() {
|
||||
let spec = self.toplevel_spec.take();
|
||||
|
||||
Reference in New Issue
Block a user