Skip to content

Commit 8baec88

Browse files
committed
---
yaml --- r: 151745 b: refs/heads/try2 c: 854d95f h: refs/heads/master i: 151743: 9162b62 v: v3
1 parent 7f71308 commit 8baec88

File tree

4 files changed

+63
-30
lines changed

4 files changed

+63
-30
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ refs/heads/snap-stage3: 78a7676898d9f80ab540c6df5d4c9ce35bb50463
55
refs/heads/try: 519addf6277dbafccbb4159db4b710c37eaa2ec5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
8-
refs/heads/try2: 00f9263914da3d18c556d7ebc3941f9638721ac2
8+
refs/heads/try2: 854d95f9ffe83c8f77782b5dc76d18799579ba95
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/src/libsyntax/ext/base.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,10 @@ pub fn syntax_expander_table() -> SyntaxEnv {
281281
ext::fmt::expand_syntax_ext));
282282
syntax_expanders.insert(intern("format_args"),
283283
builtin_normal_expander(
284-
ext::format::expand_args));
284+
ext::format::expand_format_args));
285+
syntax_expanders.insert(intern("format_args_method"),
286+
builtin_normal_expander(
287+
ext::format::expand_format_args_method));
285288
syntax_expanders.insert(intern("env"),
286289
builtin_normal_expander(
287290
ext::env::expand_env));

branches/try2/src/libsyntax/ext/deriving/show.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -120,23 +120,18 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span,
120120
// AST construction!
121121
// we're basically calling
122122
//
123-
// format_arg!(|__args| ::std::fmt::write(fmt.buf, __args), "<format_string>", exprs...)
123+
// format_arg_method!(fmt, write_fmt, "<format_string>", exprs...)
124124
//
125125
// but doing it directly via ext::format.
126126
let formatter = substr.nonself_args[0];
127-
let buf = cx.expr_field_access(span, formatter, cx.ident_of("buf"));
128-
129-
let std_write = vec!(cx.ident_of("std"), cx.ident_of("fmt"), cx.ident_of("write"));
130-
let args = cx.ident_of("__args");
131-
let write_call = cx.expr_call_global(span, std_write, vec!(buf, cx.expr_ident(span, args)));
132-
let format_closure = cx.lambda_expr(span, vec!(args), write_call);
133127

128+
let meth = cx.ident_of("write_fmt");
134129
let s = token::intern_and_get_ident(format_string.as_slice());
135130
let format_string = cx.expr_str(span, s);
136131

137132
// phew, not our responsibility any more!
138133
format::expand_preparsed_format_args(cx, span,
139-
format_closure,
134+
format::MethodCall(formatter, meth),
140135
format_string, exprs, Vec::new(),
141136
HashMap::new())
142137
}

branches/try2/src/libsyntax/ext/format.rs

Lines changed: 55 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ struct Context<'a, 'b> {
5959
next_arg: uint,
6060
}
6161

62+
pub enum Invocation {
63+
Call(@ast::Expr),
64+
MethodCall(@ast::Expr, ast::Ident),
65+
}
66+
6267
/// Parses the arguments from the given list of tokens, returning None
6368
/// if there's a parse error so we can continue parsing other format!
6469
/// expressions.
@@ -67,8 +72,9 @@ struct Context<'a, 'b> {
6772
///
6873
/// Some((fmtstr, unnamed arguments, ordering of named arguments,
6974
/// named arguments))
70-
fn parse_args(ecx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
71-
-> (@ast::Expr, Option<(@ast::Expr, Vec<@ast::Expr>, Vec<StrBuf>,
75+
fn parse_args(ecx: &mut ExtCtxt, sp: Span, allow_method: bool,
76+
tts: &[ast::TokenTree])
77+
-> (Invocation, Option<(@ast::Expr, Vec<@ast::Expr>, Vec<StrBuf>,
7278
HashMap<StrBuf, @ast::Expr>)>) {
7379
let mut args = Vec::new();
7480
let mut names = HashMap::<StrBuf, @ast::Expr>::new();
@@ -80,22 +86,31 @@ fn parse_args(ecx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
8086
.map(|x| (*x).clone())
8187
.collect());
8288
// Parse the leading function expression (maybe a block, maybe a path)
83-
let extra = p.parse_expr();
89+
let invocation = if allow_method {
90+
let e = p.parse_expr();
91+
if !p.eat(&token::COMMA) {
92+
ecx.span_err(sp, "expected token: `,`");
93+
return (Call(e), None);
94+
}
95+
MethodCall(e, p.parse_ident())
96+
} else {
97+
Call(p.parse_expr())
98+
};
8499
if !p.eat(&token::COMMA) {
85100
ecx.span_err(sp, "expected token: `,`");
86-
return (extra, None);
101+
return (invocation, None);
87102
}
88103

89104
if p.token == token::EOF {
90105
ecx.span_err(sp, "requires at least a format string argument");
91-
return (extra, None);
106+
return (invocation, None);
92107
}
93108
let fmtstr = p.parse_expr();
94109
let mut named = false;
95110
while p.token != token::EOF {
96111
if !p.eat(&token::COMMA) {
97112
ecx.span_err(sp, "expected token: `,`");
98-
return (extra, None);
113+
return (invocation, None);
99114
}
100115
if p.token == token::EOF { break } // accept trailing commas
101116
if named || (token::is_ident(&p.token) &&
@@ -110,13 +125,13 @@ fn parse_args(ecx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
110125
ecx.span_err(p.span,
111126
"expected ident, positional arguments \
112127
cannot follow named arguments");
113-
return (extra, None);
128+
return (invocation, None);
114129
}
115130
_ => {
116131
ecx.span_err(p.span,
117132
format!("expected ident for named argument, but found `{}`",
118133
p.this_token_to_str()));
119-
return (extra, None);
134+
return (invocation, None);
120135
}
121136
};
122137
let interned_name = token::get_ident(ident);
@@ -137,7 +152,7 @@ fn parse_args(ecx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
137152
args.push(p.parse_expr());
138153
}
139154
}
140-
return (extra, Some((fmtstr, args, order, names)));
155+
return (invocation, Some((fmtstr, args, order, names)));
141156
}
142157

143158
impl<'a, 'b> Context<'a, 'b> {
@@ -595,7 +610,7 @@ impl<'a, 'b> Context<'a, 'b> {
595610

596611
/// Actually builds the expression which the iformat! block will be expanded
597612
/// to
598-
fn to_expr(&self, extra: @ast::Expr) -> @ast::Expr {
613+
fn to_expr(&self, invocation: Invocation) -> @ast::Expr {
599614
let mut lets = Vec::new();
600615
let mut locals = Vec::new();
601616
let mut names = Vec::from_fn(self.name_positions.len(), |_| None);
@@ -699,8 +714,16 @@ impl<'a, 'b> Context<'a, 'b> {
699714
let resname = self.ecx.ident_of("__args");
700715
lets.push(self.ecx.stmt_let(self.fmtsp, false, resname, result));
701716
let res = self.ecx.expr_ident(self.fmtsp, resname);
702-
let result = self.ecx.expr_call(extra.span, extra, vec!(
703-
self.ecx.expr_addr_of(extra.span, res)));
717+
let result = match invocation {
718+
Call(e) => {
719+
self.ecx.expr_call(e.span, e,
720+
vec!(self.ecx.expr_addr_of(e.span, res)))
721+
}
722+
MethodCall(e, m) => {
723+
self.ecx.expr_method_call(e.span, e, m,
724+
vec!(self.ecx.expr_addr_of(e.span, res)))
725+
}
726+
};
704727
let body = self.ecx.expr_block(self.ecx.block(self.fmtsp, lets,
705728
Some(result)));
706729

@@ -794,13 +817,25 @@ impl<'a, 'b> Context<'a, 'b> {
794817
}
795818
}
796819

797-
pub fn expand_args(ecx: &mut ExtCtxt, sp: Span,
798-
tts: &[ast::TokenTree]) -> Box<base::MacResult> {
820+
pub fn expand_format_args(ecx: &mut ExtCtxt, sp: Span,
821+
tts: &[ast::TokenTree]) -> Box<base::MacResult> {
822+
823+
match parse_args(ecx, sp, false, tts) {
824+
(invocation, Some((efmt, args, order, names))) => {
825+
MacExpr::new(expand_preparsed_format_args(ecx, sp, invocation, efmt,
826+
args, order, names))
827+
}
828+
(_, None) => MacExpr::new(ecx.expr_uint(sp, 2))
829+
}
830+
}
831+
832+
pub fn expand_format_args_method(ecx: &mut ExtCtxt, sp: Span,
833+
tts: &[ast::TokenTree]) -> Box<base::MacResult> {
799834

800-
match parse_args(ecx, sp, tts) {
801-
(extra, Some((efmt, args, order, names))) => {
802-
MacExpr::new(expand_preparsed_format_args(ecx, sp, extra, efmt, args,
803-
order, names))
835+
match parse_args(ecx, sp, true, tts) {
836+
(invocation, Some((efmt, args, order, names))) => {
837+
MacExpr::new(expand_preparsed_format_args(ecx, sp, invocation, efmt,
838+
args, order, names))
804839
}
805840
(_, None) => MacExpr::new(ecx.expr_uint(sp, 2))
806841
}
@@ -810,7 +845,7 @@ pub fn expand_args(ecx: &mut ExtCtxt, sp: Span,
810845
/// name=names...)` and construct the appropriate formatting
811846
/// expression.
812847
pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
813-
extra: @ast::Expr,
848+
invocation: Invocation,
814849
efmt: @ast::Expr, args: Vec<@ast::Expr>,
815850
name_ordering: Vec<StrBuf>,
816851
names: HashMap<StrBuf, @ast::Expr>) -> @ast::Expr {
@@ -869,5 +904,5 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
869904
}
870905
}
871906

872-
cx.to_expr(extra)
907+
cx.to_expr(invocation)
873908
}

0 commit comments

Comments
 (0)