about summary refs log tree commit diff
path: root/src/libsyntax/parse
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
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')
-rw-r--r--src/libsyntax/parse/parser.rs57
-rw-r--r--src/libsyntax/parse/token.rs41
2 files changed, 78 insertions, 20 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();
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 27747d94b66..3d8fa1b6728 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -486,14 +486,15 @@ fn mk_fresh_ident_interner() -> @ident_interner {
         "while",              // 62
         "in",                 // 63
         "continue",           // 64
-
-        "be",                 // 65
-        "pure",               // 66
-        "yield",              // 67
-        "typeof",             // 68
-        "alignof",            // 69
-        "offsetof",           // 70
-        "sizeof",             // 71
+        "proc",               // 65
+
+        "be",                 // 66
+        "pure",               // 67
+        "yield",              // 68
+        "typeof",             // 69
+        "alignof",            // 70
+        "offsetof",           // 71
+        "sizeof",             // 72
     ];
 
     @interner::StrInterner::prefill(init_vec)
@@ -502,9 +503,9 @@ fn mk_fresh_ident_interner() -> @ident_interner {
 static SELF_KEYWORD_NAME: uint = 8;
 static STATIC_KEYWORD_NAME: uint = 27;
 static STRICT_KEYWORD_START: uint = 32;
-static STRICT_KEYWORD_FINAL: uint = 64;
-static RESERVED_KEYWORD_START: uint = 65;
-static RESERVED_KEYWORD_FINAL: uint = 71;
+static STRICT_KEYWORD_FINAL: uint = 65;
+static RESERVED_KEYWORD_START: uint = 66;
+static RESERVED_KEYWORD_FINAL: uint = 72;
 
 // if an interner exists in TLS, return it. Otherwise, prepare a
 // fresh one.
@@ -645,6 +646,7 @@ pub mod keywords {
         Use,
         While,
         Continue,
+        Proc,
 
         // Reserved keywords
         Alignof,
@@ -694,14 +696,15 @@ pub mod keywords {
                 Use => Ident { name: 61, ctxt: 0 },
                 While => Ident { name: 62, ctxt: 0 },
                 Continue => Ident { name: 64, ctxt: 0 },
-
-                Alignof => Ident { name: 69, ctxt: 0 },
-                Be => Ident { name: 65, ctxt: 0 },
-                Offsetof => Ident { name: 70, ctxt: 0 },
-                Pure => Ident { name: 66, ctxt: 0 },
-                Sizeof => Ident { name: 71, ctxt: 0 },
-                Typeof => Ident { name: 68, ctxt: 0 },
-                Yield => Ident { name: 67, ctxt: 0 },
+                Proc => Ident { name: 65, ctxt: 0 },
+
+                Alignof => Ident { name: 70, ctxt: 0 },
+                Be => Ident { name: 66, ctxt: 0 },
+                Offsetof => Ident { name: 71, ctxt: 0 },
+                Pure => Ident { name: 67, ctxt: 0 },
+                Sizeof => Ident { name: 72, ctxt: 0 },
+                Typeof => Ident { name: 69, ctxt: 0 },
+                Yield => Ident { name: 68, ctxt: 0 },
             }
         }
     }