diff options
| author | root <root@localhost> | 2014-07-20 16:31:43 +0200 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2014-07-21 09:54:35 -0700 |
| commit | 0e1880d8fe123354910a42f8046240dee6c6a668 (patch) | |
| tree | 2b9a3e1453dc2f7fd51ddd0ba4814dc6f259ad09 | |
| parent | 2357c443e02b185fe6be3a8ab54f3d04d1c80dd0 (diff) | |
| download | rust-0e1880d8fe123354910a42f8046240dee6c6a668.tar.gz rust-0e1880d8fe123354910a42f8046240dee6c6a668.zip | |
syntax: Join consecutive string literals in format strings together
Emit a single rt::Piece per consecutive string literals. String literals
are split on {{ or }} escapes.
Saves a small amount of static storage and emitted code size.
| -rw-r--r-- | src/libsyntax/ext/format.rs | 43 |
1 files changed, 33 insertions, 10 deletions
diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs index 4b245f2c9fd..2e86d1c005d 100644 --- a/src/libsyntax/ext/format.rs +++ b/src/libsyntax/ext/format.rs @@ -49,6 +49,9 @@ struct Context<'a, 'b> { name_types: HashMap<String, ArgumentType>, name_ordering: Vec<String>, + /// The latest consecutive literal strings + literal: Option<String>, + /// Collection of the compiled `rt::Piece` structures pieces: Vec<Gc<ast::Expr>>, name_positions: HashMap<String, uint>, @@ -362,17 +365,29 @@ impl<'a, 'b> Context<'a, 'b> { } } + /// Translate the accumulated string literals to a static `rt::Piece` + fn trans_literal_string(&mut self) -> Option<Gc<ast::Expr>> { + let sp = self.fmtsp; + self.literal.take().map(|s| { + let s = token::intern_and_get_ident(s.as_slice()); + self.ecx.expr_call_global(sp, + self.rtpath("String"), + vec!( + self.ecx.expr_str(sp, s) + )) + }) + } + /// Translate a `parse::Piece` to a static `rt::Piece` - fn trans_piece(&mut self, piece: &parse::Piece) -> Gc<ast::Expr> { + fn trans_piece(&mut self, piece: &parse::Piece) -> Option<Gc<ast::Expr>> { let sp = self.fmtsp; match *piece { parse::String(s) => { - let s = token::intern_and_get_ident(s); - self.ecx.expr_call_global(sp, - self.rtpath("String"), - vec!( - self.ecx.expr_str(sp, s) - )) + match self.literal { + Some(ref mut sb) => sb.push_str(s), + ref mut empty => *empty = Some(String::from_str(s)), + } + None } parse::Argument(ref arg) => { // Translate the position @@ -430,7 +445,7 @@ impl<'a, 'b> Context<'a, 'b> { let s = self.ecx.expr_struct(sp, path, vec!( self.ecx.field_imm(sp, self.ecx.ident_of("position"), pos), self.ecx.field_imm(sp, self.ecx.ident_of("format"), fmt))); - self.ecx.expr_call_global(sp, self.rtpath("Argument"), vec!(s)) + Some(self.ecx.expr_call_global(sp, self.rtpath("Argument"), vec!(s))) } } } @@ -694,6 +709,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span, name_ordering: name_ordering, nest_level: 0, next_arg: 0, + literal: None, pieces: Vec::new(), method_statics: Vec::new(), fmtsp: sp, @@ -712,8 +728,14 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span, Some(piece) => { if parser.errors.len() > 0 { break } cx.verify_piece(&piece); - let piece = cx.trans_piece(&piece); - cx.pieces.push(piece); + match cx.trans_piece(&piece) { + Some(piece) => { + cx.trans_literal_string().map(|piece| + cx.pieces.push(piece)); + cx.pieces.push(piece); + } + None => {} + } } None => break } @@ -727,6 +749,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span, } None => {} } + cx.trans_literal_string().map(|piece| cx.pieces.push(piece)); // Make sure that all arguments were used and all arguments have types. for (i, ty) in cx.arg_types.iter().enumerate() { |
