Skip to content

Commit 7f5bffc

Browse files
committed
Merge remote branch 'brson/recursive-elseif'
2 parents 8b5574a + bbb6836 commit 7f5bffc

File tree

8 files changed

+80
-160
lines changed

8 files changed

+80
-160
lines changed

src/comp/front/ast.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ tag expr_ {
223223
expr_unary(unop, @expr, ann);
224224
expr_lit(@lit, ann);
225225
expr_cast(@expr, @ty, ann);
226-
expr_if(@expr, block, vec[tup(@expr, block)], option.t[block], ann);
226+
expr_if(@expr, block, option.t[@expr], ann);
227227
expr_while(@expr, block, ann);
228228
expr_for(@decl, @expr, block, ann);
229229
expr_for_each(@decl, @expr, block, ann);

src/comp/front/eval.rs

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ impure fn eval_crate_directive_expr(parser p,
289289

290290
alt (x.node) {
291291

292-
case (ast.expr_if(?cond, ?thn, ?elifs, ?elopt, _)) {
292+
case (ast.expr_if(?cond, ?thn, ?elopt, _)) {
293293
auto cv = eval_expr(sess, e, cond);
294294
if (!val_is_bool(cv)) {
295295
sess.span_err(x.span, "bad cond type in 'if'");
@@ -301,24 +301,11 @@ impure fn eval_crate_directive_expr(parser p,
301301
index);
302302
}
303303

304-
for (tup(@ast.expr, ast.block) elif in elifs) {
305-
auto cv = eval_expr(sess, e, elif._0);
306-
if (!val_is_bool(cv)) {
307-
sess.span_err(x.span, "bad cond type in 'else if'");
308-
}
309-
310-
if (val_as_bool(cv)) {
311-
ret eval_crate_directive_block(p, e, elif._1, prefix,
312-
view_items, items,
313-
index);
314-
}
315-
}
316-
317304
alt (elopt) {
318-
case (some[ast.block](?els)) {
319-
ret eval_crate_directive_block(p, e, els, prefix,
320-
view_items, items,
321-
index);
305+
case (some[@ast.expr](?els)) {
306+
ret eval_crate_directive_expr(p, e, els, prefix,
307+
view_items, items,
308+
index);
322309
}
323310
case (_) {
324311
// Absent-else is ok.
@@ -353,6 +340,12 @@ impure fn eval_crate_directive_expr(parser p,
353340
sess.span_err(x.span, "no cases matched in 'alt'");
354341
}
355342

343+
case (ast.expr_block(?block, _)) {
344+
ret eval_crate_directive_block(p, e, block, prefix,
345+
view_items, items,
346+
index);
347+
}
348+
356349
case (_) {
357350
sess.span_err(x.span, "unsupported expr type");
358351
}

src/comp/front/parser.rs

Lines changed: 23 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1139,40 +1139,32 @@ impure fn parse_if_expr(parser p) -> @ast.expr {
11391139
auto cond = parse_expr(p);
11401140
expect(p, token.RPAREN);
11411141
auto thn = parse_block(p);
1142+
let option.t[@ast.expr] els = none[@ast.expr];
11421143
hi = thn.span;
1143-
1144-
let vec[tup(@ast.expr, ast.block)] elifs = vec();
1145-
let option.t[ast.block] els = none[ast.block];
1146-
let bool parsing_elses = true;
1147-
while (parsing_elses) {
1148-
alt (p.peek()) {
1149-
case (token.ELSE) {
1150-
expect(p, token.ELSE);
1151-
alt (p.peek()) {
1152-
case (token.IF) {
1153-
expect(p, token.IF);
1154-
expect(p, token.LPAREN);
1155-
auto elifcond = parse_expr(p);
1156-
expect(p, token.RPAREN);
1157-
auto elifthn = parse_block(p);
1158-
elifs += tup(elifcond, elifthn);
1159-
hi = elifthn.span;
1160-
}
1161-
case (_) {
1162-
auto eblk = parse_block(p);
1163-
els = some(eblk);
1164-
hi = eblk.span;
1165-
parsing_elses = false;
1166-
}
1167-
}
1168-
}
1169-
case (_) {
1170-
parsing_elses = false;
1171-
}
1144+
alt (p.peek()) {
1145+
case (token.ELSE) {
1146+
auto elexpr = parse_else_expr(p);
1147+
els = some(elexpr);
1148+
hi = elexpr.span;
11721149
}
1150+
case (_) { /* fall through */ }
11731151
}
11741152

1175-
ret @spanned(lo, hi, ast.expr_if(cond, thn, elifs, els, ast.ann_none));
1153+
ret @spanned(lo, hi, ast.expr_if(cond, thn, els, ast.ann_none));
1154+
}
1155+
1156+
impure fn parse_else_expr(parser p) -> @ast.expr {
1157+
expect(p, token.ELSE);
1158+
alt (p.peek()) {
1159+
case (token.IF) {
1160+
ret parse_if_expr(p);
1161+
}
1162+
case (_) {
1163+
auto blk = parse_block(p);
1164+
ret @spanned(blk.span, blk.span,
1165+
ast.expr_block(blk, ast.ann_none));
1166+
}
1167+
}
11761168
}
11771169

11781170
impure fn parse_head_local(parser p) -> @ast.decl {
@@ -1575,7 +1567,7 @@ fn stmt_ends_with_semi(@ast.stmt stmt) -> bool {
15751567
case (ast.expr_unary(_,_,_)) { ret true; }
15761568
case (ast.expr_lit(_,_)) { ret true; }
15771569
case (ast.expr_cast(_,_,_)) { ret true; }
1578-
case (ast.expr_if(_,_,_,_,_)) { ret false; }
1570+
case (ast.expr_if(_,_,_,_)) { ret false; }
15791571
case (ast.expr_for(_,_,_,_)) { ret false; }
15801572
case (ast.expr_for_each(_,_,_,_))
15811573
{ ret false; }

src/comp/middle/fold.rs

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,7 @@ type ast_fold[ENV] =
107107

108108
(fn(&ENV e, &span sp,
109109
@expr cond, &block thn,
110-
&vec[tup(@expr, block)] elifs,
111-
&option.t[block] els,
110+
&option.t[@expr] els,
112111
ann a) -> @expr) fold_expr_if,
113112

114113
(fn(&ENV e, &span sp,
@@ -590,27 +589,17 @@ fn fold_expr[ENV](&ENV env, ast_fold[ENV] fld, &@expr e) -> @expr {
590589
ret fld.fold_expr_cast(env_, e.span, ee, tt, at);
591590
}
592591

593-
case (ast.expr_if(?cnd, ?thn, ?elifs, ?els, ?t)) {
592+
case (ast.expr_if(?cnd, ?thn, ?els, ?t)) {
594593
auto ccnd = fold_expr(env_, fld, cnd);
595594
auto tthn = fold_block(env_, fld, thn);
596-
597-
let vec[tup(@ast.expr, ast.block)] eelifs = vec();
598-
for (tup(@expr, block) elif in elifs) {
599-
auto elifcnd = elif._0;
600-
auto elifthn = elif._1;
601-
auto elifccnd = fold_expr(env_, fld, elifcnd);
602-
auto eliftthn = fold_block(env_, fld, elifthn);
603-
eelifs += tup(elifccnd, eliftthn);
604-
}
605-
606-
auto eels = none[block];
595+
auto eels = none[@expr];
607596
alt (els) {
608-
case (some[block](?b)) {
609-
eels = some(fold_block(env_, fld, b));
597+
case (some[@expr](?e)) {
598+
eels = some(fold_expr(env_, fld, e));
610599
}
611600
case (_) { /* fall through */ }
612601
}
613-
ret fld.fold_expr_if(env_, e.span, ccnd, tthn, eelifs, eels, t);
602+
ret fld.fold_expr_if(env_, e.span, ccnd, tthn, eels, t);
614603
}
615604

616605
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,
11891178

11901179
fn identity_fold_expr_if[ENV](&ENV env, &span sp,
11911180
@expr cond, &block thn,
1192-
&vec[tup(@expr, block)] elifs,
1193-
&option.t[block] els, ann a) -> @expr {
1194-
ret @respan(sp, ast.expr_if(cond, thn, elifs, els, a));
1181+
&option.t[@expr] els, ann a) -> @expr {
1182+
ret @respan(sp, ast.expr_if(cond, thn, els, a));
11951183
}
11961184

11971185
fn identity_fold_expr_for[ENV](&ENV env, &span sp,
@@ -1554,7 +1542,7 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
15541542
fold_expr_unary = bind identity_fold_expr_unary[ENV](_,_,_,_,_),
15551543
fold_expr_lit = bind identity_fold_expr_lit[ENV](_,_,_,_),
15561544
fold_expr_cast = bind identity_fold_expr_cast[ENV](_,_,_,_,_),
1557-
fold_expr_if = bind identity_fold_expr_if[ENV](_,_,_,_,_,_,_),
1545+
fold_expr_if = bind identity_fold_expr_if[ENV](_,_,_,_,_,_),
15581546
fold_expr_for = bind identity_fold_expr_for[ENV](_,_,_,_,_,_),
15591547
fold_expr_for_each
15601548
= bind identity_fold_expr_for_each[ENV](_,_,_,_,_,_),

src/comp/middle/trans.rs

Lines changed: 9 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2833,9 +2833,8 @@ fn join_results(@block_ctxt parent_cx,
28332833
ret res(join_cx, phi);
28342834
}
28352835

2836-
fn trans_if(@block_ctxt cx, @ast.expr cond, &ast.block thn,
2837-
&vec[tup(@ast.expr, ast.block)] elifs,
2838-
&option.t[ast.block] els) -> result {
2836+
fn trans_if(@block_ctxt cx, @ast.expr cond,
2837+
&ast.block thn, &option.t[@ast.expr] els) -> result {
28392838

28402839
auto cond_res = trans_expr(cx, cond);
28412840

@@ -2845,25 +2844,11 @@ fn trans_if(@block_ctxt cx, @ast.expr cond, &ast.block thn,
28452844
auto else_cx = new_scope_block_ctxt(cx, "else");
28462845
auto else_res = res(else_cx, C_nil());
28472846

2848-
auto num_elifs = _vec.len[tup(@ast.expr, ast.block)](elifs);
2849-
if (num_elifs > 0u) {
2850-
auto next_elif = elifs.(0u);
2851-
auto next_elifthn = next_elif._0;
2852-
auto next_elifcnd = next_elif._1;
2853-
auto rest_elifs = _vec.shift[tup(@ast.expr, ast.block)](elifs);
2854-
else_res = trans_if(else_cx, next_elifthn, next_elifcnd,
2855-
rest_elifs, els);
2856-
}
2857-
2858-
/* else: FIXME: rustboot has a problem here
2859-
with preconditions inside an else block */
2860-
if (num_elifs == 0u) {
2861-
alt (els) {
2862-
case (some[ast.block](?eblk)) {
2863-
else_res = trans_block(else_cx, eblk);
2864-
}
2865-
case (_) { /* fall through */ }
2847+
alt (els) {
2848+
case (some[@ast.expr](?elexpr)) {
2849+
else_res = trans_expr(else_cx, elexpr);
28662850
}
2851+
case (_) { /* fall through */ }
28672852
}
28682853

28692854
cond_res.bcx.build.CondBr(cond_res.val,
@@ -4303,8 +4288,8 @@ fn trans_expr(@block_ctxt cx, @ast.expr e) -> result {
43034288
ret trans_binary(cx, op, x, y);
43044289
}
43054290

4306-
case (ast.expr_if(?cond, ?thn, ?elifs, ?els, _)) {
4307-
ret trans_if(cx, cond, thn, elifs, els);
4291+
case (ast.expr_if(?cond, ?thn, ?els, _)) {
4292+
ret trans_if(cx, cond, thn, els);
43084293
}
43094294

43104295
case (ast.expr_for(?decl, ?seq, ?body, _)) {
@@ -4328,14 +4313,7 @@ fn trans_expr(@block_ctxt cx, @ast.expr e) -> result {
43284313
}
43294314

43304315
case (ast.expr_block(?blk, _)) {
4331-
auto sub_cx = new_scope_block_ctxt(cx, "block-expr body");
4332-
auto next_cx = new_sub_block_ctxt(cx, "next");
4333-
auto sub = trans_block(sub_cx, blk);
4334-
4335-
cx.build.Br(sub_cx.llbb);
4336-
sub.bcx.build.Br(next_cx.llbb);
4337-
4338-
ret res(next_cx, sub.val);
4316+
ret trans_block(cx, blk);
43394317
}
43404318

43414319
case (ast.expr_assign(?dst, ?src, ?ann)) {

src/comp/middle/ty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,7 @@ fn expr_ty(@ast.expr expr) -> @t {
712712
case (ast.expr_unary(_, _, ?ann)) { ret ann_to_type(ann); }
713713
case (ast.expr_lit(_, ?ann)) { ret ann_to_type(ann); }
714714
case (ast.expr_cast(_, _, ?ann)) { ret ann_to_type(ann); }
715-
case (ast.expr_if(_, _, _, _, ?ann)) { ret ann_to_type(ann); }
715+
case (ast.expr_if(_, _, _, ?ann)) { ret ann_to_type(ann); }
716716
case (ast.expr_for(_, _, _, ?ann)) { ret ann_to_type(ann); }
717717
case (ast.expr_for_each(_, _, _, ?ann))
718718
{ ret ann_to_type(ann); }

src/comp/middle/typeck.rs

Lines changed: 16 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,28 +1272,20 @@ fn demand_expr_full(&@fn_ctxt fcx, @ty.t expected, @ast.expr e,
12721272
e_1 = ast.expr_cast(sube, ast_ty,
12731273
ast.ann_type(t, none[vec[@ty.t]]));
12741274
}
1275-
case (ast.expr_if(?cond, ?then_0, ?elifs_0, ?else_0, ?ann)) {
1275+
case (ast.expr_if(?cond, ?then_0, ?else_0, ?ann)) {
12761276
auto t = demand_full(fcx, e.span, expected,
12771277
ann_to_type(ann), adk);
12781278
auto then_1 = demand_block(fcx, expected, then_0);
12791279

1280-
let vec[tup(@ast.expr, ast.block)] elifs_1 = vec();
1281-
for (tup(@ast.expr, ast.block) elif in elifs_0) {
1282-
auto elifcond = elif._0;
1283-
auto elifthn_0 = elif._1;
1284-
auto elifthn_1 = demand_block(fcx, expected, elifthn_0);
1285-
elifs_1 += tup(elifcond, elifthn_1);
1286-
}
1287-
12881280
auto else_1;
12891281
alt (else_0) {
1290-
case (none[ast.block]) { else_1 = none[ast.block]; }
1291-
case (some[ast.block](?b_0)) {
1292-
auto b_1 = demand_block(fcx, expected, b_0);
1293-
else_1 = some[ast.block](b_1);
1282+
case (none[@ast.expr]) { else_1 = none[@ast.expr]; }
1283+
case (some[@ast.expr](?e_0)) {
1284+
auto e_1 = demand_expr(fcx, expected, e_0);
1285+
else_1 = some[@ast.expr](e_1);
12941286
}
12951287
}
1296-
e_1 = ast.expr_if(cond, then_1, elifs_1, else_1,
1288+
e_1 = ast.expr_if(cond, then_1, else_1,
12971289
ast.ann_type(t, none[vec[@ty.t]]));
12981290
}
12991291
case (ast.expr_for(?decl, ?seq, ?bloc, ?ann)) {
@@ -1875,39 +1867,24 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
18751867
ret @fold.respan[ast.expr_](expr.span, newexpr);
18761868
}
18771869

1878-
case (ast.expr_if(?cond, ?thn, ?elifs, ?elsopt, _)) {
1870+
case (ast.expr_if(?cond, ?thn, ?elsopt, _)) {
18791871
auto cond_0 = check_expr(fcx, cond);
18801872
auto cond_1 = demand_expr(fcx, plain_ty(ty.ty_bool), cond_0);
18811873

18821874
auto thn_0 = check_block(fcx, thn);
18831875
auto thn_t = block_ty(thn_0);
18841876

1885-
auto num_elifs = _vec.len[tup(@ast.expr, ast.block)](elifs);
1886-
let vec[tup(@ast.expr, ast.block)] elifs_1 = vec();
1887-
for each (uint i in _uint.range(0u, num_elifs)) {
1888-
auto elif = elifs.(i);
1889-
auto elifcond = elif._0;
1890-
auto elifcond_0 = check_expr(fcx, cond);
1891-
auto elifcond_1 = demand_expr(fcx,
1892-
plain_ty(ty.ty_bool),
1893-
elifcond_0);
1894-
auto elifthn = elif._1;
1895-
auto elifthn_0 = check_block(fcx, elifthn);
1896-
auto elifthn_1 = demand_block(fcx, thn_t, elifthn_0);
1897-
elifs_1 += tup(elifcond_1, elifthn_1);
1898-
}
1899-
19001877
auto elsopt_1;
19011878
auto elsopt_t;
19021879
alt (elsopt) {
1903-
case (some[ast.block](?els)) {
1904-
auto els_0 = check_block(fcx, els);
1905-
auto els_1 = demand_block(fcx, thn_t, els_0);
1906-
elsopt_1 = some[ast.block](els_1);
1907-
elsopt_t = block_ty(els_1);
1908-
}
1909-
case (none[ast.block]) {
1910-
elsopt_1 = none[ast.block];
1880+
case (some[@ast.expr](?els)) {
1881+
auto els_0 = check_expr(fcx, els);
1882+
auto els_1 = demand_expr(fcx, thn_t, els_0);
1883+
elsopt_1 = some[@ast.expr](els_1);
1884+
elsopt_t = expr_ty(els_1);
1885+
}
1886+
case (none[@ast.expr]) {
1887+
elsopt_1 = none[@ast.expr];
19111888
elsopt_t = plain_ty(ty.ty_nil);
19121889
}
19131890
}
@@ -1917,7 +1894,7 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
19171894
auto ann = ast.ann_type(elsopt_t, none[vec[@ty.t]]);
19181895
ret @fold.respan[ast.expr_](expr.span,
19191896
ast.expr_if(cond_1, thn_1,
1920-
elifs_1, elsopt_1, ann));
1897+
elsopt_1, ann));
19211898
}
19221899

19231900
case (ast.expr_for(?decl, ?seq, ?body, _)) {

0 commit comments

Comments
 (0)