diff options
| author | bors <bors@rust-lang.org> | 2013-08-13 19:23:21 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-08-13 19:23:21 -0700 |
| commit | 7585b34d3171eb79057dbf8196312b08a5bc328b (patch) | |
| tree | 3531f8443816138646d28cd0651e09d9190a8886 /src/libsyntax | |
| parent | 433fbe8fcf13724445cc57c85cc454352c969429 (diff) | |
| parent | 36882b3d54043efc9f78459da39471fb8d5e6239 (diff) | |
| download | rust-7585b34d3171eb79057dbf8196312b08a5bc328b.tar.gz rust-7585b34d3171eb79057dbf8196312b08a5bc328b.zip | |
auto merge of #8446 : alexcrichton/rust/ifmt++, r=graydon
This includes a number of improvements to `ifmt!`
* Implements formatting arguments -- `{:0.5x}` works now
* Formatting now works on all integer widths, not just `int` and `uint`
* Added a large doc block to `std::fmt` which should help explain what `ifmt!` is all about
* Added floating point formatters, although they have the same pitfalls from before (they're just proof-of-concept now)
Closed a couple of issues along the way, yay! Once this gets into a snapshot, I'll start looking into removing all of `fmt`
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ext/ifmt.rs | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/src/libsyntax/ext/ifmt.rs b/src/libsyntax/ext/ifmt.rs index 65d2f798f31..6999f046b7b 100644 --- a/src/libsyntax/ext/ifmt.rs +++ b/src/libsyntax/ext/ifmt.rs @@ -127,7 +127,13 @@ impl Context { } } parse::Argument(ref arg) => { - // argument first (it's first in the format string) + // width/precision first, if they have implicit positional + // parameters it makes more sense to consume them first. + self.verify_count(arg.format.width); + self.verify_count(arg.format.precision); + + // argument second, if it's an implicit positional parameter + // it's written second, so it should come after width/precision. let pos = match arg.position { parse::ArgumentNext => { let i = self.next_arg; @@ -144,10 +150,6 @@ impl Context { } else { Known(arg.format.ty.to_managed()) }; self.verify_arg_type(pos, ty); - // width/precision next - self.verify_count(arg.format.width); - self.verify_count(arg.format.precision); - // and finally the method being applied match arg.method { None => {} @@ -315,6 +317,10 @@ impl Context { /// Translate a `parse::Piece` to a static `rt::Piece` fn trans_piece(&mut self, piece: &parse::Piece) -> @ast::expr { let sp = self.fmtsp; + let parsepath = |s: &str| { + ~[self.ecx.ident_of("std"), self.ecx.ident_of("fmt"), + self.ecx.ident_of("parse"), self.ecx.ident_of(s)] + }; let rtpath = |s: &str| { ~[self.ecx.ident_of("std"), self.ecx.ident_of("fmt"), self.ecx.ident_of("rt"), self.ecx.ident_of(s)] @@ -480,20 +486,24 @@ impl Context { let fill = self.ecx.expr_lit(sp, ast::lit_int(fill as i64, ast::ty_char)); let align = match arg.format.align { - None | Some(parse::AlignLeft) => { - self.ecx.expr_bool(sp, true) + parse::AlignLeft => { + self.ecx.path_global(sp, parsepath("AlignLeft")) } - Some(parse::AlignRight) => { - self.ecx.expr_bool(sp, false) + parse::AlignRight => { + self.ecx.path_global(sp, parsepath("AlignRight")) + } + parse::AlignUnknown => { + self.ecx.path_global(sp, parsepath("AlignUnknown")) } }; + let align = self.ecx.expr_path(align); let flags = self.ecx.expr_uint(sp, arg.format.flags); let prec = trans_count(arg.format.precision); let width = trans_count(arg.format.width); let path = self.ecx.path_global(sp, rtpath("FormatSpec")); let fmt = self.ecx.expr_struct(sp, path, ~[ self.ecx.field_imm(sp, self.ecx.ident_of("fill"), fill), - self.ecx.field_imm(sp, self.ecx.ident_of("alignleft"), align), + self.ecx.field_imm(sp, self.ecx.ident_of("align"), align), self.ecx.field_imm(sp, self.ecx.ident_of("flags"), flags), self.ecx.field_imm(sp, self.ecx.ident_of("precision"), prec), self.ecx.field_imm(sp, self.ecx.ident_of("width"), width), @@ -627,15 +637,17 @@ impl Context { Known(tyname) => { let fmt_trait = match tyname.as_slice() { "?" => "Poly", - "d" | "i" => "Signed", - "u" => "Unsigned", "b" => "Bool", "c" => "Char", + "d" | "i" => "Signed", + "f" => "Float", "o" => "Octal", + "p" => "Pointer", + "s" => "String", + "t" => "Binary", + "u" => "Unsigned", "x" => "LowerHex", "X" => "UpperHex", - "s" => "String", - "p" => "Pointer", _ => { self.ecx.span_err(sp, fmt!("unknown format trait \ `%s`", tyname)); |
