about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@mozilla.com>2012-11-16 14:50:35 -0800
committerGraydon Hoare <graydon@mozilla.com>2012-11-16 14:50:49 -0800
commit5005be67cc4efb54adf6f68dbaa86d7f2ca14391 (patch)
tree91de5ee034f647a86b251f31763c687496b3d6f4 /src/libsyntax
parent2bf6663cf0864a16c75b95f69a9c2cb37ea485f6 (diff)
downloadrust-5005be67cc4efb54adf6f68dbaa86d7f2ca14391.tar.gz
rust-5005be67cc4efb54adf6f68dbaa86d7f2ca14391.zip
syntax: rename quote! to quote_tokens!, add quote_{expr,type,item,pat,stmt}!
r=brson, Close #3976.
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ext/base.rs17
-rw-r--r--src/libsyntax/ext/quote.rs133
2 files changed, 122 insertions, 28 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 3f5d0f13b31..eb4026c08d9 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -96,8 +96,21 @@ fn syntax_expander_table() -> HashMap<~str, syntax_extension> {
                                 ext::log_syntax::expand_syntax_ext));
     syntax_expanders.insert(~"ast",
                             builtin(ext::qquote::expand_ast));
-    syntax_expanders.insert(~"quote",
-                            builtin_expr_tt(ext::quote::expand_quote));
+
+    // Quasi-quoting expanders
+    syntax_expanders.insert(~"quote_tokens",
+                            builtin_expr_tt(ext::quote::expand_quote_tokens));
+    syntax_expanders.insert(~"quote_expr",
+                            builtin_expr_tt(ext::quote::expand_quote_expr));
+    syntax_expanders.insert(~"quote_type",
+                            builtin_expr_tt(ext::quote::expand_quote_type));
+    syntax_expanders.insert(~"quote_item",
+                            builtin_expr_tt(ext::quote::expand_quote_item));
+    syntax_expanders.insert(~"quote_pat",
+                            builtin_expr_tt(ext::quote::expand_quote_pat));
+    syntax_expanders.insert(~"quote_stmt",
+                            builtin_expr_tt(ext::quote::expand_quote_stmt));
+
     syntax_expanders.insert(~"line",
                             builtin(ext::source_util::expand_line));
     syntax_expanders.insert(~"col",
diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs
index 68a3c4a1399..db77166bfe3 100644
--- a/src/libsyntax/ext/quote.rs
+++ b/src/libsyntax/ext/quote.rs
@@ -16,33 +16,54 @@ use token::*;
 *
 */
 
-pub fn expand_quote(cx: ext_ctxt,
-                    sp: span,
-                    tts: ~[ast::token_tree]) -> base::mac_result
-{
+pub mod rt {
+    pub use ast::*;
+    pub use parse::token::*;
+    pub use parse::new_parser_from_tt;
+}
 
-    // NB: It appears that the main parser loses its mind if we consider
-    // $foo as a tt_nonterminal during the main parse, so we have to re-parse
-    // under quote_depth > 0. This is silly and should go away; the _guess_ is
-    // it has to do with transition away from supporting old-style macros, so
-    // try removing it when enough of them are gone.
-    let p = parse::new_parser_from_tt(cx.parse_sess(), cx.cfg(), tts);
-    p.quote_depth += 1u;
-    let tq = dvec::DVec();
-    while p.token != token::EOF {
-        tq.push(p.parse_token_tree());
-    }
-    let tts = tq.get();
+pub fn expand_quote_tokens(cx: ext_ctxt,
+                           sp: span,
+                           tts: ~[ast::token_tree]) -> base::mac_result {
+    base::mr_expr(expand_tt(cx, sp, tts))
+}
 
-    // We want to emit a block expression that does a sequence of 'use's to
-    // import the AST and token constructors, followed by a tt expression.
-    let uses = ~[ build::mk_glob_use(cx, sp, ids_ext(cx, ~[~"syntax",
-                                                           ~"ast"])),
-                  build::mk_glob_use(cx, sp, ids_ext(cx, ~[~"syntax",
-                                                           ~"parse",
-                                                           ~"token"])) ];
-    base::mr_expr(build::mk_block(cx, sp, uses, ~[],
-                                  Some(mk_tt(cx, sp, &ast::tt_delim(tts)))))
+pub fn expand_quote_expr(cx: ext_ctxt,
+                         sp: span,
+                         tts: ~[ast::token_tree]) -> base::mac_result {
+    base::mr_expr(expand_parse_call(cx, sp, ~"parse_expr", ~[], tts))
+}
+
+pub fn expand_quote_item(cx: ext_ctxt,
+                         sp: span,
+                         tts: ~[ast::token_tree]) -> base::mac_result {
+    let e_attrs = build::mk_uniq_vec_e(cx, sp, ~[]);
+    base::mr_expr(expand_parse_call(cx, sp, ~"parse_item",
+                                    ~[e_attrs], tts))
+}
+
+pub fn expand_quote_pat(cx: ext_ctxt,
+                        sp: span,
+                        tts: ~[ast::token_tree]) -> base::mac_result {
+    let e_refutable = build::mk_lit(cx, sp, ast::lit_bool(true));
+    base::mr_expr(expand_parse_call(cx, sp, ~"parse_pat",
+                                    ~[e_refutable], tts))
+}
+
+pub fn expand_quote_type(cx: ext_ctxt,
+                         sp: span,
+                         tts: ~[ast::token_tree]) -> base::mac_result {
+    let e_param_colons = build::mk_lit(cx, sp, ast::lit_bool(false));
+    base::mr_expr(expand_parse_call(cx, sp, ~"parse_type",
+                                    ~[e_param_colons], tts))
+}
+
+pub fn expand_quote_stmt(cx: ext_ctxt,
+                         sp: span,
+                         tts: ~[ast::token_tree]) -> base::mac_result {
+    let e_attrs = build::mk_uniq_vec_e(cx, sp, ~[]);
+    base::mr_expr(expand_parse_call(cx, sp, ~"parse_stmt",
+                                    ~[e_attrs], tts))
 }
 
 fn ids_ext(cx: ext_ctxt, strs: ~[~str]) -> ~[ast::ident] {
@@ -304,4 +325,64 @@ fn mk_tt(cx: ext_ctxt, sp: span, tt: &ast::token_tree) -> @ast::expr {
         ast::tt_nonterminal(sp, ident) =>
         build::mk_copy(cx, sp, build::mk_path(cx, sp, ~[ident]))
     }
-}
\ No newline at end of file
+}
+
+
+fn expand_tt(cx: ext_ctxt,
+             sp: span,
+             tts: ~[ast::token_tree]) -> @ast::expr {
+    // NB: It appears that the main parser loses its mind if we consider
+    // $foo as a tt_nonterminal during the main parse, so we have to re-parse
+    // under quote_depth > 0. This is silly and should go away; the _guess_ is
+    // it has to do with transition away from supporting old-style macros, so
+    // try removing it when enough of them are gone.
+    let p = parse::new_parser_from_tt(cx.parse_sess(), cx.cfg(), tts);
+    p.quote_depth += 1u;
+    let tq = dvec::DVec();
+    while p.token != token::EOF {
+        tq.push(p.parse_token_tree());
+    }
+    let tts = tq.get();
+
+    // We want to emit a block expression that does a sequence of 'use's to
+    // import the runtime module, followed by a tt expression.
+    let uses = ~[ build::mk_glob_use(cx, sp, ids_ext(cx, ~[~"syntax",
+                                                           ~"ext",
+                                                           ~"quote",
+                                                           ~"rt"])) ];
+    build::mk_block(cx, sp, uses, ~[],
+                    Some(mk_tt(cx, sp, &ast::tt_delim(tts))))
+}
+
+fn expand_parse_call(cx: ext_ctxt,
+                     sp: span,
+                     parse_method: ~str,
+                     arg_exprs: ~[@ast::expr],
+                     tts: ~[ast::token_tree]) -> @ast::expr {
+    let tt_expr = expand_tt(cx, sp, tts);
+
+    let cfg_call = || build::mk_call_(
+        cx, sp, build::mk_access(cx, sp, ids_ext(cx, ~[~"ext_cx"]),
+                                 id_ext(cx, ~"cfg")), ~[]);
+
+    let parse_sess_call = || build::mk_call_(
+        cx, sp, build::mk_access(cx, sp, ids_ext(cx, ~[~"ext_cx"]),
+                                 id_ext(cx, ~"parse_sess")), ~[]);
+
+    let new_parser_call =
+        build::mk_call(cx, sp,
+                       ids_ext(cx, ~[~"syntax",
+                                     ~"ext",
+                                     ~"quote",
+                                     ~"rt",
+                                     ~"new_parser_from_tt"]),
+                       ~[parse_sess_call(),
+                         cfg_call(),
+                         build::mk_uniq_vec_e(cx, sp, ~[tt_expr])]);
+
+    build::mk_call_(cx, sp,
+                    build::mk_access_(cx, sp, new_parser_call,
+                                      id_ext(cx, parse_method)),
+                    arg_exprs)
+}
+