aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGraydon Hoare <[email protected]>2011-03-14 16:59:04 -0700
committerGraydon Hoare <[email protected]>2011-03-14 16:59:04 -0700
commit7f5bffc3ea8545be1916dd089e4f25a360c83950 (patch)
tree877d7e430339360c8645a1983707d04088d1cba2 /src
parentRename check_assignment_like to check_assignment since it turned out not to b... (diff)
parentMerge branch 'master' into recursive-elseif (diff)
downloadrust-7f5bffc3ea8545be1916dd089e4f25a360c83950.tar.xz
rust-7f5bffc3ea8545be1916dd089e4f25a360c83950.zip
Merge remote branch 'brson/recursive-elseif'
Diffstat (limited to 'src')
-rw-r--r--src/comp/front/ast.rs2
-rw-r--r--src/comp/front/eval.rs29
-rw-r--r--src/comp/front/parser.rs54
-rw-r--r--src/comp/middle/fold.rs30
-rw-r--r--src/comp/middle/trans.rs40
-rw-r--r--src/comp/middle/ty.rs2
-rw-r--r--src/comp/middle/typeck.rs55
-rw-r--r--src/comp/pretty/pprust.rs28
8 files changed, 80 insertions, 160 deletions
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs
index 8507298d..a7ff64fa 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 77f3acd1..ac249848 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 b2aa6495..df57bc19 100644
--- a/src/comp/front/parser.rs
+++ b/src/comp/front/parser.rs
@@ -1139,40 +1139,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 {
@@ -1575,7 +1567,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 8de85749..1fc91693 100644
--- a/src/comp/middle/fold.rs
+++ b/src/comp/middle/fold.rs
@@ -107,8 +107,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,
@@ -590,27 +589,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)) {
@@ -1189,9 +1178,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,
@@ -1554,7 +1542,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 de19a01a..4fab3454 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 0999e416..0c540f5c 100644
--- a/src/comp/middle/ty.rs
+++ b/src/comp/middle/ty.rs
@@ -712,7 +712,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 6b826f1b..1818c4fd 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -1272,28 +1272,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)) {
@@ -1875,39 +1867,24 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
ret @fold.respan[ast.expr_](expr.span, newexpr);
}
- 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 (none[ast.block]) {
- elsopt_1 = none[ast.block];
+ 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.expr]) {
+ elsopt_1 = none[@ast.expr];
elsopt_t = plain_ty(ty.ty_nil);
}
}
@@ -1917,7 +1894,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 413de413..e59c0c3d 100644
--- a/src/comp/pretty/pprust.rs
+++ b/src/comp/pretty/pprust.rs
@@ -376,26 +376,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 */ }
}