diff options
| author | Paul Stansifer <paul.stansifer@gmail.com> | 2012-11-08 23:12:45 -0500 |
|---|---|---|
| committer | Graydon Hoare <graydon@mozilla.com> | 2012-11-29 12:09:10 -0800 |
| commit | fca52554e7e3b3eff0aaf8686fe4616628577ade (patch) | |
| tree | cf48e7031d7943d2bc5cd9eafc56c7abd8975a15 /src/libsyntax | |
| parent | cafea5ecb69ad9439502426a69e5d297c4525758 (diff) | |
| download | rust-fca52554e7e3b3eff0aaf8686fe4616628577ade.tar.gz rust-fca52554e7e3b3eff0aaf8686fe4616628577ade.zip | |
Make it possible to invoke item macros without passing identifier arguments.
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ext/base.rs | 15 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 63 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/macro_rules.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 6 |
4 files changed, 55 insertions, 33 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 9a642818a53..3701614f137 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -12,7 +12,7 @@ use ast_util::dummy_sp; // new-style macro! tt code: // // syntax_expander_tt, syntax_expander_tt_item, mac_result, -// expr_tt, item_tt +// normal_tt, item_tt // // also note that ast::mac has way too many cases and can probably // be trimmed down substantially. @@ -60,7 +60,10 @@ enum syntax_extension { item_decorator(item_decorator), // Token-tree expanders - expr_tt(syntax_expander_tt), + normal_tt(syntax_expander_tt), + + // perhaps macro_rules! will lose its odd special identifier argument, + // and this can go away also item_tt(syntax_expander_tt_item), } @@ -69,8 +72,8 @@ enum syntax_extension { fn syntax_expander_table() -> HashMap<~str, syntax_extension> { fn builtin(f: syntax_expander_) -> syntax_extension {normal({expander: f, span: None})} - fn builtin_expr_tt(f: syntax_expander_tt_) -> syntax_extension { - expr_tt({expander: f, span: None}) + fn builtin_normal_tt(f: syntax_expander_tt_) -> syntax_extension { + normal_tt({expander: f, span: None}) } fn builtin_item_tt(f: syntax_expander_tt_item_) -> syntax_extension { item_tt({expander: f, span: None}) @@ -94,7 +97,7 @@ fn syntax_expander_table() -> HashMap<~str, syntax_extension> { syntax_expanders.insert(~"ident_to_str", builtin(ext::ident_to_str::expand_syntax_ext)); syntax_expanders.insert(~"log_syntax", - builtin_expr_tt( + builtin_normal_tt( ext::log_syntax::expand_syntax_ext)); syntax_expanders.insert(~"ast", builtin(ext::qquote::expand_ast)); @@ -139,7 +142,7 @@ fn syntax_expander_table() -> HashMap<~str, syntax_extension> { builtin_item_tt(ext::pipes::expand_proto)); syntax_expanders.insert( ~"trace_macros", - builtin_expr_tt(ext::trace_macros::expand_trace_macros)); + builtin_normal_tt(ext::trace_macros::expand_trace_macros)); return syntax_expanders; } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 26fbc3be16c..c296938d5d2 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -54,7 +54,7 @@ fn expand_expr(exts: HashMap<~str, syntax_extension>, cx: ext_ctxt, exts.insert(named_extension.name, named_extension.ext); (ast::expr_rec(~[], None), s) } - Some(expr_tt(_)) => { + Some(normal_tt(_)) => { cx.span_fatal(pth.span, fmt!("this tt-style macro should be \ invoked '%s!(...)'", *extname)) @@ -78,7 +78,7 @@ fn expand_expr(exts: HashMap<~str, syntax_extension>, cx: ext_ctxt, cx.span_fatal(pth.span, fmt!("macro undefined: '%s'", *extname)) } - Some(expr_tt({expander: exp, span: exp_sp})) => { + Some(normal_tt({expander: exp, span: exp_sp})) => { let expanded = match exp(cx, mac.span, tts) { mr_expr(e) => e, mr_expr_or_item(expr_maker,_) => expr_maker(), @@ -153,7 +153,7 @@ fn expand_mod_items(exts: HashMap<~str, syntax_extension>, cx: ext_ctxt, }; match exts.find(mname) { None | Some(normal(_)) | Some(macro_defining(_)) - | Some(expr_tt(_)) | Some(item_tt(*)) => items, + | Some(normal_tt(_)) | Some(item_tt(*)) => items, Some(item_decorator(dec_fn)) => { dec_fn(cx, attr.span, attr.node.value, items) } @@ -200,34 +200,49 @@ fn expand_item_mac(exts: HashMap<~str, syntax_extension>, match it.node { item_mac({node: mac_invoc_tt(pth, tts), _}) => { let extname = cx.parse_sess().interner.get(pth.idents[0]); - match exts.find(*extname) { + let (expanded, ex_span) = match exts.find(*extname) { None => { cx.span_fatal(pth.span, - fmt!("macro undefined: '%s'", *extname)) + fmt!("macro undefined: '%s!'", *extname)) + } + Some(normal_tt(expand)) => { + if it.ident != parse::token::special_idents::invalid { + cx.span_fatal(pth.span, + fmt!("macro %s! expects no ident argument, \ + given '%s'", *extname, + *cx.parse_sess().interner.get(it.ident))); + } + (expand.expander(cx, it.span, tts), expand.span) } Some(item_tt(expand)) => { - let expanded = expand.expander(cx, it.span, it.ident, tts); - cx.bt_push(ExpandedFrom({call_site: it.span, - callie: {name: *extname, - span: expand.span}})); - let maybe_it = match expanded { - mr_item(it) => fld.fold_item(it), - mr_expr(_) => cx.span_fatal(pth.span, - ~"expr macro in item position: " + - *extname), - mr_expr_or_item(_, item_maker) => - option::chain(item_maker(), |i| {fld.fold_item(i)}), - mr_def(mdef) => { - exts.insert(mdef.name, mdef.ext); - None - } - }; - cx.bt_pop(); - return maybe_it + if it.ident == parse::token::special_idents::invalid { + cx.span_fatal(pth.span, + fmt!("macro %s! expects an ident argument", + *extname)); + } + (expand.expander(cx, it.span, it.ident, tts), expand.span) } _ => cx.span_fatal( it.span, fmt!("%s! is not legal in item position", *extname)) - } + }; + + cx.bt_push(ExpandedFrom({call_site: it.span, + callie: {name: *extname, + span: ex_span}})); + let maybe_it = match expanded { + mr_item(it) => fld.fold_item(it), + mr_expr(_) => cx.span_fatal(pth.span, + ~"expr macro in item position: " + + *extname), + mr_expr_or_item(_, item_maker) => + option::chain(item_maker(), |i| {fld.fold_item(i)}), + mr_def(mdef) => { + exts.insert(mdef.name, mdef.ext); + None + } + }; + cx.bt_pop(); + return maybe_it; } _ => cx.span_bug(it.span, ~"invalid item macro invocation") } diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 7957cde8fdc..012e421718a 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -1,4 +1,4 @@ -use base::{ext_ctxt, mac_result, mr_expr_or_item, mr_def, expr_tt}; +use base::{ext_ctxt, mac_result, mr_expr_or_item, mr_def, normal_tt}; use codemap::span; use ast::{ident, matcher_, matcher, match_tok, match_nonterminal, match_seq, tt_delim}; @@ -113,6 +113,6 @@ fn add_new_extension(cx: ext_ctxt, sp: span, name: ident, return mr_def({ name: *cx.parse_sess().interner.get(name), - ext: expr_tt({expander: exp, span: Some(sp)}) + ext: normal_tt({expander: exp, span: Some(sp)}) }); } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index e521a698da7..638a02775d9 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3534,7 +3534,11 @@ impl Parser { // item macro. let pth = self.parse_path_without_tps(); self.expect(token::NOT); - let id = self.parse_ident(); + let id = if self.token == token::LPAREN { + token::special_idents::invalid // no special identifier + } else { + self.parse_ident() + }; let tts = match self.token { token::LPAREN | token::LBRACE => { let ket = token::flip_delimiter(copy self.token); |
