about summary refs log tree commit diff
path: root/src/libsyntax/parse/parser.rs
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2013-10-28 15:22:49 -0700
committerPatrick Walton <pcwalton@mimiga.net>2013-10-29 10:34:17 -0700
commit7e77bf17694e31c741fe3a31c7eca5437d9cb6d5 (patch)
tree07fbf75c901955bc5b527929785e544829da92b0 /src/libsyntax/parse/parser.rs
parente6650c87a3800264a043b7f129e6a4841c4cc3f7 (diff)
downloadrust-7e77bf17694e31c741fe3a31c7eca5437d9cb6d5.tar.gz
rust-7e77bf17694e31c741fe3a31c7eca5437d9cb6d5.zip
librustc: Implement the `proc` type as sugar for `~once fn` and `proc`
notation for closures, and disable the feature gate for `once fn` if
used with the `~` sigil.
Diffstat (limited to 'src/libsyntax/parse/parser.rs')
-rw-r--r--src/libsyntax/parse/parser.rs57
1 files changed, 56 insertions, 1 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 8b399266676..716fb5040f6 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -27,7 +27,7 @@ use ast::{ExprAssign, ExprAssignOp, ExprBinary, ExprBlock};
 use ast::{ExprBreak, ExprCall, ExprCast, ExprDoBody};
 use ast::{ExprField, ExprFnBlock, ExprIf, ExprIndex};
 use ast::{ExprLit, ExprLogLevel, ExprLoop, ExprMac};
-use ast::{ExprMethodCall, ExprParen, ExprPath, ExprRepeat};
+use ast::{ExprMethodCall, ExprParen, ExprPath, ExprProc, ExprRepeat};
 use ast::{ExprRet, ExprSelf, ExprStruct, ExprTup, ExprUnary};
 use ast::{ExprVec, ExprVstore, ExprVstoreMutBox};
 use ast::{ExprVstoreSlice, ExprVstoreBox};
@@ -814,6 +814,21 @@ impl Parser {
         });
     }
 
+    // Parses a procedure type (`proc`). The initial `proc` keyword must
+    // already have been parsed.
+    pub fn parse_proc_type(&self) -> ty_ {
+        let (decl, lifetimes) = self.parse_ty_fn_decl();
+        ty_closure(@TyClosure {
+            sigil: OwnedSigil,
+            region: None,
+            purity: impure_fn,
+            onceness: Once,
+            bounds: None,
+            decl: decl,
+            lifetimes: lifetimes,
+        })
+    }
+
     // parse a ty_closure type
     pub fn parse_ty_closure(&self,
                             sigil: ast::Sigil,
@@ -1123,6 +1138,8 @@ impl Parser {
             let e = self.parse_expr();
             self.expect(&token::RPAREN);
             ty_typeof(e)
+        } else if self.eat_keyword(keywords::Proc) {
+            self.parse_proc_type()
         } else if *self.token == token::MOD_SEP
             || is_ident_or_path(self.token) {
             // NAMED TYPE
@@ -1672,6 +1689,19 @@ impl Parser {
                                  ExprBlock(blk));
         } else if token::is_bar(&*self.token) {
             return self.parse_lambda_expr();
+        } else if self.eat_keyword(keywords::Proc) {
+            let decl = self.parse_proc_decl();
+            let body = self.parse_expr();
+            let fakeblock = ast::Block {
+                view_items: ~[],
+                stmts: ~[],
+                expr: Some(body),
+                id: ast::DUMMY_NODE_ID,
+                rules: DefaultBlock,
+                span: body.span,
+            };
+
+            return self.mk_expr(lo, body.span.hi, ExprProc(decl, fakeblock));
         } else if self.eat_keyword(keywords::Self) {
             ex = ExprSelf;
             hi = self.span.hi;
@@ -3616,6 +3646,31 @@ impl Parser {
         }
     }
 
+    // Parses the `(arg, arg) -> return_type` header on a procedure.
+    fn parse_proc_decl(&self) -> fn_decl {
+        let inputs =
+            self.parse_unspanned_seq(&token::LPAREN,
+                                     &token::RPAREN,
+                                     seq_sep_trailing_allowed(token::COMMA),
+                                     |p| p.parse_fn_block_arg());
+
+        let output = if self.eat(&token::RARROW) {
+            self.parse_ty(false)
+        } else {
+            Ty {
+                id: ast::DUMMY_NODE_ID,
+                node: ty_infer,
+                span: *self.span,
+            }
+        };
+
+        ast::fn_decl {
+            inputs: inputs,
+            output: output,
+            cf: return_val,
+        }
+    }
+
     // parse the name and optional generic types of a function header.
     fn parse_fn_header(&self) -> (Ident, ast::Generics) {
         let id = self.parse_ident();