further max_depth improvements
This commit is contained in:
@@ -208,6 +208,15 @@ impl NumberFocus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
struct CommaSeparatedCharList {
|
||||||
|
pstr: PartialString,
|
||||||
|
offset: usize,
|
||||||
|
max_depth: usize,
|
||||||
|
end_cell: HeapCellValue,
|
||||||
|
end_h: Option<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
enum TokenOrRedirect {
|
enum TokenOrRedirect {
|
||||||
Atom(Atom),
|
Atom(Atom),
|
||||||
@@ -234,7 +243,7 @@ enum TokenOrRedirect {
|
|||||||
CloseList(Rc<Cell<(bool, usize)>>),
|
CloseList(Rc<Cell<(bool, usize)>>),
|
||||||
HeadTailSeparator,
|
HeadTailSeparator,
|
||||||
StackPop,
|
StackPop,
|
||||||
CommaSeparatedCharList { pstr: PartialString, offset: usize, num_chars: usize },
|
CommaSeparatedCharList(CommaSeparatedCharList),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn requires_space(atom: &str, op: &str) -> bool {
|
pub(crate) fn requires_space(atom: &str, op: &str) -> bool {
|
||||||
@@ -1115,10 +1124,19 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// returns true if max_depth limit is reached and ellipsis is printed.
|
// returns true if max_depth limit is reached and ellipsis is printed.
|
||||||
fn print_string_as_functor(&mut self, focus: usize, max_depth: usize) -> bool {
|
fn print_string_as_functor(&mut self, focus: usize, max_depth: &mut usize) -> bool {
|
||||||
let iter = HeapPStrIter::new(self.iter.heap, focus);
|
let iter = HeapPStrIter::new(self.iter.heap, focus);
|
||||||
|
|
||||||
for (char_count, c) in iter.chars().enumerate() {
|
for (char_count, c) in iter.chars().enumerate() {
|
||||||
|
if self.check_max_depth(max_depth) {
|
||||||
|
if char_count > 0 {
|
||||||
|
self.state_stack.push(TokenOrRedirect::Close);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.state_stack.push(TokenOrRedirect::Atom(atom!("...")));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
append_str!(self, "'.'");
|
append_str!(self, "'.'");
|
||||||
push_char!(self, '(');
|
push_char!(self, '(');
|
||||||
|
|
||||||
@@ -1126,16 +1144,13 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
push_char!(self, ',');
|
push_char!(self, ',');
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Close);
|
self.state_stack.push(TokenOrRedirect::Close);
|
||||||
|
|
||||||
if max_depth >= char_count + 1 {
|
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(atom!("...")));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// proper strings are terminal so there's no need for max_depth to
|
||||||
|
// be a mutable ref here.
|
||||||
fn print_proper_string(&mut self, focus: usize, max_depth: usize) {
|
fn print_proper_string(&mut self, focus: usize, max_depth: usize) {
|
||||||
push_char!(self, '"');
|
push_char!(self, '"');
|
||||||
|
|
||||||
@@ -1223,16 +1238,14 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
self.at_cdr(",");
|
self.at_cdr(",");
|
||||||
self.remove_list_children(focus.value() as usize);
|
self.remove_list_children(focus.value() as usize);
|
||||||
|
|
||||||
if !self.print_string_as_functor(focus.value() as usize, max_depth) {
|
if !self.print_string_as_functor(focus.value() as usize, &mut max_depth) {
|
||||||
if end_cell == empty_list_as_cell!() {
|
if end_cell == empty_list_as_cell!() {
|
||||||
if !self.at_cdr("") {
|
if !self.at_cdr("") {
|
||||||
append_str!(self, "[]");
|
append_str!(self, "[]");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.state_stack
|
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||||
.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
self.iter.push_stack(IterStackLoc::iterable_loc(end_h, HeapOrStackTag::Heap));
|
||||||
self.iter
|
|
||||||
.push_stack(IterStackLoc::iterable_loc(end_h, HeapOrStackTag::Heap));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -1250,63 +1263,27 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
let switch = self.close_list(switch);
|
let switch = self.close_list(switch);
|
||||||
|
|
||||||
let (h, offset) = pstr_loc_and_offset(self.iter.heap, focus.value() as usize);
|
let (h, offset) = pstr_loc_and_offset(self.iter.heap, focus.value() as usize);
|
||||||
let pstr = cell_as_string!(self.iter.heap[h]);
|
|
||||||
|
|
||||||
let offset = offset.get_num() as usize;
|
let offset = offset.get_num() as usize;
|
||||||
let pstr = pstr.as_str_from(offset);
|
|
||||||
let tag = value.get_tag();
|
let tag = value.get_tag();
|
||||||
|
|
||||||
if tag == HeapCellValueTag::PStrOffset {
|
let end_h = if tag == HeapCellValueTag::PStrOffset {
|
||||||
// remove the fixnum offset from the iterator stack so we don't
|
// remove the fixnum offset from the iterator stack so we don't
|
||||||
// print an extraneous number. pstr offset value cells are never
|
// print an extraneous number. pstr offset value cells are never
|
||||||
// used by the iterator to mark cyclic terms so the removal is safe.
|
// used by the iterator to mark cyclic terms so the removal is safe.
|
||||||
self.iter.pop_stack();
|
self.iter.pop_stack();
|
||||||
}
|
Some(end_h)
|
||||||
|
} else {
|
||||||
let non_trivial_end_cell = end_cell != empty_list_as_cell!();
|
None
|
||||||
let non_trivial_end_cell_offset = non_trivial_end_cell as usize;
|
};
|
||||||
|
|
||||||
let list_depth = pstr.chars().count() + non_trivial_end_cell_offset;
|
|
||||||
|
|
||||||
if self.max_depth > 0 && list_depth >= max_depth {
|
|
||||||
if tag != HeapCellValueTag::PStrOffset && tag != HeapCellValueTag::CStr {
|
|
||||||
self.iter.pop_stack();
|
|
||||||
}
|
|
||||||
|
|
||||||
if list_depth > max_depth {
|
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(atom!("...")));
|
|
||||||
|
|
||||||
if !self.max_depth_exhausted(max_depth) {
|
|
||||||
self.state_stack.push(TokenOrRedirect::HeadTailSeparator);
|
|
||||||
}
|
|
||||||
} else if non_trivial_end_cell {
|
|
||||||
self.iter.push_stack(IterStackLoc::iterable_loc(end_h, HeapOrStackTag::Heap));
|
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::FunctorRedirect(1));
|
|
||||||
self.state_stack.push(TokenOrRedirect::HeadTailSeparator);
|
|
||||||
}
|
|
||||||
} else if non_trivial_end_cell {
|
|
||||||
if tag == HeapCellValueTag::PStrOffset {
|
|
||||||
self.iter.push_stack(IterStackLoc::iterable_loc(end_h, HeapOrStackTag::Heap));
|
|
||||||
}
|
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth.saturating_sub(list_depth - 1)));
|
|
||||||
self.state_stack.push(TokenOrRedirect::HeadTailSeparator);
|
|
||||||
}
|
|
||||||
|
|
||||||
if !self.max_depth_exhausted(max_depth) {
|
if !self.max_depth_exhausted(max_depth) {
|
||||||
let mut num_chars = 0;
|
|
||||||
|
|
||||||
for (char_count, _c) in pstr.chars().enumerate() {
|
|
||||||
num_chars += 1;
|
|
||||||
|
|
||||||
if self.max_depth > 0 && char_count + 1 >= max_depth {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let pstr = cell_as_string!(self.iter.heap[h]);
|
let pstr = cell_as_string!(self.iter.heap[h]);
|
||||||
self.state_stack.push(TokenOrRedirect::CommaSeparatedCharList { pstr, offset, num_chars });
|
self.state_stack.push(TokenOrRedirect::CommaSeparatedCharList(CommaSeparatedCharList {
|
||||||
|
pstr, offset, max_depth, end_cell, end_h,
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
self.state_stack.push(TokenOrRedirect::Atom(atom!("...")));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.open_list(switch);
|
self.open_list(switch);
|
||||||
@@ -1538,6 +1515,46 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn print_comma_separated_char_list(&mut self, char_list: CommaSeparatedCharList) {
|
||||||
|
let CommaSeparatedCharList { pstr, offset, max_depth, end_cell, end_h } = char_list;
|
||||||
|
let pstr_str = pstr.as_str_from(offset);
|
||||||
|
|
||||||
|
if let Some(c) = pstr_str.chars().next() {
|
||||||
|
let offset = offset + c.len_utf8();
|
||||||
|
|
||||||
|
if !self.max_depth_exhausted(max_depth) {
|
||||||
|
self.state_stack.push(TokenOrRedirect::CommaSeparatedCharList(CommaSeparatedCharList {
|
||||||
|
pstr,
|
||||||
|
offset,
|
||||||
|
max_depth: max_depth.saturating_sub(1),
|
||||||
|
end_cell,
|
||||||
|
end_h,
|
||||||
|
}));
|
||||||
|
|
||||||
|
let max_depth_allows = self.max_depth == 0 || max_depth > 1;
|
||||||
|
|
||||||
|
if max_depth_allows && pstr_str.chars().skip(1).next().is_some() {
|
||||||
|
self.state_stack.push(TokenOrRedirect::Comma);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.state_stack.push(TokenOrRedirect::Char(c));
|
||||||
|
} else {
|
||||||
|
self.state_stack.push(TokenOrRedirect::Atom(atom!("...")));
|
||||||
|
self.state_stack.push(TokenOrRedirect::HeadTailSeparator);
|
||||||
|
}
|
||||||
|
} else if self.max_depth_exhausted(max_depth) {
|
||||||
|
self.state_stack.push(TokenOrRedirect::Atom(atom!("...")));
|
||||||
|
self.state_stack.push(TokenOrRedirect::HeadTailSeparator);
|
||||||
|
} else if end_cell != empty_list_as_cell!() {
|
||||||
|
if let Some(end_h) = end_h {
|
||||||
|
self.iter.push_stack(IterStackLoc::iterable_loc(end_h, HeapOrStackTag::Heap));
|
||||||
|
}
|
||||||
|
|
||||||
|
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth + 1));
|
||||||
|
self.state_stack.push(TokenOrRedirect::HeadTailSeparator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_heap_term(
|
fn handle_heap_term(
|
||||||
&mut self,
|
&mut self,
|
||||||
op: Option<DirectedOp>,
|
op: Option<DirectedOp>,
|
||||||
@@ -1777,24 +1794,8 @@ 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!("...")));
|
||||||
}
|
}
|
||||||
TokenOrRedirect::CommaSeparatedCharList { pstr, offset, num_chars } => {
|
TokenOrRedirect::CommaSeparatedCharList(char_list) => {
|
||||||
let pstr_str = pstr.as_str_from(offset);
|
self.print_comma_separated_char_list(char_list);
|
||||||
|
|
||||||
if let Some(c) = pstr_str.chars().next() {
|
|
||||||
let offset = offset + c.len_utf8();
|
|
||||||
|
|
||||||
if num_chars > 1 {
|
|
||||||
self.state_stack.push(TokenOrRedirect::CommaSeparatedCharList {
|
|
||||||
pstr,
|
|
||||||
offset: offset,
|
|
||||||
num_chars: num_chars - 1,
|
|
||||||
});
|
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Comma);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Char(c));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user