Rollup merge of #37065 - nnethercote:opt-mk_printer, r=nikomatsakis
Merge `Printer::token` and `Printer::size`. Logically, it's a vector of pairs, so might as well represent it that way. The commit also changes `scan_stack` so that it is initialized with the default size, instead of the excessive `55 * linewidth` size, which it usually doesn't get even close to reaching.
This commit is contained in:
commit
ffa9bbf7cd
@ -125,9 +125,8 @@ impl fmt::Display for Token {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn buf_str(toks: &[Token], szs: &[isize], left: usize, right: usize, lim: usize) -> String {
|
fn buf_str(buf: &[BufEntry], left: usize, right: usize, lim: usize) -> String {
|
||||||
let n = toks.len();
|
let n = buf.len();
|
||||||
assert_eq!(n, szs.len());
|
|
||||||
let mut i = left;
|
let mut i = left;
|
||||||
let mut l = lim;
|
let mut l = lim;
|
||||||
let mut s = String::from("[");
|
let mut s = String::from("[");
|
||||||
@ -136,7 +135,7 @@ fn buf_str(toks: &[Token], szs: &[isize], left: usize, right: usize, lim: usize)
|
|||||||
if i != left {
|
if i != left {
|
||||||
s.push_str(", ");
|
s.push_str(", ");
|
||||||
}
|
}
|
||||||
s.push_str(&format!("{}={}", szs[i], &toks[i]));
|
s.push_str(&format!("{}={}", buf[i].size, &buf[i].token));
|
||||||
i += 1;
|
i += 1;
|
||||||
i %= n;
|
i %= n;
|
||||||
}
|
}
|
||||||
@ -159,13 +158,9 @@ pub struct PrintStackElem {
|
|||||||
const SIZE_INFINITY: isize = 0xffff;
|
const SIZE_INFINITY: isize = 0xffff;
|
||||||
|
|
||||||
pub fn mk_printer<'a>(out: Box<io::Write+'a>, linewidth: usize) -> Printer<'a> {
|
pub fn mk_printer<'a>(out: Box<io::Write+'a>, linewidth: usize) -> Printer<'a> {
|
||||||
// Yes 55, it makes the ring buffers big enough to never
|
// Yes 55, it makes the ring buffers big enough to never fall behind.
|
||||||
// fall behind.
|
|
||||||
let n: usize = 55 * linewidth;
|
let n: usize = 55 * linewidth;
|
||||||
debug!("mk_printer {}", linewidth);
|
debug!("mk_printer {}", linewidth);
|
||||||
let token = vec![Token::Eof; n];
|
|
||||||
let size = vec![0; n];
|
|
||||||
let scan_stack = VecDeque::with_capacity(n);
|
|
||||||
Printer {
|
Printer {
|
||||||
out: out,
|
out: out,
|
||||||
buf_len: n,
|
buf_len: n,
|
||||||
@ -173,11 +168,10 @@ pub fn mk_printer<'a>(out: Box<io::Write+'a>, linewidth: usize) -> Printer<'a> {
|
|||||||
space: linewidth as isize,
|
space: linewidth as isize,
|
||||||
left: 0,
|
left: 0,
|
||||||
right: 0,
|
right: 0,
|
||||||
token: token,
|
buf: vec![BufEntry { token: Token::Eof, size: 0 }; n],
|
||||||
size: size,
|
|
||||||
left_total: 0,
|
left_total: 0,
|
||||||
right_total: 0,
|
right_total: 0,
|
||||||
scan_stack: scan_stack,
|
scan_stack: VecDeque::new(),
|
||||||
print_stack: Vec::new(),
|
print_stack: Vec::new(),
|
||||||
pending_indentation: 0
|
pending_indentation: 0
|
||||||
}
|
}
|
||||||
@ -269,10 +263,8 @@ pub struct Printer<'a> {
|
|||||||
left: usize,
|
left: usize,
|
||||||
/// Index of right side of input stream
|
/// Index of right side of input stream
|
||||||
right: usize,
|
right: usize,
|
||||||
/// Ring-buffer stream goes through
|
/// Ring-buffer of tokens and calculated sizes
|
||||||
token: Vec<Token> ,
|
buf: Vec<BufEntry>,
|
||||||
/// Ring-buffer of calculated sizes
|
|
||||||
size: Vec<isize> ,
|
|
||||||
/// Running size of stream "...left"
|
/// Running size of stream "...left"
|
||||||
left_total: isize,
|
left_total: isize,
|
||||||
/// Running size of stream "...right"
|
/// Running size of stream "...right"
|
||||||
@ -283,20 +275,26 @@ pub struct Printer<'a> {
|
|||||||
/// Begin (if there is any) on top of it. Stuff is flushed off the
|
/// Begin (if there is any) on top of it. Stuff is flushed off the
|
||||||
/// bottom as it becomes irrelevant due to the primary ring-buffer
|
/// bottom as it becomes irrelevant due to the primary ring-buffer
|
||||||
/// advancing.
|
/// advancing.
|
||||||
scan_stack: VecDeque<usize> ,
|
scan_stack: VecDeque<usize>,
|
||||||
/// Stack of blocks-in-progress being flushed by print
|
/// Stack of blocks-in-progress being flushed by print
|
||||||
print_stack: Vec<PrintStackElem> ,
|
print_stack: Vec<PrintStackElem> ,
|
||||||
/// Buffered indentation to avoid writing trailing whitespace
|
/// Buffered indentation to avoid writing trailing whitespace
|
||||||
pending_indentation: isize,
|
pending_indentation: isize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct BufEntry {
|
||||||
|
token: Token,
|
||||||
|
size: isize,
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> Printer<'a> {
|
impl<'a> Printer<'a> {
|
||||||
pub fn last_token(&mut self) -> Token {
|
pub fn last_token(&mut self) -> Token {
|
||||||
self.token[self.right].clone()
|
self.buf[self.right].token.clone()
|
||||||
}
|
}
|
||||||
// be very careful with this!
|
// be very careful with this!
|
||||||
pub fn replace_last_token(&mut self, t: Token) {
|
pub fn replace_last_token(&mut self, t: Token) {
|
||||||
self.token[self.right] = t;
|
self.buf[self.right].token = t;
|
||||||
}
|
}
|
||||||
pub fn pretty_print(&mut self, token: Token) -> io::Result<()> {
|
pub fn pretty_print(&mut self, token: Token) -> io::Result<()> {
|
||||||
debug!("pp Vec<{},{}>", self.left, self.right);
|
debug!("pp Vec<{},{}>", self.left, self.right);
|
||||||
@ -318,8 +316,7 @@ impl<'a> Printer<'a> {
|
|||||||
} else { self.advance_right(); }
|
} else { self.advance_right(); }
|
||||||
debug!("pp Begin({})/buffer Vec<{},{}>",
|
debug!("pp Begin({})/buffer Vec<{},{}>",
|
||||||
b.offset, self.left, self.right);
|
b.offset, self.left, self.right);
|
||||||
self.token[self.right] = token;
|
self.buf[self.right] = BufEntry { token: token, size: -self.right_total };
|
||||||
self.size[self.right] = -self.right_total;
|
|
||||||
let right = self.right;
|
let right = self.right;
|
||||||
self.scan_push(right);
|
self.scan_push(right);
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -331,8 +328,7 @@ impl<'a> Printer<'a> {
|
|||||||
} else {
|
} else {
|
||||||
debug!("pp End/buffer Vec<{},{}>", self.left, self.right);
|
debug!("pp End/buffer Vec<{},{}>", self.left, self.right);
|
||||||
self.advance_right();
|
self.advance_right();
|
||||||
self.token[self.right] = token;
|
self.buf[self.right] = BufEntry { token: token, size: -1 };
|
||||||
self.size[self.right] = -1;
|
|
||||||
let right = self.right;
|
let right = self.right;
|
||||||
self.scan_push(right);
|
self.scan_push(right);
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -350,8 +346,7 @@ impl<'a> Printer<'a> {
|
|||||||
self.check_stack(0);
|
self.check_stack(0);
|
||||||
let right = self.right;
|
let right = self.right;
|
||||||
self.scan_push(right);
|
self.scan_push(right);
|
||||||
self.token[self.right] = token;
|
self.buf[self.right] = BufEntry { token: token, size: -self.right_total };
|
||||||
self.size[self.right] = -self.right_total;
|
|
||||||
self.right_total += b.blank_space;
|
self.right_total += b.blank_space;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -364,8 +359,7 @@ impl<'a> Printer<'a> {
|
|||||||
debug!("pp String('{}')/buffer Vec<{},{}>",
|
debug!("pp String('{}')/buffer Vec<{},{}>",
|
||||||
s, self.left, self.right);
|
s, self.left, self.right);
|
||||||
self.advance_right();
|
self.advance_right();
|
||||||
self.token[self.right] = Token::String(s, len);
|
self.buf[self.right] = BufEntry { token: Token::String(s, len), size: len };
|
||||||
self.size[self.right] = len;
|
|
||||||
self.right_total += len;
|
self.right_total += len;
|
||||||
self.check_stream()
|
self.check_stream()
|
||||||
}
|
}
|
||||||
@ -381,7 +375,7 @@ impl<'a> Printer<'a> {
|
|||||||
if Some(&self.left) == self.scan_stack.back() {
|
if Some(&self.left) == self.scan_stack.back() {
|
||||||
debug!("setting {} to infinity and popping", self.left);
|
debug!("setting {} to infinity and popping", self.left);
|
||||||
let scanned = self.scan_pop_bottom();
|
let scanned = self.scan_pop_bottom();
|
||||||
self.size[scanned] = SIZE_INFINITY;
|
self.buf[scanned].size = SIZE_INFINITY;
|
||||||
}
|
}
|
||||||
self.advance_left()?;
|
self.advance_left()?;
|
||||||
if self.left != self.right {
|
if self.left != self.right {
|
||||||
@ -410,12 +404,12 @@ impl<'a> Printer<'a> {
|
|||||||
}
|
}
|
||||||
pub fn advance_left(&mut self) -> io::Result<()> {
|
pub fn advance_left(&mut self) -> io::Result<()> {
|
||||||
debug!("advance_left Vec<{},{}>, sizeof({})={}", self.left, self.right,
|
debug!("advance_left Vec<{},{}>, sizeof({})={}", self.left, self.right,
|
||||||
self.left, self.size[self.left]);
|
self.left, self.buf[self.left].size);
|
||||||
|
|
||||||
let mut left_size = self.size[self.left];
|
let mut left_size = self.buf[self.left].size;
|
||||||
|
|
||||||
while left_size >= 0 {
|
while left_size >= 0 {
|
||||||
let left = self.token[self.left].clone();
|
let left = self.buf[self.left].token.clone();
|
||||||
|
|
||||||
let len = match left {
|
let len = match left {
|
||||||
Token::Break(b) => b.blank_space,
|
Token::Break(b) => b.blank_space,
|
||||||
@ -437,7 +431,7 @@ impl<'a> Printer<'a> {
|
|||||||
self.left += 1;
|
self.left += 1;
|
||||||
self.left %= self.buf_len;
|
self.left %= self.buf_len;
|
||||||
|
|
||||||
left_size = self.size[self.left];
|
left_size = self.buf[self.left].size;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -445,23 +439,23 @@ impl<'a> Printer<'a> {
|
|||||||
pub fn check_stack(&mut self, k: isize) {
|
pub fn check_stack(&mut self, k: isize) {
|
||||||
if !self.scan_stack.is_empty() {
|
if !self.scan_stack.is_empty() {
|
||||||
let x = self.scan_top();
|
let x = self.scan_top();
|
||||||
match self.token[x] {
|
match self.buf[x].token {
|
||||||
Token::Begin(_) => {
|
Token::Begin(_) => {
|
||||||
if k > 0 {
|
if k > 0 {
|
||||||
let popped = self.scan_pop();
|
let popped = self.scan_pop();
|
||||||
self.size[popped] = self.size[x] + self.right_total;
|
self.buf[popped].size = self.buf[x].size + self.right_total;
|
||||||
self.check_stack(k - 1);
|
self.check_stack(k - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Token::End => {
|
Token::End => {
|
||||||
// paper says + not =, but that makes no sense.
|
// paper says + not =, but that makes no sense.
|
||||||
let popped = self.scan_pop();
|
let popped = self.scan_pop();
|
||||||
self.size[popped] = 1;
|
self.buf[popped].size = 1;
|
||||||
self.check_stack(k + 1);
|
self.check_stack(k + 1);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let popped = self.scan_pop();
|
let popped = self.scan_pop();
|
||||||
self.size[popped] = self.size[x] + self.right_total;
|
self.buf[popped].size = self.buf[x].size + self.right_total;
|
||||||
if k > 0 {
|
if k > 0 {
|
||||||
self.check_stack(k);
|
self.check_stack(k);
|
||||||
}
|
}
|
||||||
@ -499,8 +493,7 @@ impl<'a> Printer<'a> {
|
|||||||
pub fn print(&mut self, token: Token, l: isize) -> io::Result<()> {
|
pub fn print(&mut self, token: Token, l: isize) -> io::Result<()> {
|
||||||
debug!("print {} {} (remaining line space={})", token, l,
|
debug!("print {} {} (remaining line space={})", token, l,
|
||||||
self.space);
|
self.space);
|
||||||
debug!("{}", buf_str(&self.token,
|
debug!("{}", buf_str(&self.buf,
|
||||||
&self.size,
|
|
||||||
self.left,
|
self.left,
|
||||||
self.right,
|
self.right,
|
||||||
6));
|
6));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user