Skip to content

Commit

Permalink
Split up pretty_print and print.
Browse files Browse the repository at this point in the history
`pretty_print` takes a `Token` and `match`es on it. But the particular
`Token` kind is known at each call site, so this commit splits it into
five functions: `pretty_print_eof`, `pretty_print_begin`, etc.

This commit also does likewise with `print`, though there is one
callsite for `print` where the `Token` kind isn't known, so a generic
`print` has to stay (but it now just calls out to the various `print_*`
functions).
  • Loading branch information
nnethercote committed Nov 29, 2018
1 parent 787959c commit 64cd645
Showing 1 changed file with 152 additions and 150 deletions.
302 changes: 152 additions & 150 deletions src/libsyntax/print/pp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,9 @@
//! calculation, SCAN will write "infinity" to the size and let PRINT consume
//! it.
//!
//! In this implementation (following the paper, again) the SCAN process is
//! the method called `Printer::pretty_print`, and the 'PRINT' process is the method
//! called `Printer::print`.
//! In this implementation (following the paper, again) the SCAN process is the
//! methods called `Printer::pretty_print_*`, and the 'PRINT' process is the
//! method called `Printer::print`.

use std::collections::VecDeque;
use std::fmt;
Expand Down Expand Up @@ -319,78 +319,77 @@ impl<'a> Printer<'a> {
self.buf[self.right].token = t;
}

pub fn pretty_print(&mut self, token: Token) -> io::Result<()> {
debug!("pp Vec<{},{}>", self.left, self.right);
match token {
Token::Eof => {
if !self.scan_stack.is_empty() {
self.check_stack(0);
self.advance_left()?;
}
self.indent(0);
Ok(())
}
Token::Begin(b) => {
if self.scan_stack.is_empty() {
self.left_total = 1;
self.right_total = 1;
self.left = 0;
self.right = 0;
} else {
self.advance_right();
}
debug!("pp Begin({})/buffer Vec<{},{}>",
b.offset, self.left, self.right);
self.buf[self.right] = BufEntry { token: token, size: -self.right_total };
let right = self.right;
self.scan_push(right);
Ok(())
}
Token::End => {
if self.scan_stack.is_empty() {
debug!("pp End/print Vec<{},{}>", self.left, self.right);
self.print(token, 0)
} else {
debug!("pp End/buffer Vec<{},{}>", self.left, self.right);
self.advance_right();
self.buf[self.right] = BufEntry { token: token, size: -1 };
let right = self.right;
self.scan_push(right);
Ok(())
}
}
Token::Break(b) => {
if self.scan_stack.is_empty() {
self.left_total = 1;
self.right_total = 1;
self.left = 0;
self.right = 0;
} else {
self.advance_right();
}
debug!("pp Break({})/buffer Vec<{},{}>",
b.offset, self.left, self.right);
self.check_stack(0);
let right = self.right;
self.scan_push(right);
self.buf[self.right] = BufEntry { token: token, size: -self.right_total };
self.right_total += b.blank_space;
Ok(())
}
Token::String(s, len) => {
if self.scan_stack.is_empty() {
debug!("pp String('{}')/print Vec<{},{}>",
s, self.left, self.right);
self.print(Token::String(s, len), len)
} else {
debug!("pp String('{}')/buffer Vec<{},{}>",
s, self.left, self.right);
self.advance_right();
self.buf[self.right] = BufEntry { token: Token::String(s, len), size: len };
self.right_total += len;
self.check_stream()
}
}
fn pretty_print_eof(&mut self) -> io::Result<()> {
if !self.scan_stack.is_empty() {
self.check_stack(0);
self.advance_left()?;
}
self.indent(0);
Ok(())
}

fn pretty_print_begin(&mut self, b: BeginToken) -> io::Result<()> {
if self.scan_stack.is_empty() {
self.left_total = 1;
self.right_total = 1;
self.left = 0;
self.right = 0;
} else {
self.advance_right();
}
debug!("pp Begin({})/buffer Vec<{},{}>",
b.offset, self.left, self.right);
self.buf[self.right] = BufEntry { token: Token::Begin(b), size: -self.right_total };
let right = self.right;
self.scan_push(right);
Ok(())
}

fn pretty_print_end(&mut self) -> io::Result<()> {
if self.scan_stack.is_empty() {
debug!("pp End/print Vec<{},{}>", self.left, self.right);
self.print_end()
} else {
debug!("pp End/buffer Vec<{},{}>", self.left, self.right);
self.advance_right();
self.buf[self.right] = BufEntry { token: Token::End, size: -1 };
let right = self.right;
self.scan_push(right);
Ok(())
}
}

fn pretty_print_break(&mut self, b: BreakToken) -> io::Result<()> {
if self.scan_stack.is_empty() {
self.left_total = 1;
self.right_total = 1;
self.left = 0;
self.right = 0;
} else {
self.advance_right();
}
debug!("pp Break({})/buffer Vec<{},{}>",
b.offset, self.left, self.right);
self.check_stack(0);
let right = self.right;
self.scan_push(right);
self.buf[self.right] = BufEntry { token: Token::Break(b), size: -self.right_total };
self.right_total += b.blank_space;
Ok(())
}

fn pretty_print_string(&mut self, s: Cow<'static, str>, len: isize) -> io::Result<()> {
if self.scan_stack.is_empty() {
debug!("pp String('{}')/print Vec<{},{}>",
s, self.left, self.right);
self.print_string(s, len)
} else {
debug!("pp String('{}')/buffer Vec<{},{}>",
s, self.left, self.right);
self.advance_right();
self.buf[self.right] = BufEntry { token: Token::String(s, len), size: len };
self.right_total += len;
self.check_stream()
}
}

Expand Down Expand Up @@ -526,7 +525,70 @@ impl<'a> Printer<'a> {
}
}

pub fn print_str(&mut self, s: &str) -> io::Result<()> {
pub fn print_begin(&mut self, b: BeginToken, l: isize) -> io::Result<()> {
if l > self.space {
let col = self.margin - self.space + b.offset;
debug!("print Begin -> push broken block at col {}", col);
self.print_stack.push(PrintStackElem {
offset: col,
pbreak: PrintStackBreak::Broken(b.breaks)
});
} else {
debug!("print Begin -> push fitting block");
self.print_stack.push(PrintStackElem {
offset: 0,
pbreak: PrintStackBreak::Fits
});
}
Ok(())
}

pub fn print_end(&mut self) -> io::Result<()> {
debug!("print End -> pop End");
let print_stack = &mut self.print_stack;
assert!(!print_stack.is_empty());
print_stack.pop().unwrap();
Ok(())
}

pub fn print_break(&mut self, b: BreakToken, l: isize) -> io::Result<()> {
let top = self.get_top();
match top.pbreak {
PrintStackBreak::Fits => {
debug!("print Break({}) in fitting block", b.blank_space);
self.space -= b.blank_space;
self.indent(b.blank_space);
Ok(())
}
PrintStackBreak::Broken(Breaks::Consistent) => {
debug!("print Break({}+{}) in consistent block",
top.offset, b.offset);
let ret = self.print_newline(top.offset + b.offset);
self.space = self.margin - (top.offset + b.offset);
ret
}
PrintStackBreak::Broken(Breaks::Inconsistent) => {
if l > self.space {
debug!("print Break({}+{}) w/ newline in inconsistent",
top.offset, b.offset);
let ret = self.print_newline(top.offset + b.offset);
self.space = self.margin - (top.offset + b.offset);
ret
} else {
debug!("print Break({}) w/o newline in inconsistent",
b.blank_space);
self.indent(b.blank_space);
self.space -= b.blank_space;
Ok(())
}
}
}
}

pub fn print_string(&mut self, s: Cow<'static, str>, len: isize) -> io::Result<()> {
debug!("print String({})", s);
// assert!(len <= space);
self.space -= len;
while self.pending_indentation > 0 {
write!(self.out, " ")?;
self.pending_indentation -= 1;
Expand All @@ -542,85 +604,25 @@ impl<'a> Printer<'a> {
self.right,
6));
match token {
Token::Begin(b) => {
if l > self.space {
let col = self.margin - self.space + b.offset;
debug!("print Begin -> push broken block at col {}", col);
self.print_stack.push(PrintStackElem {
offset: col,
pbreak: PrintStackBreak::Broken(b.breaks)
});
} else {
debug!("print Begin -> push fitting block");
self.print_stack.push(PrintStackElem {
offset: 0,
pbreak: PrintStackBreak::Fits
});
}
Ok(())
}
Token::End => {
debug!("print End -> pop End");
let print_stack = &mut self.print_stack;
assert!(!print_stack.is_empty());
print_stack.pop().unwrap();
Ok(())
}
Token::Break(b) => {
let top = self.get_top();
match top.pbreak {
PrintStackBreak::Fits => {
debug!("print Break({}) in fitting block", b.blank_space);
self.space -= b.blank_space;
self.indent(b.blank_space);
Ok(())
}
PrintStackBreak::Broken(Breaks::Consistent) => {
debug!("print Break({}+{}) in consistent block",
top.offset, b.offset);
let ret = self.print_newline(top.offset + b.offset);
self.space = self.margin - (top.offset + b.offset);
ret
}
PrintStackBreak::Broken(Breaks::Inconsistent) => {
if l > self.space {
debug!("print Break({}+{}) w/ newline in inconsistent",
top.offset, b.offset);
let ret = self.print_newline(top.offset + b.offset);
self.space = self.margin - (top.offset + b.offset);
ret
} else {
debug!("print Break({}) w/o newline in inconsistent",
b.blank_space);
self.indent(b.blank_space);
self.space -= b.blank_space;
Ok(())
}
}
}
}
Token::String(ref s, len) => {
debug!("print String({})", s);
assert_eq!(l, len);
// assert!(l <= space);
self.space -= len;
self.print_str(s)
}
Token::Eof => {
// Eof should never get here.
panic!();
Token::Begin(b) => self.print_begin(b, l),
Token::End => self.print_end(),
Token::Break(b) => self.print_break(b, l),
Token::String(s, len) => {
assert_eq!(len, l);
self.print_string(s, len)
}
Token::Eof => panic!(), // Eof should never get here.
}
}

// Convenience functions to talk to the printer.

/// "raw box"
pub fn rbox(&mut self, indent: usize, b: Breaks) -> io::Result<()> {
self.pretty_print(Token::Begin(BeginToken {
self.pretty_print_begin(BeginToken {
offset: indent as isize,
breaks: b
}))
})
}

/// Inconsistent breaking box
Expand All @@ -634,24 +636,24 @@ impl<'a> Printer<'a> {
}

pub fn break_offset(&mut self, n: usize, off: isize) -> io::Result<()> {
self.pretty_print(Token::Break(BreakToken {
self.pretty_print_break(BreakToken {
offset: off,
blank_space: n as isize
}))
})
}

pub fn end(&mut self) -> io::Result<()> {
self.pretty_print(Token::End)
self.pretty_print_end()
}

pub fn eof(&mut self) -> io::Result<()> {
self.pretty_print(Token::Eof)
self.pretty_print_eof()
}

pub fn word<S: Into<Cow<'static, str>>>(&mut self, wrd: S) -> io::Result<()> {
let s = wrd.into();
let len = s.len() as isize;
self.pretty_print(Token::String(s, len))
self.pretty_print_string(s, len)
}

fn spaces(&mut self, n: usize) -> io::Result<()> {
Expand Down

0 comments on commit 64cd645

Please sign in to comment.