diff options
| author | bors <bors@rust-lang.org> | 2014-07-30 13:01:10 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-07-30 13:01:10 +0000 |
| commit | 3ab170ffc5e45d31eef85db8fd7a3b68764f77c2 (patch) | |
| tree | 8146c564ee7c93820cb78da85b9cd9f1d51cc081 /src/libsyntax/ext | |
| parent | 692077b6431460b96beb0ccf4f38299618d51db2 (diff) | |
| parent | e841a88b9298b0d1fef93192d8e163b44645fc73 (diff) | |
| download | rust-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.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/ext/build.rs | 52 | ||||
| -rw-r--r-- | src/libsyntax/ext/quote.rs | 12 |
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]) |
