state_stack: Vec<TokenOrRedirect>,
toplevel_spec: Option<DirectedOp>,
last_item_idx: usize,
- num_ops_on_stack: usize,
parent_of_first_op: Option<(DirectedOp, usize)>,
pub var_names: IndexMap<HeapCellValue, VarPtr>,
pub numbervars_offset: Integer,
state_stack: vec![],
toplevel_spec: None,
last_item_idx: 0,
- num_ops_on_stack: 0,
parent_of_first_op: None,
numbervars: false,
numbervars_offset: Integer::from(0),
}
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 self.max_depth_exhausted(max_depth) {
self.iter.pop_stack();
self.state_stack.push(TokenOrRedirect::Atom(atom!("...")));
- return;
} else if self.check_max_depth(&mut max_depth) {
self.iter.pop_stack();
self.iter.pop_stack();
self.state_stack.push(TokenOrRedirect::Atom(atom!("...")));
- return;
} else if self.check_max_depth(&mut max_depth) {
self.iter.pop_stack();
self.iter.pop_stack();
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 {
arity: usize,
name: Atom,
op_desc: Option<OpDesc>,
- parent_op: Option<DirectedOp>,
) -> bool {
if self.numbervars && is_numbered_var(name, arity) {
if self.format_numbered_vars() {
}
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;
}
}
right_directed_op,
));
- self.num_ops_on_stack += 1;
self.set_parent_of_first_op(parent_op);
} else {
self.state_stack.push(TokenOrRedirect::Close);
if add_brackets {
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);
- let parent_op = self.parent_of_first_op
- .and_then(|(parent_op, last_item_idx)| {
- // if parent_op isn't printed to the output string
- // already, then it doesn't border the present op
- // and we should return None.
- if self.last_item_idx == last_item_idx {
- Some(parent_op)
- } else {
- None
- }
- });
+ if !self.outputter.ends_with(" ") {
+ let parent_op = self.parent_of_first_op
+ .and_then(|(parent_op, last_item_idx)| {
+ // if parent_op isn't printed to the output string
+ // already, then it doesn't border the present op
+ // and we should return None.
+ if self.last_item_idx == last_item_idx {
+ Some(parent_op)
+ } else {
+ None
+ }
+ });
- for op in &[op, parent_op] {
- if let Some(ref op) = &op {
- if !self.outputter.ends_with(" ") {
+ for op in &[op, parent_op] {
+ if let Some(ref op) = &op {
if op.is_left() && (op.is_prefix() || requires_space(op.as_atom().as_str(), "(")) {
self.state_stack.push(TokenOrRedirect::Space);
- break;
+ return;
}
}
}
}
} else {
- self.format_clause(max_depth, arity, name, Some(op_desc), op);
+ self.format_clause(max_depth, arity, name, Some(op_desc));
}
}
);
} else {
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 {
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);
});
}
}
TokenOrRedirect::Atom(atom) => self.print_impromptu_atom(atom),
TokenOrRedirect::BarAsOp => append_str!(self, " | "),
TokenOrRedirect::Char(c) => print_char!(self, self.quoted, c),
- TokenOrRedirect::Op(atom, ..) => {
- self.num_ops_on_stack -= 1;
- self.parent_of_first_op = None;
+ TokenOrRedirect::Op(atom, op) => {
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::CompositeRedirect(max_depth, op) => {
all_cells_unmarked(&wam.machine_st.heap);
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");
}
}