Allow the else part of an expr_if to be either expr_if or expr_block
This commit is contained in:
parent
c848ed1e98
commit
3fedb18c0a
5 changed files with 55 additions and 30 deletions
|
|
@ -149,7 +149,7 @@ tag expr_ {
|
|||
expr_unary(unop, @expr, ann);
|
||||
expr_lit(@lit, ann);
|
||||
expr_cast(@expr, @ty, ann);
|
||||
expr_if(@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_do_while(block, @expr, ann);
|
||||
|
|
|
|||
|
|
@ -891,30 +891,29 @@ 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.block] els = none[ast.block];
|
||||
let option.t[@ast.expr] els = none[@ast.expr];
|
||||
hi = thn.span;
|
||||
alt (p.peek()) {
|
||||
case (token.ELSE) {
|
||||
auto eblk = parse_else_block(p);
|
||||
els = some(eblk);
|
||||
hi = eblk.span;
|
||||
auto elexpr = parse_else_expr(p);
|
||||
els = some(elexpr);
|
||||
hi = elexpr.span;
|
||||
}
|
||||
case (_) { /* fall through */ }
|
||||
}
|
||||
ret @spanned(lo, hi, ast.expr_if(cond, thn, els, ast.ann_none));
|
||||
}
|
||||
|
||||
impure fn parse_else_block(parser p) -> ast.block {
|
||||
impure fn parse_else_expr(parser p) -> @ast.expr {
|
||||
expect(p, token.ELSE);
|
||||
alt (p.peek()) {
|
||||
case (token.IF) {
|
||||
let vec[@ast.stmt] stmts = vec();
|
||||
auto ifexpr = parse_if_expr(p);
|
||||
auto bloc = index_block(stmts, some(ifexpr));
|
||||
ret spanned(ifexpr.span, ifexpr.span, bloc);
|
||||
ret parse_if_expr(p);
|
||||
}
|
||||
case (_) {
|
||||
ret parse_block(p);
|
||||
auto blk = parse_block(p);
|
||||
ret @spanned(blk.span, blk.span,
|
||||
ast.expr_block(blk, ast.ann_none));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ type ast_fold[ENV] =
|
|||
|
||||
(fn(&ENV e, &span sp,
|
||||
@expr cond, &block thn,
|
||||
&option.t[block] els,
|
||||
&option.t[@expr] els,
|
||||
ann a) -> @expr) fold_expr_if,
|
||||
|
||||
(fn(&ENV e, &span sp,
|
||||
|
|
@ -504,10 +504,10 @@ fn fold_expr[ENV](&ENV env, ast_fold[ENV] fld, &@expr e) -> @expr {
|
|||
case (ast.expr_if(?cnd, ?thn, ?els, ?t)) {
|
||||
auto ccnd = fold_expr(env_, fld, cnd);
|
||||
auto tthn = fold_block(env_, fld, thn);
|
||||
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 */ }
|
||||
}
|
||||
|
|
@ -961,7 +961,7 @@ 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,
|
||||
&option.t[block] els, ann a) -> @expr {
|
||||
&option.t[@expr] els, ann a) -> @expr {
|
||||
ret @respan(sp, ast.expr_if(cond, thn, els, a));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1931,7 +1931,7 @@ fn join_results(@block_ctxt parent_cx,
|
|||
}
|
||||
|
||||
fn trans_if(@block_ctxt cx, @ast.expr cond,
|
||||
&ast.block thn, &option.t[ast.block] els) -> result {
|
||||
&ast.block thn, &option.t[@ast.expr] els) -> result {
|
||||
|
||||
auto cond_res = trans_expr(cx, cond);
|
||||
|
||||
|
|
@ -1942,8 +1942,19 @@ fn trans_if(@block_ctxt cx, @ast.expr cond,
|
|||
auto else_res = res(else_cx, C_nil());
|
||||
|
||||
alt (els) {
|
||||
case (some[ast.block](?eblk)) {
|
||||
else_res = trans_block(else_cx, eblk);
|
||||
case (some[@ast.expr](?elexpr)) {
|
||||
// FIXME: Shouldn't need to unwrap the block here,
|
||||
// instead just use 'else_res = trans_expr(else_cx, elexpr)',
|
||||
// but either a) trans_expr doesn't handle expr_block
|
||||
// correctly or b) I have no idea what I'm doing...
|
||||
alt (elexpr.node) {
|
||||
case (ast.expr_if(_, _, _, _)) {
|
||||
else_res = trans_expr(else_cx, elexpr);
|
||||
}
|
||||
case (ast.expr_block(?b, _)) {
|
||||
else_res = trans_block(else_cx, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
case (_) { /* fall through */ }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -870,10 +870,10 @@ fn demand_expr_full(&@fn_ctxt fcx, @ty.t expected, @ast.expr e,
|
|||
auto then_1 = demand_block(fcx, expected, then_0);
|
||||
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, else_1, ast.ann_type(t));
|
||||
|
|
@ -1205,14 +1205,14 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1308,6 +1308,21 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
|
|||
ast.expr_alt(expr_1, arms_1, ann));
|
||||
}
|
||||
|
||||
case (ast.expr_block(?b, _)) {
|
||||
auto b_0 = check_block(fcx, b);
|
||||
auto ann;
|
||||
alt (b_0.node.expr) {
|
||||
case (some[@ast.expr](?expr)) {
|
||||
ann = ast.ann_type(expr_ty(expr));
|
||||
}
|
||||
case (none[@ast.expr]) {
|
||||
ann = ast.ann_type(plain_ty(ty.ty_nil));
|
||||
}
|
||||
}
|
||||
ret @fold.respan[ast.expr_](expr.span,
|
||||
ast.expr_block(b_0, ann));
|
||||
}
|
||||
|
||||
case (ast.expr_bind(?f, ?args, _)) {
|
||||
auto f_0 = check_expr(fcx, f);
|
||||
auto t_0 = expr_ty(f_0);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue