diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2013-10-28 15:22:49 -0700 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2013-10-29 10:34:17 -0700 |
| commit | 7e77bf17694e31c741fe3a31c7eca5437d9cb6d5 (patch) | |
| tree | 07fbf75c901955bc5b527929785e544829da92b0 /src/libsyntax/parse | |
| parent | e6650c87a3800264a043b7f129e6a4841c4cc3f7 (diff) | |
| download | rust-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.rs | 57 | ||||
| -rw-r--r-- | src/libsyntax/parse/token.rs | 41 |
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 }, } } } |
