diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2012-08-14 19:20:56 -0700 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2012-08-15 16:20:34 -0700 |
| commit | bdb206f2855cc6f7d3d79379633f7429b7327fec (patch) | |
| tree | 05764770b6b2729780bb1289d3c2db55d1cc55c5 /src/libsyntax | |
| parent | d54db12155257787797cd9c7eaf06a215ff516e5 (diff) | |
| download | rust-bdb206f2855cc6f7d3d79379633f7429b7327fec.tar.gz rust-bdb206f2855cc6f7d3d79379633f7429b7327fec.zip | |
rustc: Parse labeled loop, break, and again
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 9 | ||||
| -rw-r--r-- | src/libsyntax/ast_util.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 10 | ||||
| -rw-r--r-- | src/libsyntax/parse/classify.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 22 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 15 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 6 |
7 files changed, 48 insertions, 18 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 39e116990dd..a09bd073c44 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -89,7 +89,8 @@ enum def { node_id /* expr node that creates the closure */), def_class(def_id, bool /* has constructor */), def_typaram_binder(node_id), /* class, impl or trait that has ty params */ - def_region(node_id) + def_region(node_id), + def_label(node_id) } // The set of meta_items that define the compilation environment of the crate, @@ -316,7 +317,7 @@ enum expr_ { /* Conditionless loop (can be exited with break, cont, ret, or fail) Same semantics as while(true) { body }, but typestate knows that the (implicit) condition is always true. */ - expr_loop(blk), + expr_loop(blk, option<ident>), expr_match(@expr, ~[arm], alt_mode), expr_fn(proto, fn_decl, blk, capture_clause), expr_fn_block(fn_decl, blk, capture_clause), @@ -339,8 +340,8 @@ enum expr_ { expr_path(@path), expr_addr_of(mutability, @expr), expr_fail(option<@expr>), - expr_break, - expr_again, + expr_break(option<ident>), + expr_again(option<ident>), expr_ret(option<@expr>), expr_log(int, @expr, @expr), diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 6ea6ecb1ba3..4a6f8b1e77a 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -61,7 +61,7 @@ pure fn def_id_of_def(d: def) -> def_id { } def_arg(id, _) | def_local(id, _) | def_self(id) | def_upvar(id, _, _) | def_binding(id, _) | def_region(id) - | def_typaram_binder(id) => { + | def_typaram_binder(id) | def_label(id) => { local_def(id) } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 5cce86fd458..5bd35490f0e 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -448,8 +448,9 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ { expr_while(cond, body) => { expr_while(fld.fold_expr(cond), fld.fold_block(body)) } - expr_loop(body) => { - expr_loop(fld.fold_block(body)) + expr_loop(body, opt_ident) => { + expr_loop(fld.fold_block(body), + option::map(opt_ident, |x| fld.fold_ident(x))) } expr_match(expr, arms, mode) => { expr_match(fld.fold_expr(expr), @@ -492,7 +493,10 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ { } expr_path(pth) => expr_path(fld.fold_path(pth)), expr_fail(e) => expr_fail(option::map(e, |x| fld.fold_expr(x))), - expr_break | expr_again => copy e, + expr_break(opt_ident) => + expr_break(option::map(opt_ident, |x| fld.fold_ident(x))), + expr_again(opt_ident) => + expr_again(option::map(opt_ident, |x| fld.fold_ident(x))), expr_ret(e) => expr_ret(option::map(e, |x| fld.fold_expr(x))), expr_log(i, lv, e) => expr_log(i, fld.fold_expr(lv), fld.fold_expr(e)), diff --git a/src/libsyntax/parse/classify.rs b/src/libsyntax/parse/classify.rs index d8ae8044370..1fd9dc2c23c 100644 --- a/src/libsyntax/parse/classify.rs +++ b/src/libsyntax/parse/classify.rs @@ -7,7 +7,7 @@ import ast_util::operator_prec; fn expr_requires_semi_to_be_stmt(e: @ast::expr) -> bool { match e.node { ast::expr_if(_, _, _) | ast::expr_match(_, _, _) | ast::expr_block(_) - | ast::expr_while(_, _) | ast::expr_loop(_) + | ast::expr_while(_, _) | ast::expr_loop(_, _) | ast::expr_call(_, _, true) => false, _ => true } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 642cdaa8fab..977e75362f8 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -939,10 +939,18 @@ class parser { ex = expr_ret(some(e)); } else { ex = expr_ret(none); } } else if self.eat_keyword(~"break") { - ex = expr_break; + if is_ident(self.token) { + ex = expr_break(some(self.parse_ident())); + } else { + ex = expr_break(none); + } hi = self.span.hi; } else if self.eat_keyword(~"again") { - ex = expr_again; + if is_ident(self.token) { + ex = expr_again(some(self.parse_ident())); + } else { + ex = expr_again(none); + } hi = self.span.hi; } else if self.eat_keyword(~"copy") { let e = self.parse_expr(); @@ -1585,10 +1593,18 @@ class parser { } fn parse_loop_expr() -> @expr { + let opt_ident; + if is_ident(self.token) { + opt_ident = some(self.parse_ident()); + self.expect(token::COLON); + } else { + opt_ident = none; + } + let lo = self.last_span.lo; let body = self.parse_block_no_value(); let mut hi = body.span.hi; - return self.mk_expr(lo, hi, expr_loop(body)); + return self.mk_expr(lo, hi, expr_loop(body, opt_ident)); } // For distingishing between record literals and blocks diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 39bc18529c9..49ded036e04 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1142,9 +1142,10 @@ fn print_expr(s: ps, &&expr: @ast::expr) { space(s.s); print_block(s, blk); } - ast::expr_loop(blk) => { + ast::expr_loop(blk, opt_ident) => { head(s, ~"loop"); space(s.s); + option::iter(opt_ident, |ident| word_space(s, *ident)); print_block(s, blk); } ast::expr_match(expr, arms, mode) => { @@ -1310,8 +1311,16 @@ fn print_expr(s: ps, &&expr: @ast::expr) { _ => () } } - ast::expr_break => word(s.s, ~"break"), - ast::expr_again => word(s.s, ~"again"), + ast::expr_break(opt_ident) => { + word(s.s, ~"break"); + space(s.s); + option::iter(opt_ident, |ident| word_space(s, *ident)); + } + ast::expr_again(opt_ident) => { + word(s.s, ~"again"); + space(s.s); + option::iter(opt_ident, |ident| word_space(s, *ident)); + } ast::expr_ret(result) => { word(s.s, ~"return"); match result { diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 1903a688aea..93d253d2163 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -422,7 +422,7 @@ fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) { visit_expr_opt(eo, e, v); } expr_while(x, b) => { v.visit_expr(x, e, v); v.visit_block(b, e, v); } - expr_loop(b) => v.visit_block(b, e, v), + expr_loop(b, _) => v.visit_block(b, e, v), expr_match(x, arms, _) => { v.visit_expr(x, e, v); for arms.each |a| { v.visit_arm(a, e, v); } @@ -452,8 +452,8 @@ fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) { expr_index(a, b) => { v.visit_expr(a, e, v); v.visit_expr(b, e, v); } expr_path(p) => visit_path(p, e, v), expr_fail(eo) => visit_expr_opt(eo, e, v), - expr_break => (), - expr_again => (), + expr_break(_) => (), + expr_again(_) => (), expr_ret(eo) => visit_expr_opt(eo, e, v), expr_log(_, lv, x) => { v.visit_expr(lv, e, v); |
