diff options
| author | Keegan McAllister <kmcallister@mozilla.com> | 2014-09-15 16:09:09 -0700 |
|---|---|---|
| committer | Keegan McAllister <kmcallister@mozilla.com> | 2015-01-05 11:38:12 -0800 |
| commit | 5e5924b79915326d81db2aebfe73d2a20b8506f1 (patch) | |
| tree | 16d55df447ad54f7d8a0dff9a900d12e7b091dd1 /src/libsyntax/ext | |
| parent | d1cf1b1e6bf0b33fe3bb9fa01d9d94f797c9f9fc (diff) | |
| download | rust-5e5924b79915326d81db2aebfe73d2a20b8506f1.tar.gz rust-5e5924b79915326d81db2aebfe73d2a20b8506f1.zip | |
Replace LetSyntaxTT with MacroRulesTT
The implementation of LetSyntaxTT was specialized to macro_rules! in various ways. This gets rid of the false generality and simplifies the code.
Diffstat (limited to 'src/libsyntax/ext')
| -rw-r--r-- | src/libsyntax/ext/base.rs | 12 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 54 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/macro_rules.rs | 21 |
3 files changed, 30 insertions, 57 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 91cc8a24622..4b38e6c0cb2 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -328,13 +328,8 @@ pub enum SyntaxExtension { /// IdentTT(Box<IdentMacroExpander + 'static>, Option<Span>), - /// An ident macro that has two properties: - /// - it adds a macro definition to the environment, and - /// - the definition it adds doesn't introduce any new - /// identifiers. - /// - /// `macro_rules!` is a LetSyntaxTT - LetSyntaxTT(Box<IdentMacroExpander + 'static>, Option<Span>), + /// Represents `macro_rules!` itself. + MacroRulesTT, } pub type NamedSyntaxExtension = (Name, SyntaxExtension); @@ -364,8 +359,7 @@ fn initial_syntax_expander_table(ecfg: &expand::ExpansionConfig) -> SyntaxEnv { } let mut syntax_expanders = SyntaxEnv::new(); - syntax_expanders.insert(intern("macro_rules"), - LetSyntaxTT(box ext::tt::macro_rules::add_new_extension, None)); + syntax_expanders.insert(intern("macro_rules"), MacroRulesTT); syntax_expanders.insert(intern("fmt"), builtin_normal_expander( ext::fmt::expand_syntax_ext)); diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index b3f30dd4581..a1a13f23064 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -7,7 +7,6 @@ // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. -use self::Either::*; use ast::{Block, Crate, DeclLocal, ExprMac, PatMac}; use ast::{Local, Ident, MacInvocTT}; @@ -18,6 +17,7 @@ use ast; use ast_util::path_to_ident; use ext::mtwt; use ext::build::AstBuilder; +use ext::tt::macro_rules; use attr; use attr::AttrMetaMethods; use codemap; @@ -33,11 +33,6 @@ use util::small_vector::SmallVector; use visit; use visit::Visitor; -enum Either<L,R> { - Left(L), - Right(R) -} - pub fn expand_type(t: P<ast::Ty>, fld: &mut MacroExpander, impl_ty: Option<P<ast::Ty>>) @@ -548,8 +543,8 @@ pub fn expand_item_mac(it: P<ast::Item>, fld: &mut MacroExpander) let extnamestr = token::get_ident(extname); let fm = fresh_mark(); - let def_or_items = { - let mut expanded = match fld.cx.syntax_env.find(&extname.name) { + let items = { + let expanded = match fld.cx.syntax_env.find(&extname.name) { None => { fld.cx.span_err(path_span, format!("macro undefined: '{}!'", @@ -600,11 +595,10 @@ pub fn expand_item_mac(it: P<ast::Item>, fld: &mut MacroExpander) let marked_tts = mark_tts(tts[], fm); expander.expand(fld.cx, it.span, it.ident, marked_tts) } - LetSyntaxTT(ref expander, span) => { + MacroRulesTT => { if it.ident.name == parse::token::special_idents::invalid.name { fld.cx.span_err(path_span, - format!("macro {}! expects an ident argument", - extnamestr.get())[]); + format!("macro_rules! expects an ident argument")[]); return SmallVector::zero(); } fld.cx.bt_push(ExpnInfo { @@ -612,11 +606,21 @@ pub fn expand_item_mac(it: P<ast::Item>, fld: &mut MacroExpander) callee: NameAndSpan { name: extnamestr.get().to_string(), format: MacroBang, - span: span + span: None, } }); - // DON'T mark before expansion: - expander.expand(fld.cx, it.span, it.ident, tts) + // DON'T mark before expansion. + let MacroDef { name, ext } + = macro_rules::add_new_extension(fld.cx, it.span, it.ident, tts); + + fld.cx.syntax_env.insert(intern(name.as_slice()), ext); + if attr::contains_name(it.attrs.as_slice(), "macro_export") { + fld.cx.exported_macros.push(it); + } + + // macro_rules! has a side effect but expands to nothing. + fld.cx.bt_pop(); + return SmallVector::zero(); } _ => { fld.cx.span_err(it.span, @@ -627,31 +631,17 @@ pub fn expand_item_mac(it: P<ast::Item>, fld: &mut MacroExpander) } }; - match expanded.make_def() { - Some(def) => Left(def), - None => Right(expanded.make_items()) - } + expanded.make_items() }; - let items = match def_or_items { - Left(MacroDef { name, ext }) => { - // hidden invariant: this should only be possible as the - // result of expanding a LetSyntaxTT, and thus doesn't - // need to be marked. Not that it could be marked anyway. - // create issue to recommend refactoring here? - fld.cx.syntax_env.insert(intern(name[]), ext); - if attr::contains_name(it.attrs[], "macro_export") { - fld.cx.exported_macros.push(it); - } - SmallVector::zero() - } - Right(Some(items)) => { + let items = match items { + Some(items) => { items.into_iter() .map(|i| mark_item(i, fm)) .flat_map(|i| fld.fold_item(i).into_iter()) .collect() } - Right(None) => { + None => { fld.cx.span_err(path_span, format!("non-item macro in item position: {}", extnamestr.get())[]); diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 08014dc1338..15b75442ca2 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -129,15 +129,6 @@ impl TTMacroExpander for MacroRulesMacroExpander { } } -struct MacroRulesDefiner { - def: Option<MacroDef> -} -impl MacResult for MacroRulesDefiner { - fn make_def(&mut self) -> Option<MacroDef> { - Some(self.def.take().expect("empty MacroRulesDefiner")) - } -} - /// Given `lhses` and `rhses`, this is the new macro we create fn generic_extension<'cx>(cx: &'cx ExtCtxt, sp: Span, @@ -219,7 +210,7 @@ pub fn add_new_extension<'cx>(cx: &'cx mut ExtCtxt, sp: Span, name: Ident, arg: Vec<ast::TokenTree> ) - -> Box<MacResult+'cx> { + -> MacroDef { let lhs_nm = gensym_ident("lhs"); let rhs_nm = gensym_ident("rhs"); @@ -279,10 +270,8 @@ pub fn add_new_extension<'cx>(cx: &'cx mut ExtCtxt, rhses: rhses, }; - box MacroRulesDefiner { - def: Some(MacroDef { - name: token::get_ident(name).to_string(), - ext: NormalTT(exp, Some(sp)) - }) - } as Box<MacResult+'cx> + MacroDef { + name: token::get_ident(name).to_string(), + ext: NormalTT(exp, Some(sp)) + } } |
