about summary refs log tree commit diff
path: root/src/libsyntax/ext
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-07-30 13:01:10 +0000
committerbors <bors@rust-lang.org>2014-07-30 13:01:10 +0000
commit3ab170ffc5e45d31eef85db8fd7a3b68764f77c2 (patch)
tree8146c564ee7c93820cb78da85b9cd9f1d51cc081 /src/libsyntax/ext
parent692077b6431460b96beb0ccf4f38299618d51db2 (diff)
parente841a88b9298b0d1fef93192d8e163b44645fc73 (diff)
downloadrust-3ab170ffc5e45d31eef85db8fd7a3b68764f77c2.tar.gz
rust-3ab170ffc5e45d31eef85db8fd7a3b68764f77c2.zip
auto merge of #16037 : erickt/rust/quote_arm, r=acrichto
This adds support for `quote_arm!(cx, $pat => $expr)`, and `macro_rules!(($a:arm) => (...))`. It also fixes a bug in pretty printing, where this would generate invalid code:

```
match { 5i } {
    1 => 2,
    _ => 3,
}
```

It would generate this code:

```
match { 5i } {
    1 => 2
    _ => 3
}
```

Finally, it adds a couple helper methods to `ExtCtxt`.
Diffstat (limited to 'src/libsyntax/ext')
-rw-r--r--src/libsyntax/ext/base.rs3
-rw-r--r--src/libsyntax/ext/build.rs52
-rw-r--r--src/libsyntax/ext/quote.rs12
3 files changed, 67 insertions, 0 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index a66d6839ab0..d00406e07b7 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -382,6 +382,9 @@ fn initial_syntax_expander_table() -> SyntaxEnv {
     syntax_expanders.insert(intern("quote_pat"),
                        builtin_normal_expander(
                             ext::quote::expand_quote_pat));
+    syntax_expanders.insert(intern("quote_arm"),
+                       builtin_normal_expander(
+                            ext::quote::expand_quote_arm));
     syntax_expanders.insert(intern("quote_stmt"),
                        builtin_normal_expander(
                             ext::quote::expand_quote_stmt));
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 7d683382589..6c9e113f41a 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -170,6 +170,13 @@ pub trait AstBuilder {
                 subpats: Vec<Gc<ast::Pat>>) -> Gc<ast::Pat>;
     fn pat_struct(&self, span: Span,
                   path: ast::Path, field_pats: Vec<ast::FieldPat> ) -> Gc<ast::Pat>;
+    fn pat_tuple(&self, span: Span, pats: Vec<Gc<ast::Pat>>) -> Gc<ast::Pat>;
+
+    fn pat_some(&self, span: Span, pat: Gc<ast::Pat>) -> Gc<ast::Pat>;
+    fn pat_none(&self, span: Span) -> Gc<ast::Pat>;
+
+    fn pat_ok(&self, span: Span, pat: Gc<ast::Pat>) -> Gc<ast::Pat>;
+    fn pat_err(&self, span: Span, pat: Gc<ast::Pat>) -> Gc<ast::Pat>;
 
     fn arm(&self, span: Span, pats: Vec<Gc<ast::Pat>> , expr: Gc<ast::Expr>) -> ast::Arm;
     fn arm_unreachable(&self, span: Span) -> ast::Arm;
@@ -178,6 +185,7 @@ pub trait AstBuilder {
     fn expr_if(&self, span: Span,
                cond: Gc<ast::Expr>, then: Gc<ast::Expr>,
                els: Option<Gc<ast::Expr>>) -> Gc<ast::Expr>;
+    fn expr_loop(&self, span: Span, block: P<ast::Block>) -> Gc<ast::Expr>;
 
     fn lambda_fn_decl(&self, span: Span,
                       fn_decl: P<ast::FnDecl>, blk: P<ast::Block>) -> Gc<ast::Expr>;
@@ -777,6 +785,46 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
         let pat = ast::PatStruct(path, field_pats, false);
         self.pat(span, pat)
     }
+    fn pat_tuple(&self, span: Span, pats: Vec<Gc<ast::Pat>>) -> Gc<ast::Pat> {
+        let pat = ast::PatTup(pats);
+        self.pat(span, pat)
+    }
+
+    fn pat_some(&self, span: Span, pat: Gc<ast::Pat>) -> Gc<ast::Pat> {
+        let some = vec!(
+            self.ident_of("std"),
+            self.ident_of("option"),
+            self.ident_of("Some"));
+        let path = self.path_global(span, some);
+        self.pat_enum(span, path, vec!(pat))
+    }
+
+    fn pat_none(&self, span: Span) -> Gc<ast::Pat> {
+        let some = vec!(
+            self.ident_of("std"),
+            self.ident_of("option"),
+            self.ident_of("None"));
+        let path = self.path_global(span, some);
+        self.pat_enum(span, path, vec!())
+    }
+
+    fn pat_ok(&self, span: Span, pat: Gc<ast::Pat>) -> Gc<ast::Pat> {
+        let some = vec!(
+            self.ident_of("std"),
+            self.ident_of("result"),
+            self.ident_of("Ok"));
+        let path = self.path_global(span, some);
+        self.pat_enum(span, path, vec!(pat))
+    }
+
+    fn pat_err(&self, span: Span, pat: Gc<ast::Pat>) -> Gc<ast::Pat> {
+        let some = vec!(
+            self.ident_of("std"),
+            self.ident_of("result"),
+            self.ident_of("Err"));
+        let path = self.path_global(span, some);
+        self.pat_enum(span, path, vec!(pat))
+    }
 
     fn arm(&self, _span: Span, pats: Vec<Gc<ast::Pat>> , expr: Gc<ast::Expr>) -> ast::Arm {
         ast::Arm {
@@ -803,6 +851,10 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
         self.expr(span, ast::ExprIf(cond, self.block_expr(then), els))
     }
 
+    fn expr_loop(&self, span: Span, block: P<ast::Block>) -> Gc<ast::Expr> {
+        self.expr(span, ast::ExprLoop(block, None))
+    }
+
     fn lambda_fn_decl(&self, span: Span,
                       fn_decl: P<ast::FnDecl>, blk: P<ast::Block>) -> Gc<ast::Expr> {
         self.expr(span, ast::ExprFnBlock(fn_decl, blk))
diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs
index a7ede6f742d..dcfb0198127 100644
--- a/src/libsyntax/ext/quote.rs
+++ b/src/libsyntax/ext/quote.rs
@@ -144,8 +144,10 @@ pub mod rt {
     impl_to_source!(Generics, generics_to_string)
     impl_to_source!(Gc<ast::Item>, item_to_string)
     impl_to_source!(Gc<ast::Method>, method_to_string)
+    impl_to_source!(Gc<ast::Stmt>, stmt_to_string)
     impl_to_source!(Gc<ast::Expr>, expr_to_string)
     impl_to_source!(Gc<ast::Pat>, pat_to_string)
+    impl_to_source!(ast::Arm, arm_to_string)
     impl_to_source_slice!(ast::Ty, ", ")
     impl_to_source_slice!(Gc<ast::Item>, "\n\n")
 
@@ -239,11 +241,13 @@ pub mod rt {
     impl_to_tokens!(ast::Ident)
     impl_to_tokens!(Gc<ast::Item>)
     impl_to_tokens!(Gc<ast::Pat>)
+    impl_to_tokens!(ast::Arm)
     impl_to_tokens!(Gc<ast::Method>)
     impl_to_tokens_lifetime!(&'a [Gc<ast::Item>])
     impl_to_tokens!(ast::Ty)
     impl_to_tokens_lifetime!(&'a [ast::Ty])
     impl_to_tokens!(Generics)
+    impl_to_tokens!(Gc<ast::Stmt>)
     impl_to_tokens!(Gc<ast::Expr>)
     impl_to_tokens!(ast::Block)
     impl_to_tokens!(ast::Arg)
@@ -345,6 +349,14 @@ pub fn expand_quote_pat(cx: &mut ExtCtxt,
     base::MacExpr::new(expanded)
 }
 
+pub fn expand_quote_arm(cx: &mut ExtCtxt,
+                        sp: Span,
+                        tts: &[ast::TokenTree])
+                        -> Box<base::MacResult> {
+    let expanded = expand_parse_call(cx, sp, "parse_arm", vec!(), tts);
+    base::MacExpr::new(expanded)
+}
+
 pub fn expand_quote_ty(cx: &mut ExtCtxt,
                        sp: Span,
                        tts: &[ast::TokenTree])