//! line (which it can't) and so naturally place the content on its own line to
//! avoid combining it with other lines and making matters even worse.
-pub use self::PrintStackBreak::*;
-pub use self::Breaks::*;
-pub use self::Token::*;
-
use std::io;
use std::string;
use std::iter::repeat;
#[derive(Clone)]
pub enum Token {
- String(string::String, int),
+ String(String, int),
Break(BreakToken),
Begin(BeginToken),
End,
impl Token {
pub fn is_eof(&self) -> bool {
- match *self { Eof => true, _ => false }
+ match *self {
+ Token::Eof => true,
+ _ => false,
+ }
}
pub fn is_hardbreak_tok(&self) -> bool {
match *self {
- Break(BreakToken {
+ Token::Break(BreakToken {
offset: 0,
blank_space: bs
}) if bs == SIZE_INFINITY =>
}
}
-pub fn tok_str(t: Token) -> string::String {
- match t {
- String(s, len) => return format!("STR({},{})", s, len),
- Break(_) => return "BREAK".to_string(),
- Begin(_) => return "BEGIN".to_string(),
- End => return "END".to_string(),
- Eof => return "EOF".to_string()
+pub fn tok_str(token: &Token) -> String {
+ match *token {
+ Token::String(ref s, len) => format!("STR({},{})", s, len),
+ Token::Break(_) => "BREAK".to_string(),
+ Token::Begin(_) => "BEGIN".to_string(),
+ Token::End => "END".to_string(),
+ Token::Eof => "EOF".to_string()
}
}
-pub fn buf_str(toks: Vec<Token>,
- szs: Vec<int>,
+pub fn buf_str(toks: &[Token],
+ szs: &[int],
left: uint,
right: uint,
lim: uint)
- -> string::String {
+ -> String {
let n = toks.len();
assert_eq!(n, szs.len());
let mut i = left;
}
s.push_str(&format!("{}={}",
szs[i],
- tok_str(toks[i].clone()))[]);
+ tok_str(&toks[i]))[]);
i += 1u;
i %= n;
}
// fall behind.
let n: uint = 3 * linewidth;
debug!("mk_printer {}", linewidth);
- let token: Vec<Token> = repeat(Eof).take(n).collect();
+ let token: Vec<Token> = repeat(Token::Eof).take(n).collect();
let size: Vec<int> = repeat(0i).take(n).collect();
let scan_stack: Vec<uint> = repeat(0u).take(n).collect();
Printer {
pub fn replace_last_token(&mut self, t: Token) {
self.token[self.right] = t;
}
- pub fn pretty_print(&mut self, t: Token) -> io::IoResult<()> {
+ pub fn pretty_print(&mut self, token: Token) -> io::IoResult<()> {
debug!("pp ~[{},{}]", self.left, self.right);
- match t {
- Eof => {
+ match token {
+ Token::Eof => {
if !self.scan_stack_empty {
self.check_stack(0);
- let left = self.token[self.left].clone();
- let left_size = self.size[self.left];
- try!(self.advance_left(left, left_size));
+ try!(self.advance_left());
}
self.indent(0);
Ok(())
}
- Begin(b) => {
+ Token::Begin(b) => {
if self.scan_stack_empty {
self.left_total = 1;
self.right_total = 1;
} else { self.advance_right(); }
debug!("pp Begin({})/buffer ~[{},{}]",
b.offset, self.left, self.right);
- self.token[self.right] = t;
+ self.token[self.right] = token;
self.size[self.right] = -self.right_total;
let right = self.right;
self.scan_push(right);
Ok(())
}
- End => {
+ Token::End => {
if self.scan_stack_empty {
debug!("pp End/print ~[{},{}]", self.left, self.right);
- self.print(t, 0)
+ self.print(token, 0)
} else {
debug!("pp End/buffer ~[{},{}]", self.left, self.right);
self.advance_right();
- self.token[self.right] = t;
+ self.token[self.right] = token;
self.size[self.right] = -1;
let right = self.right;
self.scan_push(right);
Ok(())
}
}
- Break(b) => {
+ Token::Break(b) => {
if self.scan_stack_empty {
self.left_total = 1;
self.right_total = 1;
self.check_stack(0);
let right = self.right;
self.scan_push(right);
- self.token[self.right] = t;
+ self.token[self.right] = token;
self.size[self.right] = -self.right_total;
self.right_total += b.blank_space;
Ok(())
}
- String(ref s, len) => {
+ Token::String(s, len) => {
if self.scan_stack_empty {
debug!("pp String('{}')/print ~[{},{}]",
- *s, self.left, self.right);
- self.print(t.clone(), len)
+ s, self.left, self.right);
+ self.print(Token::String(s, len), len)
} else {
debug!("pp String('{}')/buffer ~[{},{}]",
- *s, self.left, self.right);
+ s, self.left, self.right);
self.advance_right();
- self.token[self.right] = t.clone();
+ self.token[self.right] = Token::String(s, len);
self.size[self.right] = len;
self.right_total += len;
self.check_stream()
self.size[scanned] = SIZE_INFINITY;
}
}
- let left = self.token[self.left].clone();
- let left_size = self.size[self.left];
- try!(self.advance_left(left, left_size));
+ try!(self.advance_left());
if self.left != self.right {
try!(self.check_stream());
}
self.right %= self.buf_len;
assert!((self.right != self.left));
}
- pub fn advance_left(&mut self, x: Token, l: int) -> io::IoResult<()> {
+ pub fn advance_left(&mut self) -> io::IoResult<()> {
debug!("advance_left ~[{},{}], sizeof({})={}", self.left, self.right,
- self.left, l);
- if l >= 0 {
- let ret = self.print(x.clone(), l);
- match x {
- Break(b) => self.left_total += b.blank_space,
- String(_, len) => {
- assert_eq!(len, l); self.left_total += len;
- }
- _ => ()
- }
- if self.left != self.right {
- self.left += 1u;
- self.left %= self.buf_len;
- let left = self.token[self.left].clone();
- let left_size = self.size[self.left];
- try!(self.advance_left(left, left_size));
+ self.left, self.size[self.left]);
+
+ let mut left_size = self.size[self.left];
+
+ while left_size >= 0 {
+ let left = self.token[self.left].clone();
+
+ let len = match left {
+ Token::Break(b) => b.blank_space,
+ Token::String(_, len) => {
+ assert_eq!(len, left_size);
+ len
+ }
+ _ => 0
+ };
+
+ try!(self.print(left, left_size));
+
+ self.left_total += len;
+
+ if self.left == self.right {
+ break;
}
- ret
- } else {
- Ok(())
+
+ self.left += 1u;
+ self.left %= self.buf_len;
+
+ left_size = self.size[self.left];
}
+
+ Ok(())
}
pub fn check_stack(&mut self, k: int) {
if !self.scan_stack_empty {
let x = self.scan_top();
match self.token[x] {
- Begin(_) => {
+ Token::Begin(_) => {
if k > 0 {
let popped = self.scan_pop();
self.size[popped] = self.size[x] + self.right_total;
self.check_stack(k - 1);
}
}
- End => {
+ Token::End => {
// paper says + not =, but that makes no sense.
let popped = self.scan_pop();
self.size[popped] = 1;
} else {
PrintStackElem {
offset: 0,
- pbreak: Broken(Inconsistent)
+ pbreak: PrintStackBreak::Broken(Breaks::Inconsistent)
}
}
}
}
write!(self.out, "{}", s)
}
- pub fn print(&mut self, x: Token, l: int) -> io::IoResult<()> {
- debug!("print {} {} (remaining line space={})", tok_str(x.clone()), l,
+ pub fn print(&mut self, token: Token, l: int) -> io::IoResult<()> {
+ debug!("print {} {} (remaining line space={})", tok_str(&token), l,
self.space);
- debug!("{}", buf_str(self.token.clone(),
- self.size.clone(),
+ debug!("{}", buf_str(&self.token[],
+ &self.size[],
self.left,
self.right,
6));
- match x {
- Begin(b) => {
+ 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: Broken(b.breaks)
+ pbreak: PrintStackBreak::Broken(b.breaks)
});
} else {
debug!("print Begin -> push fitting block");
self.print_stack.push(PrintStackElem {
offset: 0,
- pbreak: Fits
+ pbreak: PrintStackBreak::Fits
});
}
Ok(())
}
- End => {
+ Token::End => {
debug!("print End -> pop End");
let print_stack = &mut self.print_stack;
assert!((print_stack.len() != 0u));
print_stack.pop().unwrap();
Ok(())
}
- Break(b) => {
+ Token::Break(b) => {
let top = self.get_top();
match top.pbreak {
- Fits => {
+ PrintStackBreak::Fits => {
debug!("print Break({}) in fitting block", b.blank_space);
self.space -= b.blank_space;
self.indent(b.blank_space);
Ok(())
}
- Broken(Consistent) => {
+ 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
}
- Broken(Inconsistent) => {
+ PrintStackBreak::Broken(Breaks::Inconsistent) => {
if l > self.space {
debug!("print Break({}+{}) w/ newline in inconsistent",
top.offset, b.offset);
}
}
}
- String(s, len) => {
+ Token::String(s, len) => {
debug!("print String({})", s);
assert_eq!(l, len);
// assert!(l <= space);
self.space -= len;
self.print_str(&s[])
}
- Eof => {
+ Token::Eof => {
// Eof should never get here.
panic!();
}
//
// "raw box"
pub fn rbox(p: &mut Printer, indent: uint, b: Breaks) -> io::IoResult<()> {
- p.pretty_print(Begin(BeginToken {
+ p.pretty_print(Token::Begin(BeginToken {
offset: indent as int,
breaks: b
}))
}
pub fn ibox(p: &mut Printer, indent: uint) -> io::IoResult<()> {
- rbox(p, indent, Inconsistent)
+ rbox(p, indent, Breaks::Inconsistent)
}
pub fn cbox(p: &mut Printer, indent: uint) -> io::IoResult<()> {
- rbox(p, indent, Consistent)
+ rbox(p, indent, Breaks::Consistent)
}
pub fn break_offset(p: &mut Printer, n: uint, off: int) -> io::IoResult<()> {
- p.pretty_print(Break(BreakToken {
+ p.pretty_print(Token::Break(BreakToken {
offset: off,
blank_space: n as int
}))
}
-pub fn end(p: &mut Printer) -> io::IoResult<()> { p.pretty_print(End) }
+pub fn end(p: &mut Printer) -> io::IoResult<()> {
+ p.pretty_print(Token::End)
+}
-pub fn eof(p: &mut Printer) -> io::IoResult<()> { p.pretty_print(Eof) }
+pub fn eof(p: &mut Printer) -> io::IoResult<()> {
+ p.pretty_print(Token::Eof)
+}
pub fn word(p: &mut Printer, wrd: &str) -> io::IoResult<()> {
- p.pretty_print(String(/* bad */ wrd.to_string(), wrd.len() as int))
+ p.pretty_print(Token::String(/* bad */ wrd.to_string(), wrd.len() as int))
}
pub fn huge_word(p: &mut Printer, wrd: &str) -> io::IoResult<()> {
- p.pretty_print(String(/* bad */ wrd.to_string(), SIZE_INFINITY))
+ p.pretty_print(Token::String(/* bad */ wrd.to_string(), SIZE_INFINITY))
}
pub fn zero_word(p: &mut Printer, wrd: &str) -> io::IoResult<()> {
- p.pretty_print(String(/* bad */ wrd.to_string(), 0))
+ p.pretty_print(Token::String(/* bad */ wrd.to_string(), 0))
}
pub fn spaces(p: &mut Printer, n: uint) -> io::IoResult<()> {
}
pub fn hardbreak_tok_offset(off: int) -> Token {
- Break(BreakToken {offset: off, blank_space: SIZE_INFINITY})
+ Token::Break(BreakToken {offset: off, blank_space: SIZE_INFINITY})
}
-pub fn hardbreak_tok() -> Token { return hardbreak_tok_offset(0); }
+pub fn hardbreak_tok() -> Token {
+ hardbreak_tok_offset(0)
+}
use parse::lexer::comments;
use parse;
use print::pp::{self, break_offset, word, space, zerobreak, hardbreak};
-use print::pp::{Breaks, Consistent, Inconsistent, eof};
+use print::pp::{Breaks, eof};
+use print::pp::Breaks::{Consistent, Inconsistent};
use ptr::P;
use std::{ascii, mem};
impl<'a> State<'a> {
pub fn ibox(&mut self, u: uint) -> IoResult<()> {
- self.boxes.push(pp::Inconsistent);
+ self.boxes.push(pp::Breaks::Inconsistent);
pp::ibox(&mut self.s, u)
}
}
pub fn cbox(&mut self, u: uint) -> IoResult<()> {
- self.boxes.push(pp::Consistent);
+ self.boxes.push(pp::Breaks::Consistent);
pp::cbox(&mut self.s, u)
}
}
pub fn is_begin(&mut self) -> bool {
- match self.s.last_token() { pp::Begin(_) => true, _ => false }
+ match self.s.last_token() {
+ pp::Token::Begin(_) => true,
+ _ => false,
+ }
}
pub fn is_end(&mut self) -> bool {
- match self.s.last_token() { pp::End => true, _ => false }
+ match self.s.last_token() {
+ pp::Token::End => true,
+ _ => false,
+ }
}
// is this the beginning of a line?
pub fn in_cbox(&self) -> bool {
match self.boxes.last() {
- Some(&last_box) => last_box == pp::Consistent,
+ Some(&last_box) => last_box == pp::Breaks::Consistent,
None => false
}
}
Ok(())
}
+ fn print_expr_box(&mut self,
+ place: &Option<P<ast::Expr>>,
+ expr: &ast::Expr) -> IoResult<()> {
+ try!(word(&mut self.s, "box"));
+ try!(word(&mut self.s, "("));
+ try!(place.as_ref().map_or(Ok(()), |e|self.print_expr(&**e)));
+ try!(self.word_space(")"));
+ self.print_expr(expr)
+ }
+
+ fn print_expr_vec(&mut self, exprs: &[P<ast::Expr>]) -> IoResult<()> {
+ try!(self.ibox(indent_unit));
+ try!(word(&mut self.s, "["));
+ try!(self.commasep_exprs(Inconsistent, &exprs[]));
+ try!(word(&mut self.s, "]"));
+ self.end()
+ }
+
+ fn print_expr_repeat(&mut self,
+ element: &ast::Expr,
+ count: &ast::Expr) -> IoResult<()> {
+ try!(self.ibox(indent_unit));
+ try!(word(&mut self.s, "["));
+ try!(self.print_expr(element));
+ try!(self.word_space(";"));
+ try!(self.print_expr(count));
+ try!(word(&mut self.s, "]"));
+ self.end()
+ }
+
+ fn print_expr_struct(&mut self,
+ path: &ast::Path,
+ fields: &[ast::Field],
+ wth: &Option<P<ast::Expr>>) -> IoResult<()> {
+ try!(self.print_path(path, true));
+ if !(fields.is_empty() && wth.is_none()) {
+ try!(word(&mut self.s, "{"));
+ try!(self.commasep_cmnt(
+ Consistent,
+ &fields[],
+ |s, field| {
+ try!(s.ibox(indent_unit));
+ try!(s.print_ident(field.ident.node));
+ try!(s.word_space(":"));
+ try!(s.print_expr(&*field.expr));
+ s.end()
+ },
+ |f| f.span));
+ match *wth {
+ Some(ref expr) => {
+ try!(self.ibox(indent_unit));
+ if !fields.is_empty() {
+ try!(word(&mut self.s, ","));
+ try!(space(&mut self.s));
+ }
+ try!(word(&mut self.s, ".."));
+ try!(self.print_expr(&**expr));
+ try!(self.end());
+ }
+ _ => try!(word(&mut self.s, ",")),
+ }
+ try!(word(&mut self.s, "}"));
+ }
+ Ok(())
+ }
+
+ fn print_expr_tup(&mut self, exprs: &[P<ast::Expr>]) -> IoResult<()> {
+ try!(self.popen());
+ try!(self.commasep_exprs(Inconsistent, &exprs[]));
+ if exprs.len() == 1 {
+ try!(word(&mut self.s, ","));
+ }
+ self.pclose()
+ }
+
+ fn print_expr_call(&mut self,
+ func: &ast::Expr,
+ args: &[P<ast::Expr>]) -> IoResult<()> {
+ try!(self.print_expr_maybe_paren(func));
+ self.print_call_post(args)
+ }
+
+ fn print_expr_method_call(&mut self,
+ ident: ast::SpannedIdent,
+ tys: &[P<ast::Ty>],
+ args: &[P<ast::Expr>]) -> IoResult<()> {
+ let base_args = args.slice_from(1);
+ try!(self.print_expr(&*args[0]));
+ try!(word(&mut self.s, "."));
+ try!(self.print_ident(ident.node));
+ if tys.len() > 0u {
+ try!(word(&mut self.s, "::<"));
+ try!(self.commasep(Inconsistent, tys,
+ |s, ty| s.print_type(&**ty)));
+ try!(word(&mut self.s, ">"));
+ }
+ self.print_call_post(base_args)
+ }
+
+ fn print_expr_binary(&mut self,
+ op: ast::BinOp,
+ lhs: &ast::Expr,
+ rhs: &ast::Expr) -> IoResult<()> {
+ try!(self.print_expr(lhs));
+ try!(space(&mut self.s));
+ try!(self.word_space(ast_util::binop_to_string(op)));
+ self.print_expr(rhs)
+ }
+
+ fn print_expr_unary(&mut self,
+ op: ast::UnOp,
+ expr: &ast::Expr) -> IoResult<()> {
+ try!(word(&mut self.s, ast_util::unop_to_string(op)));
+ self.print_expr_maybe_paren(expr)
+ }
+
+ fn print_expr_addr_of(&mut self,
+ mutability: ast::Mutability,
+ expr: &ast::Expr) -> IoResult<()> {
+ try!(word(&mut self.s, "&"));
+ try!(self.print_mutability(mutability));
+ self.print_expr_maybe_paren(expr)
+ }
+
pub fn print_expr(&mut self, expr: &ast::Expr) -> IoResult<()> {
try!(self.maybe_print_comment(expr.span.lo));
try!(self.ibox(indent_unit));
try!(self.ann.pre(self, NodeExpr(expr)));
match expr.node {
- ast::ExprBox(ref p, ref e) => {
- try!(word(&mut self.s, "box"));
- try!(word(&mut self.s, "("));
- try!(p.as_ref().map_or(Ok(()), |e|self.print_expr(&**e)));
- try!(self.word_space(")"));
- try!(self.print_expr(&**e));
+ ast::ExprBox(ref place, ref expr) => {
+ try!(self.print_expr_box(place, &**expr));
}
ast::ExprVec(ref exprs) => {
- try!(self.ibox(indent_unit));
- try!(word(&mut self.s, "["));
- try!(self.commasep_exprs(Inconsistent, &exprs[]));
- try!(word(&mut self.s, "]"));
- try!(self.end());
+ try!(self.print_expr_vec(&exprs[]));
}
-
ast::ExprRepeat(ref element, ref count) => {
- try!(self.ibox(indent_unit));
- try!(word(&mut self.s, "["));
- try!(self.print_expr(&**element));
- try!(self.word_space(";"));
- try!(self.print_expr(&**count));
- try!(word(&mut self.s, "]"));
- try!(self.end());
+ try!(self.print_expr_repeat(&**element, &**count));
}
-
ast::ExprStruct(ref path, ref fields, ref wth) => {
- try!(self.print_path(path, true));
- if !(fields.is_empty() && wth.is_none()) {
- try!(word(&mut self.s, "{"));
- try!(self.commasep_cmnt(
- Consistent,
- &fields[],
- |s, field| {
- try!(s.ibox(indent_unit));
- try!(s.print_ident(field.ident.node));
- try!(s.word_space(":"));
- try!(s.print_expr(&*field.expr));
- s.end()
- },
- |f| f.span));
- match *wth {
- Some(ref expr) => {
- try!(self.ibox(indent_unit));
- if !fields.is_empty() {
- try!(word(&mut self.s, ","));
- try!(space(&mut self.s));
- }
- try!(word(&mut self.s, ".."));
- try!(self.print_expr(&**expr));
- try!(self.end());
- }
- _ => try!(word(&mut self.s, ",")),
- }
- try!(word(&mut self.s, "}"));
- }
+ try!(self.print_expr_struct(path, &fields[], wth));
}
ast::ExprTup(ref exprs) => {
- try!(self.popen());
- try!(self.commasep_exprs(Inconsistent, &exprs[]));
- if exprs.len() == 1 {
- try!(word(&mut self.s, ","));
- }
- try!(self.pclose());
+ try!(self.print_expr_tup(&exprs[]));
}
ast::ExprCall(ref func, ref args) => {
- try!(self.print_expr_maybe_paren(&**func));
- try!(self.print_call_post(&args[]));
+ try!(self.print_expr_call(&**func, &args[]));
}
ast::ExprMethodCall(ident, ref tys, ref args) => {
- let base_args = args.slice_from(1);
- try!(self.print_expr(&*args[0]));
- try!(word(&mut self.s, "."));
- try!(self.print_ident(ident.node));
- if tys.len() > 0u {
- try!(word(&mut self.s, "::<"));
- try!(self.commasep(Inconsistent, &tys[],
- |s, ty| s.print_type(&**ty)));
- try!(word(&mut self.s, ">"));
- }
- try!(self.print_call_post(base_args));
+ try!(self.print_expr_method_call(ident, &tys[], &args[]));
}
ast::ExprBinary(op, ref lhs, ref rhs) => {
- try!(self.print_expr(&**lhs));
- try!(space(&mut self.s));
- try!(self.word_space(ast_util::binop_to_string(op)));
- try!(self.print_expr(&**rhs));
+ try!(self.print_expr_binary(op, &**lhs, &**rhs));
}
ast::ExprUnary(op, ref expr) => {
- try!(word(&mut self.s, ast_util::unop_to_string(op)));
- try!(self.print_expr_maybe_paren(&**expr));
+ try!(self.print_expr_unary(op, &**expr));
}
ast::ExprAddrOf(m, ref expr) => {
- try!(word(&mut self.s, "&"));
- try!(self.print_mutability(m));
- try!(self.print_expr_maybe_paren(&**expr));
+ try!(self.print_expr_addr_of(m, &**expr));
+ }
+ ast::ExprLit(ref lit) => {
+ try!(self.print_literal(&**lit));
}
- ast::ExprLit(ref lit) => try!(self.print_literal(&**lit)),
ast::ExprCast(ref expr, ref ty) => {
try!(self.print_expr(&**expr));
try!(space(&mut self.s));
comments::BlankLine => {
// We need to do at least one, possibly two hardbreaks.
let is_semi = match self.s.last_token() {
- pp::String(s, _) => ";" == s,
+ pp::Token::String(s, _) => ";" == s,
_ => false
};
if is_semi || self.is_begin() || self.is_end() {