Skip to content

Commit 7129883

Browse files
committed
Allow interpolations of all the nt_*s.
1 parent 0646890 commit 7129883

File tree

3 files changed

+56
-11
lines changed

3 files changed

+56
-11
lines changed

src/libsyntax/ext/tt/macro_rules.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@ fn add_new_extension(cx: ext_ctxt, sp: span, name: ident,
2424
ms(match_nonterminal(@~"lhs",@~"matchers", 0u)),
2525
ms(match_tok(FAT_ARROW)),
2626
ms(match_nonterminal(@~"rhs",@~"tt", 1u)),
27-
], some(SEMI), false, 0u, 2u))];
27+
], some(SEMI), false, 0u, 2u)),
28+
//to phase into semicolon-termination instead of
29+
//semicolon-separation
30+
ms(match_seq(~[ms(match_tok(SEMI))], none, true, 2u, 2u))];
2831

2932

3033
// Parse the macro_rules! invocation (`none` is for no interpolations):

src/libsyntax/parse/parser.rs

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -120,22 +120,28 @@ macro_rules! maybe_whole_expr {
120120
}
121121

122122
macro_rules! maybe_whole {
123-
{$p:expr, $constructor:path} => { alt copy $p.token {
124-
INTERPOLATED($constructor(x)) { $p.bump(); return x; }
123+
{$p:expr, $constructor:ident} => { alt copy $p.token {
124+
INTERPOLATED(token::$constructor(x)) { $p.bump(); return x; }
125+
_ {}
126+
}} ;
127+
{deref $p:expr, $constructor:ident} => { alt copy $p.token {
128+
INTERPOLATED(token::$constructor(x)) { $p.bump(); return *x; }
129+
_ {}
130+
}} ;
131+
{some $p:expr, $constructor:ident} => { alt copy $p.token {
132+
INTERPOLATED(token::$constructor(x)) { $p.bump(); return some(x); }
133+
_ {}
134+
}} ;
135+
{pair_empty $p:expr, $constructor:ident} => { alt copy $p.token {
136+
INTERPOLATED(token::$constructor(x)) { $p.bump(); return (~[], x); }
125137
_ {}
126138
}}
139+
127140
}
128141

129-
/* ident is handled by common.rs */
130142

131-
fn dummy() {
132-
/* we will need this to bootstrap maybe_whole! */
133-
#macro[[#maybe_whole_path[p],
134-
alt p.token {
135-
INTERPOLATED(token::nt_path(pt)) { p.bump(); return pt; }
136-
_ {} }]];
137-
}
138143

144+
/* ident is handled by common.rs */
139145

140146
class parser {
141147
let sess: parse_sess;
@@ -389,6 +395,8 @@ class parser {
389395
}
390396

391397
fn parse_ty(colons_before_params: bool) -> @ty {
398+
maybe_whole!{self, nt_ty};
399+
392400
let lo = self.span.lo;
393401

394402
alt self.maybe_parse_dollar_mac() {
@@ -610,6 +618,7 @@ class parser {
610618
parse_ident: fn(parser) -> ident,
611619
parse_last_ident: fn(parser) -> ident) -> @path {
612620

621+
maybe_whole!{self, nt_path};
613622
let lo = self.span.lo;
614623
let global = self.eat(token::MOD_SEP);
615624
let mut ids = ~[];
@@ -638,6 +647,7 @@ class parser {
638647
fn parse_path_with_tps(colons: bool) -> @path {
639648
debug!{"parse_path_with_tps(colons=%b)", colons};
640649

650+
maybe_whole!{self, nt_path};
641651
let lo = self.span.lo;
642652
let path = self.parse_path_without_tps();
643653
if colons && !self.eat(token::MOD_SEP) {
@@ -1067,6 +1077,8 @@ class parser {
10671077
}
10681078

10691079
fn parse_token_tree() -> token_tree {
1080+
maybe_whole!{deref self, nt_tt};
1081+
10701082
fn parse_tt_tok(p: parser, delim_ok: bool) -> token_tree {
10711083
alt p.token {
10721084
token::RPAREN | token::RBRACE | token::RBRACKET
@@ -1115,6 +1127,9 @@ class parser {
11151127
}
11161128
11171129
fn parse_matchers() -> ~[matcher] {
1130+
// unification of matchers and token_trees would vastly improve
1131+
// the interpolation of matchers
1132+
maybe_whole!{self, nt_matchers};
11181133
let name_idx = @mut 0u;
11191134
return self.parse_matcher_subseq(
11201135
name_idx, token::LBRACE, token::RBRACE);
@@ -1601,6 +1616,8 @@ class parser {
16011616
}
16021617
16031618
fn parse_pat(refutable: bool) -> @pat {
1619+
maybe_whole!{self, nt_pat};
1620+
16041621
let lo = self.span.lo;
16051622
let mut hi = self.span.hi;
16061623
let mut pat;
@@ -1830,6 +1847,8 @@ class parser {
18301847
}
18311848

18321849
fn parse_stmt(+first_item_attrs: ~[attribute]) -> @stmt {
1850+
maybe_whole!{self, nt_stmt};
1851+
18331852
fn check_expected_item(p: parser, current_attrs: ~[attribute]) {
18341853
// If we have attributes then we should have an item
18351854
if vec::is_not_empty(current_attrs) {
@@ -1890,6 +1909,8 @@ class parser {
18901909
fn parse_inner_attrs_and_block(parse_attrs: bool)
18911910
-> (~[attribute], blk) {
18921911

1912+
maybe_whole!{pair_empty self, nt_block};
1913+
18931914
fn maybe_parse_inner_attrs_and_next(p: parser, parse_attrs: bool) ->
18941915
{inner: ~[attribute], next: ~[attribute]} {
18951916
if parse_attrs {
@@ -2735,6 +2756,8 @@ class parser {
27352756

27362757
fn parse_item(+attrs: ~[attribute], vis: visibility)
27372758
-> option<@item> {
2759+
2760+
maybe_whole!{some self,nt_item};
27382761
let lo = self.span.lo;
27392762
let (ident, item_, extra_attrs) = if self.eat_keyword(~"const") {
27402763
self.parse_item_const()
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
macro_rules! overly_complicated {
3+
{$fnname:ident, $arg:ident, $ty:ty, $body:block, $val:expr, $pat:pat, $res:path} =>
4+
{
5+
fn $fnname($arg: $ty) -> option<$ty> $body
6+
alt $fnname($val) {
7+
some($pat) {
8+
$res
9+
}
10+
_ { fail; }
11+
}
12+
}
13+
14+
}
15+
fn main() {
16+
assert overly_complicated!(f, x, option<uint>, { return some(x); },
17+
some(8u), some(y), y) == 8u
18+
19+
}

0 commit comments

Comments
 (0)