diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs index 5999388ee12ce..59a928be88a86 100644 --- a/src/comp/front/ast.rs +++ b/src/comp/front/ast.rs @@ -223,7 +223,7 @@ tag expr_ { expr_unary(unop, @expr, ann); expr_lit(@lit, ann); expr_cast(@expr, @ty, ann); - expr_if(@expr, block, vec[tup(@expr, block)], option.t[block], ann); + expr_if(@expr, block, option.t[@expr], ann); expr_while(@expr, block, ann); expr_for(@decl, @expr, block, ann); expr_for_each(@decl, @expr, block, ann); diff --git a/src/comp/front/eval.rs b/src/comp/front/eval.rs index efa9aa0d92802..21a764df06141 100644 --- a/src/comp/front/eval.rs +++ b/src/comp/front/eval.rs @@ -289,7 +289,7 @@ impure fn eval_crate_directive_expr(parser p, alt (x.node) { - case (ast.expr_if(?cond, ?thn, ?elifs, ?elopt, _)) { + case (ast.expr_if(?cond, ?thn, ?elopt, _)) { auto cv = eval_expr(sess, e, cond); if (!val_is_bool(cv)) { sess.span_err(x.span, "bad cond type in 'if'"); @@ -301,24 +301,11 @@ impure fn eval_crate_directive_expr(parser p, index); } - for (tup(@ast.expr, ast.block) elif in elifs) { - auto cv = eval_expr(sess, e, elif._0); - if (!val_is_bool(cv)) { - sess.span_err(x.span, "bad cond type in 'else if'"); - } - - if (val_as_bool(cv)) { - ret eval_crate_directive_block(p, e, elif._1, prefix, - view_items, items, - index); - } - } - alt (elopt) { - case (some[ast.block](?els)) { - ret eval_crate_directive_block(p, e, els, prefix, - view_items, items, - index); + case (some[@ast.expr](?els)) { + ret eval_crate_directive_expr(p, e, els, prefix, + view_items, items, + index); } case (_) { // Absent-else is ok. @@ -353,6 +340,12 @@ impure fn eval_crate_directive_expr(parser p, sess.span_err(x.span, "no cases matched in 'alt'"); } + case (ast.expr_block(?block, _)) { + ret eval_crate_directive_block(p, e, block, prefix, + view_items, items, + index); + } + case (_) { sess.span_err(x.span, "unsupported expr type"); } diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index 45cec0c0d2337..653e45a1ebf07 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -1094,40 +1094,32 @@ impure fn parse_if_expr(parser p) -> @ast.expr { auto cond = parse_expr(p); expect(p, token.RPAREN); auto thn = parse_block(p); + let option.t[@ast.expr] els = none[@ast.expr]; hi = thn.span; - - let vec[tup(@ast.expr, ast.block)] elifs = vec(); - let option.t[ast.block] els = none[ast.block]; - let bool parsing_elses = true; - while (parsing_elses) { - alt (p.peek()) { - case (token.ELSE) { - expect(p, token.ELSE); - alt (p.peek()) { - case (token.IF) { - expect(p, token.IF); - expect(p, token.LPAREN); - auto elifcond = parse_expr(p); - expect(p, token.RPAREN); - auto elifthn = parse_block(p); - elifs += tup(elifcond, elifthn); - hi = elifthn.span; - } - case (_) { - auto eblk = parse_block(p); - els = some(eblk); - hi = eblk.span; - parsing_elses = false; - } - } - } - case (_) { - parsing_elses = false; - } + alt (p.peek()) { + case (token.ELSE) { + auto elexpr = parse_else_expr(p); + els = some(elexpr); + hi = elexpr.span; } + case (_) { /* fall through */ } } - ret @spanned(lo, hi, ast.expr_if(cond, thn, elifs, els, ast.ann_none)); + ret @spanned(lo, hi, ast.expr_if(cond, thn, els, ast.ann_none)); +} + +impure fn parse_else_expr(parser p) -> @ast.expr { + expect(p, token.ELSE); + alt (p.peek()) { + case (token.IF) { + ret parse_if_expr(p); + } + case (_) { + auto blk = parse_block(p); + ret @spanned(blk.span, blk.span, + ast.expr_block(blk, ast.ann_none)); + } + } } impure fn parse_head_local(parser p) -> @ast.decl { @@ -1530,7 +1522,7 @@ fn stmt_ends_with_semi(@ast.stmt stmt) -> bool { case (ast.expr_unary(_,_,_)) { ret true; } case (ast.expr_lit(_,_)) { ret true; } case (ast.expr_cast(_,_,_)) { ret true; } - case (ast.expr_if(_,_,_,_,_)) { ret false; } + case (ast.expr_if(_,_,_,_)) { ret false; } case (ast.expr_for(_,_,_,_)) { ret false; } case (ast.expr_for_each(_,_,_,_)) { ret false; } diff --git a/src/comp/middle/fold.rs b/src/comp/middle/fold.rs index 17a2a2ca37424..bbe6f84172bcd 100644 --- a/src/comp/middle/fold.rs +++ b/src/comp/middle/fold.rs @@ -105,8 +105,7 @@ type ast_fold[ENV] = (fn(&ENV e, &span sp, @expr cond, &block thn, - &vec[tup(@expr, block)] elifs, - &option.t[block] els, + &option.t[@expr] els, ann a) -> @expr) fold_expr_if, (fn(&ENV e, &span sp, @@ -565,27 +564,17 @@ fn fold_expr[ENV](&ENV env, ast_fold[ENV] fld, &@expr e) -> @expr { ret fld.fold_expr_cast(env_, e.span, ee, tt, at); } - case (ast.expr_if(?cnd, ?thn, ?elifs, ?els, ?t)) { + case (ast.expr_if(?cnd, ?thn, ?els, ?t)) { auto ccnd = fold_expr(env_, fld, cnd); auto tthn = fold_block(env_, fld, thn); - - let vec[tup(@ast.expr, ast.block)] eelifs = vec(); - for (tup(@expr, block) elif in elifs) { - auto elifcnd = elif._0; - auto elifthn = elif._1; - auto elifccnd = fold_expr(env_, fld, elifcnd); - auto eliftthn = fold_block(env_, fld, elifthn); - eelifs += tup(elifccnd, eliftthn); - } - - auto eels = none[block]; + auto eels = none[@expr]; alt (els) { - case (some[block](?b)) { - eels = some(fold_block(env_, fld, b)); + case (some[@expr](?e)) { + eels = some(fold_expr(env_, fld, e)); } case (_) { /* fall through */ } } - ret fld.fold_expr_if(env_, e.span, ccnd, tthn, eelifs, eels, t); + ret fld.fold_expr_if(env_, e.span, ccnd, tthn, eels, t); } case (ast.expr_for(?decl, ?seq, ?body, ?t)) { @@ -1137,9 +1126,8 @@ fn identity_fold_expr_cast[ENV](&ENV env, &span sp, @ast.expr e, fn identity_fold_expr_if[ENV](&ENV env, &span sp, @expr cond, &block thn, - &vec[tup(@expr, block)] elifs, - &option.t[block] els, ann a) -> @expr { - ret @respan(sp, ast.expr_if(cond, thn, elifs, els, a)); + &option.t[@expr] els, ann a) -> @expr { + ret @respan(sp, ast.expr_if(cond, thn, els, a)); } fn identity_fold_expr_for[ENV](&ENV env, &span sp, @@ -1483,7 +1471,7 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] { fold_expr_unary = bind identity_fold_expr_unary[ENV](_,_,_,_,_), fold_expr_lit = bind identity_fold_expr_lit[ENV](_,_,_,_), fold_expr_cast = bind identity_fold_expr_cast[ENV](_,_,_,_,_), - fold_expr_if = bind identity_fold_expr_if[ENV](_,_,_,_,_,_,_), + fold_expr_if = bind identity_fold_expr_if[ENV](_,_,_,_,_,_), fold_expr_for = bind identity_fold_expr_for[ENV](_,_,_,_,_,_), fold_expr_for_each = bind identity_fold_expr_for_each[ENV](_,_,_,_,_,_), diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 6485054231711..6dcfb5c0a04fd 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -2833,9 +2833,8 @@ fn join_results(@block_ctxt parent_cx, ret res(join_cx, phi); } -fn trans_if(@block_ctxt cx, @ast.expr cond, &ast.block thn, - &vec[tup(@ast.expr, ast.block)] elifs, - &option.t[ast.block] els) -> result { +fn trans_if(@block_ctxt cx, @ast.expr cond, + &ast.block thn, &option.t[@ast.expr] els) -> result { auto cond_res = trans_expr(cx, cond); @@ -2845,25 +2844,11 @@ fn trans_if(@block_ctxt cx, @ast.expr cond, &ast.block thn, auto else_cx = new_scope_block_ctxt(cx, "else"); auto else_res = res(else_cx, C_nil()); - auto num_elifs = _vec.len[tup(@ast.expr, ast.block)](elifs); - if (num_elifs > 0u) { - auto next_elif = elifs.(0u); - auto next_elifthn = next_elif._0; - auto next_elifcnd = next_elif._1; - auto rest_elifs = _vec.shift[tup(@ast.expr, ast.block)](elifs); - else_res = trans_if(else_cx, next_elifthn, next_elifcnd, - rest_elifs, els); - } - - /* else: FIXME: rustboot has a problem here - with preconditions inside an else block */ - if (num_elifs == 0u) { - alt (els) { - case (some[ast.block](?eblk)) { - else_res = trans_block(else_cx, eblk); - } - case (_) { /* fall through */ } + alt (els) { + case (some[@ast.expr](?elexpr)) { + else_res = trans_expr(else_cx, elexpr); } + case (_) { /* fall through */ } } cond_res.bcx.build.CondBr(cond_res.val, @@ -4303,8 +4288,8 @@ fn trans_expr(@block_ctxt cx, @ast.expr e) -> result { ret trans_binary(cx, op, x, y); } - case (ast.expr_if(?cond, ?thn, ?elifs, ?els, _)) { - ret trans_if(cx, cond, thn, elifs, els); + case (ast.expr_if(?cond, ?thn, ?els, _)) { + ret trans_if(cx, cond, thn, els); } case (ast.expr_for(?decl, ?seq, ?body, _)) { @@ -4328,14 +4313,7 @@ fn trans_expr(@block_ctxt cx, @ast.expr e) -> result { } case (ast.expr_block(?blk, _)) { - auto sub_cx = new_scope_block_ctxt(cx, "block-expr body"); - auto next_cx = new_sub_block_ctxt(cx, "next"); - auto sub = trans_block(sub_cx, blk); - - cx.build.Br(sub_cx.llbb); - sub.bcx.build.Br(next_cx.llbb); - - ret res(next_cx, sub.val); + ret trans_block(cx, blk); } case (ast.expr_assign(?dst, ?src, ?ann)) { diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index bd3e3263820b8..0a161810e0203 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -702,7 +702,7 @@ fn expr_ty(@ast.expr expr) -> @t { case (ast.expr_unary(_, _, ?ann)) { ret ann_to_type(ann); } case (ast.expr_lit(_, ?ann)) { ret ann_to_type(ann); } case (ast.expr_cast(_, _, ?ann)) { ret ann_to_type(ann); } - case (ast.expr_if(_, _, _, _, ?ann)) { ret ann_to_type(ann); } + case (ast.expr_if(_, _, _, ?ann)) { ret ann_to_type(ann); } case (ast.expr_for(_, _, _, ?ann)) { ret ann_to_type(ann); } case (ast.expr_for_each(_, _, _, ?ann)) { ret ann_to_type(ann); } diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 7dfe918c065be..b2f371c5f9e27 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -1263,28 +1263,20 @@ fn demand_expr_full(&@fn_ctxt fcx, @ty.t expected, @ast.expr e, e_1 = ast.expr_cast(sube, ast_ty, ast.ann_type(t, none[vec[@ty.t]])); } - case (ast.expr_if(?cond, ?then_0, ?elifs_0, ?else_0, ?ann)) { + case (ast.expr_if(?cond, ?then_0, ?else_0, ?ann)) { auto t = demand_full(fcx, e.span, expected, ann_to_type(ann), adk); auto then_1 = demand_block(fcx, expected, then_0); - let vec[tup(@ast.expr, ast.block)] elifs_1 = vec(); - for (tup(@ast.expr, ast.block) elif in elifs_0) { - auto elifcond = elif._0; - auto elifthn_0 = elif._1; - auto elifthn_1 = demand_block(fcx, expected, elifthn_0); - elifs_1 += tup(elifcond, elifthn_1); - } - auto else_1; alt (else_0) { - case (none[ast.block]) { else_1 = none[ast.block]; } - case (some[ast.block](?b_0)) { - auto b_1 = demand_block(fcx, expected, b_0); - else_1 = some[ast.block](b_1); + case (none[@ast.expr]) { else_1 = none[@ast.expr]; } + case (some[@ast.expr](?e_0)) { + auto e_1 = demand_expr(fcx, expected, e_0); + else_1 = some[@ast.expr](e_1); } } - e_1 = ast.expr_if(cond, then_1, elifs_1, else_1, + e_1 = ast.expr_if(cond, then_1, else_1, ast.ann_type(t, none[vec[@ty.t]])); } case (ast.expr_for(?decl, ?seq, ?bloc, ?ann)) { @@ -1795,39 +1787,24 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr { ann)); } - case (ast.expr_if(?cond, ?thn, ?elifs, ?elsopt, _)) { + case (ast.expr_if(?cond, ?thn, ?elsopt, _)) { auto cond_0 = check_expr(fcx, cond); auto cond_1 = demand_expr(fcx, plain_ty(ty.ty_bool), cond_0); auto thn_0 = check_block(fcx, thn); auto thn_t = block_ty(thn_0); - auto num_elifs = _vec.len[tup(@ast.expr, ast.block)](elifs); - let vec[tup(@ast.expr, ast.block)] elifs_1 = vec(); - for each (uint i in _uint.range(0u, num_elifs)) { - auto elif = elifs.(i); - auto elifcond = elif._0; - auto elifcond_0 = check_expr(fcx, cond); - auto elifcond_1 = demand_expr(fcx, - plain_ty(ty.ty_bool), - elifcond_0); - auto elifthn = elif._1; - auto elifthn_0 = check_block(fcx, elifthn); - auto elifthn_1 = demand_block(fcx, thn_t, elifthn_0); - elifs_1 += tup(elifcond_1, elifthn_1); - } - auto elsopt_1; auto elsopt_t; alt (elsopt) { - case (some[ast.block](?els)) { - auto els_0 = check_block(fcx, els); - auto els_1 = demand_block(fcx, thn_t, els_0); - elsopt_1 = some[ast.block](els_1); - elsopt_t = block_ty(els_1); + case (some[@ast.expr](?els)) { + auto els_0 = check_expr(fcx, els); + auto els_1 = demand_expr(fcx, thn_t, els_0); + elsopt_1 = some[@ast.expr](els_1); + elsopt_t = expr_ty(els_1); } - case (none[ast.block]) { - elsopt_1 = none[ast.block]; + case (none[@ast.expr]) { + elsopt_1 = none[@ast.expr]; elsopt_t = plain_ty(ty.ty_nil); } } @@ -1837,7 +1814,7 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr { auto ann = ast.ann_type(elsopt_t, none[vec[@ty.t]]); ret @fold.respan[ast.expr_](expr.span, ast.expr_if(cond_1, thn_1, - elifs_1, elsopt_1, ann)); + elsopt_1, ann)); } case (ast.expr_for(?decl, ?seq, ?body, _)) { diff --git a/src/comp/pretty/pprust.rs b/src/comp/pretty/pprust.rs index 9ef9bb1614127..2b64b8e41696e 100644 --- a/src/comp/pretty/pprust.rs +++ b/src/comp/pretty/pprust.rs @@ -366,26 +366,18 @@ impure fn print_expr(ps s, @ast.expr expr) { wrd1(s, "as"); print_type(s, ty); } - case (ast.expr_if(?test,?block,?clauses,?_else,_)) { - impure fn print_clause(ps s, @ast.expr test, ast.block blk) { - wrd1(s, "if"); - popen(s); - print_expr(s, test); - pclose(s); - space(s); - print_block(s, blk); - } - print_clause(s, test, block); - for (tup(@ast.expr, ast.block) clause in clauses) { - space(s); - wrd1(s, "else"); - print_clause(s, clause._0, clause._1); - } - alt (_else) { - case (option.some[ast.block](?blk)) { + case (ast.expr_if(?test,?block,?elseopt,_)) { + wrd1(s, "if"); + popen(s); + print_expr(s, test); + pclose(s); + space(s); + print_block(s, block); + alt (elseopt) { + case (option.some[@ast.expr](?_else)) { space(s); wrd1(s, "else"); - print_block(s, blk); + print_expr(s, _else); } case (_) { /* fall through */ } }