diff options
Diffstat (limited to 'src/libsyntax/ext/format.rs')
| -rw-r--r-- | src/libsyntax/ext/format.rs | 136 |
1 files changed, 61 insertions, 75 deletions
diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs index 2a0a352f128..36dbf117604 100644 --- a/src/libsyntax/ext/format.rs +++ b/src/libsyntax/ext/format.rs @@ -17,7 +17,7 @@ use ext::base::*; use ext::base; use ext::build::AstBuilder; use fmt_macros as parse; -use parse::token::{InternedString, special_idents}; +use parse::token::special_idents; use parse::token; use ptr::P; @@ -300,56 +300,35 @@ impl<'a, 'b> Context<'a, 'b> { } } - /// These attributes are applied to all statics that this syntax extension - /// will generate. - fn static_attrs(ecx: &ExtCtxt, fmtsp: Span) -> Vec<ast::Attribute> { - // Flag statics as `inline` so LLVM can merge duplicate globals as much - // as possible (which we're generating a whole lot of). - let unnamed = ecx.meta_word(fmtsp, InternedString::new("inline")); - let unnamed = ecx.attribute(fmtsp, unnamed); - - // Do not warn format string as dead code - let dead_code = ecx.meta_word(fmtsp, InternedString::new("dead_code")); - let allow_dead_code = ecx.meta_list(fmtsp, - InternedString::new("allow"), - vec![dead_code]); - let allow_dead_code = ecx.attribute(fmtsp, allow_dead_code); - vec![unnamed, allow_dead_code] - } - fn rtpath(ecx: &ExtCtxt, s: &str) -> Vec<ast::Ident> { - vec![ecx.ident_of("std"), ecx.ident_of("fmt"), ecx.ident_of("rt"), ecx.ident_of(s)] + vec![ecx.ident_of("std"), ecx.ident_of("fmt"), ecx.ident_of("rt"), + ecx.ident_of("v1"), ecx.ident_of(s)] } fn trans_count(&self, c: parse::Count) -> P<ast::Expr> { let sp = self.fmtsp; - match c { - parse::CountIs(i) => { - self.ecx.expr_call_global(sp, Context::rtpath(self.ecx, "CountIs"), - vec!(self.ecx.expr_usize(sp, i))) + let count = |: c, arg| { + let mut path = Context::rtpath(self.ecx, "Count"); + path.push(self.ecx.ident_of(c)); + match arg { + Some(arg) => self.ecx.expr_call_global(sp, path, vec![arg]), + None => self.ecx.expr_path(self.ecx.path_global(sp, path)), } + }; + match c { + parse::CountIs(i) => count("Is", Some(self.ecx.expr_usize(sp, i))), parse::CountIsParam(i) => { - self.ecx.expr_call_global(sp, Context::rtpath(self.ecx, "CountIsParam"), - vec!(self.ecx.expr_usize(sp, i))) - } - parse::CountImplied => { - let path = self.ecx.path_global(sp, Context::rtpath(self.ecx, - "CountImplied")); - self.ecx.expr_path(path) - } - parse::CountIsNextParam => { - let path = self.ecx.path_global(sp, Context::rtpath(self.ecx, - "CountIsNextParam")); - self.ecx.expr_path(path) + count("Param", Some(self.ecx.expr_usize(sp, i))) } + parse::CountImplied => count("Implied", None), + parse::CountIsNextParam => count("NextParam", None), parse::CountIsName(n) => { let i = match self.name_positions.get(n) { Some(&i) => i, None => 0, // error already emitted elsewhere }; let i = i + self.args.len(); - self.ecx.expr_call_global(sp, Context::rtpath(self.ecx, "CountIsParam"), - vec!(self.ecx.expr_usize(sp, i))) + count("Param", Some(self.ecx.expr_usize(sp, i))) } } } @@ -373,27 +352,35 @@ impl<'a, 'b> Context<'a, 'b> { } parse::NextArgument(ref arg) => { // Translate the position - let pos = match arg.position { - // These two have a direct mapping - parse::ArgumentNext => { - let path = self.ecx.path_global(sp, Context::rtpath(self.ecx, - "ArgumentNext")); - self.ecx.expr_path(path) - } - parse::ArgumentIs(i) => { - self.ecx.expr_call_global(sp, Context::rtpath(self.ecx, "ArgumentIs"), - vec!(self.ecx.expr_usize(sp, i))) - } - // Named arguments are converted to positional arguments at - // the end of the list of arguments - parse::ArgumentNamed(n) => { - let i = match self.name_positions.get(n) { - Some(&i) => i, - None => 0, // error already emitted elsewhere - }; - let i = i + self.args.len(); - self.ecx.expr_call_global(sp, Context::rtpath(self.ecx, "ArgumentIs"), - vec!(self.ecx.expr_usize(sp, i))) + let pos = { + let pos = |: c, arg| { + let mut path = Context::rtpath(self.ecx, "Position"); + path.push(self.ecx.ident_of(c)); + match arg { + Some(i) => { + let arg = self.ecx.expr_usize(sp, i); + self.ecx.expr_call_global(sp, path, vec![arg]) + } + None => { + self.ecx.expr_path(self.ecx.path_global(sp, path)) + } + } + }; + match arg.position { + // These two have a direct mapping + parse::ArgumentNext => pos("Next", None), + parse::ArgumentIs(i) => pos("At", Some(i)), + + // Named arguments are converted to positional arguments + // at the end of the list of arguments + parse::ArgumentNamed(n) => { + let i = match self.name_positions.get(n) { + Some(&i) => i, + None => 0, // error already emitted elsewhere + }; + let i = i + self.args.len(); + pos("At", Some(i)) + } } }; @@ -417,19 +404,16 @@ impl<'a, 'b> Context<'a, 'b> { // Translate the format let fill = self.ecx.expr_lit(sp, ast::LitChar(fill)); + let align = |:name| { + let mut p = Context::rtpath(self.ecx, "Alignment"); + p.push(self.ecx.ident_of(name)); + self.ecx.path_global(sp, p) + }; let align = match arg.format.align { - parse::AlignLeft => { - self.ecx.path_global(sp, Context::rtpath(self.ecx, "AlignLeft")) - } - parse::AlignRight => { - self.ecx.path_global(sp, Context::rtpath(self.ecx, "AlignRight")) - } - parse::AlignCenter => { - self.ecx.path_global(sp, Context::rtpath(self.ecx, "AlignCenter")) - } - parse::AlignUnknown => { - self.ecx.path_global(sp, Context::rtpath(self.ecx, "AlignUnknown")) - } + parse::AlignLeft => align("Left"), + parse::AlignRight => align("Right"), + parse::AlignCenter => align("Center"), + parse::AlignUnknown => align("Unknown"), }; let align = self.ecx.expr_path(align); let flags = self.ecx.expr_usize(sp, arg.format.flags); @@ -465,7 +449,7 @@ impl<'a, 'b> Context<'a, 'b> { let st = ast::ItemStatic(ty, ast::MutImmutable, slice); let name = ecx.ident_of(name); - let item = ecx.item(fmtsp, name, Context::static_attrs(ecx, fmtsp), st); + let item = ecx.item(fmtsp, name, vec![], st); let decl = respan(fmtsp, ast::DeclItem(item)); // Wrap the declaration in a block so that it forms a single expression. @@ -575,7 +559,7 @@ impl<'a, 'b> Context<'a, 'b> { // Now create the fmt::Arguments struct with all our locals we created. let (fn_name, fn_args) = if self.all_pieces_simple { - ("new", vec![pieces, args_slice]) + ("new_v1", vec![pieces, args_slice]) } else { // Build up the static array which will store our precompiled // nonstandard placeholders, if there are any. @@ -587,7 +571,7 @@ impl<'a, 'b> Context<'a, 'b> { piece_ty, self.pieces); - ("with_placeholders", vec![pieces, fmt, args_slice]) + ("new_v1_formatted", vec![pieces, args_slice, fmt]) }; self.ecx.expr_call_global(self.fmtsp, vec!( @@ -624,7 +608,8 @@ impl<'a, 'b> Context<'a, 'b> { return ecx.expr_call_global(sp, vec![ ecx.ident_of("std"), ecx.ident_of("fmt"), - ecx.ident_of("argumentuint")], vec![arg]) + ecx.ident_of("ArgumentV1"), + ecx.ident_of("from_uint")], vec![arg]) } }; @@ -636,7 +621,8 @@ impl<'a, 'b> Context<'a, 'b> { ecx.expr_call_global(sp, vec![ ecx.ident_of("std"), ecx.ident_of("fmt"), - ecx.ident_of("argument")], vec![ecx.expr_path(format_fn), arg]) + ecx.ident_of("ArgumentV1"), + ecx.ident_of("new")], vec![arg, ecx.expr_path(format_fn)]) } } |
