about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/abi.rs2
-rw-r--r--src/libsyntax/ast.rs6
-rw-r--r--src/libsyntax/ast_map.rs2
-rw-r--r--src/libsyntax/crateid.rs6
-rw-r--r--src/libsyntax/ext/base.rs5
-rw-r--r--src/libsyntax/ext/deriving/show.rs11
-rw-r--r--src/libsyntax/ext/format.rs75
-rw-r--r--src/libsyntax/parse/token.rs2
8 files changed, 71 insertions, 38 deletions
diff --git a/src/libsyntax/abi.rs b/src/libsyntax/abi.rs
index 17251d31351..bc53d2bec8d 100644
--- a/src/libsyntax/abi.rs
+++ b/src/libsyntax/abi.rs
@@ -155,7 +155,7 @@ impl Architecture {
 
 impl fmt::Show for Abi {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f.buf, "\"{}\"", self.name())
+        write!(f, "\"{}\"", self.name())
     }
 }
 
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index e5ef31a95a3..edcb8c32ecc 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -711,7 +711,7 @@ pub enum IntTy {
 
 impl fmt::Show for IntTy {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f.buf, "{}",
+        write!(f, "{}",
                ast_util::int_ty_to_str(*self, None, ast_util::AutoSuffix))
     }
 }
@@ -727,7 +727,7 @@ pub enum UintTy {
 
 impl fmt::Show for UintTy {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f.buf, "{}",
+        write!(f, "{}",
                ast_util::uint_ty_to_str(*self, None, ast_util::AutoSuffix))
     }
 }
@@ -741,7 +741,7 @@ pub enum FloatTy {
 
 impl fmt::Show for FloatTy {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f.buf, "{}", ast_util::float_ty_to_str(*self))
+        write!(f, "{}", ast_util::float_ty_to_str(*self))
     }
 }
 
diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs
index 6a7b913dce4..f1561ea31f9 100644
--- a/src/libsyntax/ast_map.rs
+++ b/src/libsyntax/ast_map.rs
@@ -41,7 +41,7 @@ impl PathElem {
 impl fmt::Show for PathElem {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         let slot = token::get_name(self.name());
-        write!(f.buf, "{}", slot)
+        write!(f, "{}", slot)
     }
 }
 
diff --git a/src/libsyntax/crateid.rs b/src/libsyntax/crateid.rs
index 84ef7941b2e..b7700cf396d 100644
--- a/src/libsyntax/crateid.rs
+++ b/src/libsyntax/crateid.rs
@@ -33,16 +33,16 @@ pub struct CrateId {
 
 impl fmt::Show for CrateId {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        try!(write!(f.buf, "{}", self.path));
+        try!(write!(f, "{}", self.path));
         let version = match self.version {
             None => "0.0",
             Some(ref version) => version.as_slice(),
         };
         if self.path == self.name ||
                 self.path.as_slice().ends_with(format!("/{}", self.name)) {
-            write!(f.buf, "\\#{}", version)
+            write!(f, "\\#{}", version)
         } else {
-            write!(f.buf, "\\#{}:{}", self.name, version)
+            write!(f, "\\#{}:{}", self.name, version)
         }
     }
 }
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index f4330960aca..06b56bbe472 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -281,7 +281,10 @@ pub fn syntax_expander_table() -> SyntaxEnv {
                                 ext::fmt::expand_syntax_ext));
     syntax_expanders.insert(intern("format_args"),
                             builtin_normal_expander(
-                                ext::format::expand_args));
+                                ext::format::expand_format_args));
+    syntax_expanders.insert(intern("format_args_method"),
+                            builtin_normal_expander(
+                                ext::format::expand_format_args_method));
     syntax_expanders.insert(intern("env"),
                             builtin_normal_expander(
                                     ext::env::expand_env));
diff --git a/src/libsyntax/ext/deriving/show.rs b/src/libsyntax/ext/deriving/show.rs
index aeaf53a1939..343100d3a8e 100644
--- a/src/libsyntax/ext/deriving/show.rs
+++ b/src/libsyntax/ext/deriving/show.rs
@@ -120,23 +120,18 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span,
     // AST construction!
     // we're basically calling
     //
-    // format_arg!(|__args| ::std::fmt::write(fmt.buf, __args), "<format_string>", exprs...)
+    // format_arg_method!(fmt, write_fmt, "<format_string>", exprs...)
     //
     // but doing it directly via ext::format.
     let formatter = substr.nonself_args[0];
-    let buf = cx.expr_field_access(span, formatter, cx.ident_of("buf"));
-
-    let std_write = vec!(cx.ident_of("std"), cx.ident_of("fmt"), cx.ident_of("write"));
-    let args = cx.ident_of("__args");
-    let write_call = cx.expr_call_global(span, std_write, vec!(buf, cx.expr_ident(span, args)));
-    let format_closure = cx.lambda_expr(span, vec!(args), write_call);
 
+    let meth = cx.ident_of("write_fmt");
     let s = token::intern_and_get_ident(format_string.as_slice());
     let format_string = cx.expr_str(span, s);
 
     // phew, not our responsibility any more!
     format::expand_preparsed_format_args(cx, span,
-                                         format_closure,
+                                         format::MethodCall(formatter, meth),
                                          format_string, exprs, Vec::new(),
                                          HashMap::new())
 }
diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs
index c03d174365e..e92ce139d00 100644
--- a/src/libsyntax/ext/format.rs
+++ b/src/libsyntax/ext/format.rs
@@ -59,6 +59,11 @@ struct Context<'a, 'b> {
     next_arg: uint,
 }
 
+pub enum Invocation {
+    Call(@ast::Expr),
+    MethodCall(@ast::Expr, ast::Ident),
+}
+
 /// Parses the arguments from the given list of tokens, returning None
 /// if there's a parse error so we can continue parsing other format!
 /// expressions.
@@ -67,8 +72,9 @@ struct Context<'a, 'b> {
 ///
 ///     Some((fmtstr, unnamed arguments, ordering of named arguments,
 ///           named arguments))
-fn parse_args(ecx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
-    -> (@ast::Expr, Option<(@ast::Expr, Vec<@ast::Expr>, Vec<StrBuf>,
+fn parse_args(ecx: &mut ExtCtxt, sp: Span, allow_method: bool,
+              tts: &[ast::TokenTree])
+    -> (Invocation, Option<(@ast::Expr, Vec<@ast::Expr>, Vec<StrBuf>,
                             HashMap<StrBuf, @ast::Expr>)>) {
     let mut args = Vec::new();
     let mut names = HashMap::<StrBuf, @ast::Expr>::new();
@@ -80,22 +86,31 @@ fn parse_args(ecx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                                                 .map(|x| (*x).clone())
                                                 .collect());
     // Parse the leading function expression (maybe a block, maybe a path)
-    let extra = p.parse_expr();
+    let invocation = if allow_method {
+        let e = p.parse_expr();
+        if !p.eat(&token::COMMA) {
+            ecx.span_err(sp, "expected token: `,`");
+            return (Call(e), None);
+        }
+        MethodCall(e, p.parse_ident())
+    } else {
+        Call(p.parse_expr())
+    };
     if !p.eat(&token::COMMA) {
         ecx.span_err(sp, "expected token: `,`");
-        return (extra, None);
+        return (invocation, None);
     }
 
     if p.token == token::EOF {
         ecx.span_err(sp, "requires at least a format string argument");
-        return (extra, None);
+        return (invocation, None);
     }
     let fmtstr = p.parse_expr();
     let mut named = false;
     while p.token != token::EOF {
         if !p.eat(&token::COMMA) {
             ecx.span_err(sp, "expected token: `,`");
-            return (extra, None);
+            return (invocation, None);
         }
         if p.token == token::EOF { break } // accept trailing commas
         if named || (token::is_ident(&p.token) &&
@@ -110,13 +125,13 @@ fn parse_args(ecx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                     ecx.span_err(p.span,
                                  "expected ident, positional arguments \
                                  cannot follow named arguments");
-                    return (extra, None);
+                    return (invocation, None);
                 }
                 _ => {
                     ecx.span_err(p.span,
                                  format!("expected ident for named argument, but found `{}`",
                                          p.this_token_to_str()));
-                    return (extra, None);
+                    return (invocation, None);
                 }
             };
             let interned_name = token::get_ident(ident);
@@ -137,7 +152,7 @@ fn parse_args(ecx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
             args.push(p.parse_expr());
         }
     }
-    return (extra, Some((fmtstr, args, order, names)));
+    return (invocation, Some((fmtstr, args, order, names)));
 }
 
 impl<'a, 'b> Context<'a, 'b> {
@@ -595,7 +610,7 @@ impl<'a, 'b> Context<'a, 'b> {
 
     /// Actually builds the expression which the iformat! block will be expanded
     /// to
-    fn to_expr(&self, extra: @ast::Expr) -> @ast::Expr {
+    fn to_expr(&self, invocation: Invocation) -> @ast::Expr {
         let mut lets = Vec::new();
         let mut locals = Vec::new();
         let mut names = Vec::from_fn(self.name_positions.len(), |_| None);
@@ -699,8 +714,16 @@ impl<'a, 'b> Context<'a, 'b> {
         let resname = self.ecx.ident_of("__args");
         lets.push(self.ecx.stmt_let(self.fmtsp, false, resname, result));
         let res = self.ecx.expr_ident(self.fmtsp, resname);
-        let result = self.ecx.expr_call(extra.span, extra, vec!(
-                            self.ecx.expr_addr_of(extra.span, res)));
+        let result = match invocation {
+            Call(e) => {
+                self.ecx.expr_call(e.span, e,
+                                   vec!(self.ecx.expr_addr_of(e.span, res)))
+            }
+            MethodCall(e, m) => {
+                self.ecx.expr_method_call(e.span, e, m,
+                                          vec!(self.ecx.expr_addr_of(e.span, res)))
+            }
+        };
         let body = self.ecx.expr_block(self.ecx.block(self.fmtsp, lets,
                                                       Some(result)));
 
@@ -794,13 +817,25 @@ impl<'a, 'b> Context<'a, 'b> {
     }
 }
 
-pub fn expand_args(ecx: &mut ExtCtxt, sp: Span,
-                   tts: &[ast::TokenTree]) -> Box<base::MacResult> {
+pub fn expand_format_args(ecx: &mut ExtCtxt, sp: Span,
+                          tts: &[ast::TokenTree]) -> Box<base::MacResult> {
+
+    match parse_args(ecx, sp, false, tts) {
+        (invocation, Some((efmt, args, order, names))) => {
+            MacExpr::new(expand_preparsed_format_args(ecx, sp, invocation, efmt,
+                                                      args, order, names))
+        }
+        (_, None) => MacExpr::new(ecx.expr_uint(sp, 2))
+    }
+}
+
+pub fn expand_format_args_method(ecx: &mut ExtCtxt, sp: Span,
+                                 tts: &[ast::TokenTree]) -> Box<base::MacResult> {
 
-    match parse_args(ecx, sp, tts) {
-        (extra, Some((efmt, args, order, names))) => {
-            MacExpr::new(expand_preparsed_format_args(ecx, sp, extra, efmt, args,
-                                                order, names))
+    match parse_args(ecx, sp, true, tts) {
+        (invocation, Some((efmt, args, order, names))) => {
+            MacExpr::new(expand_preparsed_format_args(ecx, sp, invocation, efmt,
+                                                      args, order, names))
         }
         (_, None) => MacExpr::new(ecx.expr_uint(sp, 2))
     }
@@ -810,7 +845,7 @@ pub fn expand_args(ecx: &mut ExtCtxt, sp: Span,
 /// name=names...)` and construct the appropriate formatting
 /// expression.
 pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
-                                    extra: @ast::Expr,
+                                    invocation: Invocation,
                                     efmt: @ast::Expr, args: Vec<@ast::Expr>,
                                     name_ordering: Vec<StrBuf>,
                                     names: HashMap<StrBuf, @ast::Expr>) -> @ast::Expr {
@@ -869,5 +904,5 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
         }
     }
 
-    cx.to_expr(extra)
+    cx.to_expr(invocation)
 }
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 68ce8cb2bc1..5dfd18392a9 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -594,7 +594,7 @@ impl BytesContainer for InternedString {
 
 impl fmt::Show for InternedString {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f.buf, "{}", self.string.as_slice())
+        write!(f, "{}", self.string.as_slice())
     }
 }