This commit is contained in:
@@ -484,7 +484,6 @@ pub struct HCPrinter<'a, Outputter> {
|
|||||||
state_stack: Vec<TokenOrRedirect>,
|
state_stack: Vec<TokenOrRedirect>,
|
||||||
toplevel_spec: Option<DirectedOp>,
|
toplevel_spec: Option<DirectedOp>,
|
||||||
last_item_idx: usize,
|
last_item_idx: usize,
|
||||||
num_ops_on_stack: usize,
|
|
||||||
parent_of_first_op: Option<(DirectedOp, usize)>,
|
parent_of_first_op: Option<(DirectedOp, usize)>,
|
||||||
pub var_names: IndexMap<HeapCellValue, VarPtr>,
|
pub var_names: IndexMap<HeapCellValue, VarPtr>,
|
||||||
pub numbervars_offset: Integer,
|
pub numbervars_offset: Integer,
|
||||||
@@ -563,7 +562,6 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
state_stack: vec![],
|
state_stack: vec![],
|
||||||
toplevel_spec: None,
|
toplevel_spec: None,
|
||||||
last_item_idx: 0,
|
last_item_idx: 0,
|
||||||
num_ops_on_stack: 0,
|
|
||||||
parent_of_first_op: None,
|
parent_of_first_op: None,
|
||||||
numbervars: false,
|
numbervars: false,
|
||||||
numbervars_offset: Integer::from(0),
|
numbervars_offset: Integer::from(0),
|
||||||
@@ -588,15 +586,18 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn set_parent_of_first_op(&mut self, parent_op: Option<DirectedOp>) {
|
fn set_parent_of_first_op(&mut self, parent_op: Option<DirectedOp>) {
|
||||||
self.parent_of_first_op = parent_op.map(|op| (op, self.last_item_idx));
|
if let Some(op) = parent_op {
|
||||||
|
if op.is_left() && op.is_prefix() {
|
||||||
|
self.parent_of_first_op = Some((op, self.last_item_idx));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enqueue_op(&mut self, mut max_depth: usize, name: Atom, spec: OpDesc, parent_op: Option<DirectedOp>) {
|
fn enqueue_op(&mut self, mut max_depth: usize, name: Atom, spec: OpDesc) {
|
||||||
if is_postfix!(spec.get_spec()) {
|
if is_postfix!(spec.get_spec()) {
|
||||||
if self.max_depth_exhausted(max_depth) {
|
if self.max_depth_exhausted(max_depth) {
|
||||||
self.iter.pop_stack();
|
self.iter.pop_stack();
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(atom!("...")));
|
self.state_stack.push(TokenOrRedirect::Atom(atom!("...")));
|
||||||
return;
|
|
||||||
} else if self.check_max_depth(&mut max_depth) {
|
} else if self.check_max_depth(&mut max_depth) {
|
||||||
self.iter.pop_stack();
|
self.iter.pop_stack();
|
||||||
|
|
||||||
@@ -641,7 +642,6 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
self.iter.pop_stack();
|
self.iter.pop_stack();
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(atom!("...")));
|
self.state_stack.push(TokenOrRedirect::Atom(atom!("...")));
|
||||||
return;
|
|
||||||
} else if self.check_max_depth(&mut max_depth) {
|
} else if self.check_max_depth(&mut max_depth) {
|
||||||
self.iter.pop_stack();
|
self.iter.pop_stack();
|
||||||
self.iter.pop_stack();
|
self.iter.pop_stack();
|
||||||
@@ -658,12 +658,6 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
self.state_stack.push(TokenOrRedirect::CompositeRedirect(max_depth, right_directed_op));
|
self.state_stack.push(TokenOrRedirect::CompositeRedirect(max_depth, right_directed_op));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.num_ops_on_stack == 0 {
|
|
||||||
self.set_parent_of_first_op(parent_op);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.num_ops_on_stack += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn format_struct(&mut self, mut max_depth: usize, arity: usize, name: Atom) -> bool {
|
fn format_struct(&mut self, mut max_depth: usize, arity: usize, name: Atom) -> bool {
|
||||||
@@ -777,7 +771,6 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
arity: usize,
|
arity: usize,
|
||||||
name: Atom,
|
name: Atom,
|
||||||
op_desc: Option<OpDesc>,
|
op_desc: Option<OpDesc>,
|
||||||
parent_op: Option<DirectedOp>,
|
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if self.numbervars && is_numbered_var(name, arity) {
|
if self.numbervars && is_numbered_var(name, arity) {
|
||||||
if self.format_numbered_vars() {
|
if self.format_numbered_vars() {
|
||||||
@@ -796,7 +789,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !self.ignore_ops && spec.get_prec() > 0 {
|
if !self.ignore_ops && spec.get_prec() > 0 {
|
||||||
self.enqueue_op(max_depth, name, spec, parent_op);
|
self.enqueue_op(max_depth, name, spec);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1064,7 +1057,6 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
right_directed_op,
|
right_directed_op,
|
||||||
));
|
));
|
||||||
|
|
||||||
self.num_ops_on_stack += 1;
|
|
||||||
self.set_parent_of_first_op(parent_op);
|
self.set_parent_of_first_op(parent_op);
|
||||||
} else {
|
} else {
|
||||||
self.state_stack.push(TokenOrRedirect::Close);
|
self.state_stack.push(TokenOrRedirect::Close);
|
||||||
@@ -1385,33 +1377,33 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
|
|
||||||
if add_brackets {
|
if add_brackets {
|
||||||
self.state_stack.push(TokenOrRedirect::Close);
|
self.state_stack.push(TokenOrRedirect::Close);
|
||||||
self.format_clause(max_depth, arity, name, Some(op_desc), op);
|
self.format_clause(max_depth, arity, name, Some(op_desc));
|
||||||
self.state_stack.push(TokenOrRedirect::Open);
|
self.state_stack.push(TokenOrRedirect::Open);
|
||||||
|
|
||||||
let parent_op = self.parent_of_first_op
|
if !self.outputter.ends_with(" ") {
|
||||||
.and_then(|(parent_op, last_item_idx)| {
|
let parent_op = self.parent_of_first_op
|
||||||
// if parent_op isn't printed to the output string
|
.and_then(|(parent_op, last_item_idx)| {
|
||||||
// already, then it doesn't border the present op
|
// if parent_op isn't printed to the output string
|
||||||
// and we should return None.
|
// already, then it doesn't border the present op
|
||||||
if self.last_item_idx == last_item_idx {
|
// and we should return None.
|
||||||
Some(parent_op)
|
if self.last_item_idx == last_item_idx {
|
||||||
} else {
|
Some(parent_op)
|
||||||
None
|
} else {
|
||||||
}
|
None
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
|
||||||
for op in &[op, parent_op] {
|
for op in &[op, parent_op] {
|
||||||
if let Some(ref op) = &op {
|
if let Some(ref op) = &op {
|
||||||
if !self.outputter.ends_with(" ") {
|
|
||||||
if op.is_left() && (op.is_prefix() || requires_space(op.as_atom().as_str(), "(")) {
|
if op.is_left() && (op.is_prefix() || requires_space(op.as_atom().as_str(), "(")) {
|
||||||
self.state_stack.push(TokenOrRedirect::Space);
|
self.state_stack.push(TokenOrRedirect::Space);
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.format_clause(max_depth, arity, name, Some(op_desc), op);
|
self.format_clause(max_depth, arity, name, Some(op_desc));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1528,7 +1520,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
push_space_if_amb!(printer, name.as_str(), {
|
push_space_if_amb!(printer, name.as_str(), {
|
||||||
printer.format_clause(max_depth, arity, name, None, op);
|
printer.format_clause(max_depth, arity, name, None);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if fetch_op_spec(name, arity, printer.op_dir).is_some() {
|
} else if fetch_op_spec(name, arity, printer.op_dir).is_some() {
|
||||||
@@ -1594,7 +1586,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
push_space_if_amb!(self, name.as_str(), {
|
push_space_if_amb!(self, name.as_str(), {
|
||||||
self.format_clause(max_depth, arity, name, None, op);
|
self.format_clause(max_depth, arity, name, None);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1675,10 +1667,12 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
TokenOrRedirect::Atom(atom) => self.print_impromptu_atom(atom),
|
TokenOrRedirect::Atom(atom) => self.print_impromptu_atom(atom),
|
||||||
TokenOrRedirect::BarAsOp => append_str!(self, " | "),
|
TokenOrRedirect::BarAsOp => append_str!(self, " | "),
|
||||||
TokenOrRedirect::Char(c) => print_char!(self, self.quoted, c),
|
TokenOrRedirect::Char(c) => print_char!(self, self.quoted, c),
|
||||||
TokenOrRedirect::Op(atom, ..) => {
|
TokenOrRedirect::Op(atom, op) => {
|
||||||
self.num_ops_on_stack -= 1;
|
|
||||||
self.parent_of_first_op = None;
|
|
||||||
self.print_op(atom.as_str());
|
self.print_op(atom.as_str());
|
||||||
|
|
||||||
|
if is_prefix!(op.get_spec()) {
|
||||||
|
self.set_parent_of_first_op(Some(DirectedOp::Left(atom, op)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
TokenOrRedirect::NumberedVar(num_var) => append_str!(self, &num_var),
|
TokenOrRedirect::NumberedVar(num_var) => append_str!(self, &num_var),
|
||||||
TokenOrRedirect::CompositeRedirect(max_depth, op) => {
|
TokenOrRedirect::CompositeRedirect(max_depth, op) => {
|
||||||
@@ -2020,5 +2014,21 @@ mod tests {
|
|||||||
all_cells_unmarked(&wam.machine_st.heap);
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
assert_eq!(&wam.parse_and_print_term("[a|[b|c]*d].").unwrap(), "[a|[b|c]*d]");
|
assert_eq!(&wam.parse_and_print_term("[a|[b|c]*d].").unwrap(), "[a|[b|c]*d]");
|
||||||
|
|
||||||
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
|
wam.op_dir.insert(
|
||||||
|
(atom!("fy"), Fixity::Pre),
|
||||||
|
OpDesc::build_with(9, FY as u8),
|
||||||
|
);
|
||||||
|
|
||||||
|
wam.op_dir.insert(
|
||||||
|
(atom!("yf"), Fixity::Post),
|
||||||
|
OpDesc::build_with(9, YF as u8),
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(&wam.parse_and_print_term("(fy (fy 1)yf)yf.").unwrap(), "(fy (fy 1)yf)yf");
|
||||||
|
|
||||||
|
assert_eq!(&wam.parse_and_print_term("fy(fy(yf(fy(1)))).").unwrap(), "fy fy (fy 1)yf");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user