diff options
| author | Pythoner6 <pythoner6@gmail.com> | 2014-07-25 20:12:51 -0400 |
|---|---|---|
| committer | Joseph Martin <pythoner6@gmail.com> | 2014-08-29 23:43:55 -0400 |
| commit | 373b9d624341b431dd09be6c7742ef84b8e70a98 (patch) | |
| tree | 8e841749cb71c02d776d2a9ab1c0ad268d43d4b0 /src/libsyntax | |
| parent | 5419b2ca2c27b4745fa1f2773719350420542c76 (diff) | |
| download | rust-373b9d624341b431dd09be6c7742ef84b8e70a98.tar.gz rust-373b9d624341b431dd09be6c7742ef84b8e70a98.zip | |
Add support for labeled while loops.
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 12 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 11 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 2 |
6 files changed, 28 insertions, 12 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 8df6b65cd16..68a1c521f19 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -524,7 +524,8 @@ pub enum Expr_ { ExprLit(Gc<Lit>), ExprCast(Gc<Expr>, P<Ty>), ExprIf(Gc<Expr>, P<Block>, Option<Gc<Expr>>), - ExprWhile(Gc<Expr>, P<Block>), + // FIXME #6993: change to Option<Name> ... or not, if these are hygienic. + ExprWhile(Gc<Expr>, P<Block>, Option<Ident>), // FIXME #6993: change to Option<Name> ... or not, if these are hygienic. ExprForLoop(Gc<Pat>, Gc<Expr>, P<Block>, Option<Ident>), // Conditionless loop (can be exited with break, cont, or ret) diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 9dbea1c9ac2..d0f3cf6f9d7 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -66,6 +66,12 @@ fn expand_expr(e: Gc<ast::Expr>, fld: &mut MacroExpander) -> Gc<ast::Expr> { } } + ast::ExprWhile(cond, body, opt_ident) => { + let cond = fld.fold_expr(cond); + let (body, opt_ident) = expand_loop_block(body, opt_ident, fld); + fld.cx.expr(e.span, ast::ExprWhile(cond, body, opt_ident)) + } + ast::ExprLoop(loop_block, opt_ident) => { let (loop_block, opt_ident) = expand_loop_block(loop_block, opt_ident, fld); fld.cx.expr(e.span, ast::ExprLoop(loop_block, opt_ident)) diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index be1c0d96711..946ff7ff3a4 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -1132,18 +1132,20 @@ pub fn noop_fold_expr<T: Folder>(e: Gc<Expr>, folder: &mut T) -> Gc<Expr> { folder.fold_block(tr), fl.map(|x| folder.fold_expr(x))) } - ExprWhile(cond, body) => { - ExprWhile(folder.fold_expr(cond), folder.fold_block(body)) + ExprWhile(cond, body, opt_ident) => { + ExprWhile(folder.fold_expr(cond), + folder.fold_block(body), + opt_ident.map(|i| folder.fold_ident(i))) } - ExprForLoop(pat, iter, body, ref maybe_ident) => { + ExprForLoop(pat, iter, body, ref opt_ident) => { ExprForLoop(folder.fold_pat(pat), folder.fold_expr(iter), folder.fold_block(body), - maybe_ident.map(|i| folder.fold_ident(i))) + opt_ident.map(|i| folder.fold_ident(i))) } ExprLoop(body, opt_ident) => { ExprLoop(folder.fold_block(body), - opt_ident.map(|x| folder.fold_ident(x))) + opt_ident.map(|i| folder.fold_ident(i))) } ExprMatch(expr, ref arms) => { ExprMatch(folder.fold_expr(expr), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 37bda15ac2c..60f24401152 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2094,19 +2094,22 @@ impl<'a> Parser<'a> { return self.parse_for_expr(None); } if self.eat_keyword(keywords::While) { - return self.parse_while_expr(); + return self.parse_while_expr(None); } if Parser::token_is_lifetime(&self.token) { let lifetime = self.get_lifetime(); self.bump(); self.expect(&token::COLON); + if self.eat_keyword(keywords::While) { + return self.parse_while_expr(Some(lifetime)) + } if self.eat_keyword(keywords::For) { return self.parse_for_expr(Some(lifetime)) } if self.eat_keyword(keywords::Loop) { return self.parse_loop_expr(Some(lifetime)) } - self.fatal("expected `for` or `loop` after a label") + self.fatal("expected `while`, `for`, or `loop` after a label") } if self.eat_keyword(keywords::Loop) { return self.parse_loop_expr(None); @@ -2762,12 +2765,12 @@ impl<'a> Parser<'a> { self.mk_expr(lo, hi, ExprForLoop(pat, expr, loop_block, opt_ident)) } - pub fn parse_while_expr(&mut self) -> Gc<Expr> { + pub fn parse_while_expr(&mut self, opt_ident: Option<ast::Ident>) -> Gc<Expr> { let lo = self.last_span.lo; let cond = self.parse_expr_res(RESTRICT_NO_STRUCT_LITERAL); let body = self.parse_block(); let hi = body.span.hi; - return self.mk_expr(lo, hi, ExprWhile(cond, body)); + return self.mk_expr(lo, hi, ExprWhile(cond, body, opt_ident)); } pub fn parse_loop_expr(&mut self, opt_ident: Option<ast::Ident>) -> Gc<Expr> { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index da265d81250..c0483f16213 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1438,7 +1438,11 @@ impl<'a> State<'a> { ast::ExprIf(ref test, ref blk, elseopt) => { try!(self.print_if(&**test, &**blk, elseopt, false)); } - ast::ExprWhile(ref test, ref blk) => { + ast::ExprWhile(ref test, ref blk, opt_ident) => { + for ident in opt_ident.iter() { + try!(self.print_ident(*ident)); + try!(self.word_space(":")); + } try!(self.head("while")); try!(self.print_expr(&**test)); try!(space(&mut self.s)); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 7a35d82b0e4..ffe8c0e6e01 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -775,7 +775,7 @@ pub fn walk_expr<E: Clone, V: Visitor<E>>(visitor: &mut V, expression: &Expr, en visitor.visit_block(&**if_block, env.clone()); walk_expr_opt(visitor, optional_else, env.clone()) } - ExprWhile(ref subexpression, ref block) => { + ExprWhile(ref subexpression, ref block, _) => { visitor.visit_expr(&**subexpression, env.clone()); visitor.visit_block(&**block, env.clone()) } |
