diff options
| author | Patrick Walton <[email protected]> | 2010-11-29 17:11:03 -0800 |
|---|---|---|
| committer | Patrick Walton <[email protected]> | 2010-11-29 17:11:41 -0800 |
| commit | 6c5a05b819c4dc7e3c47056a61a27fa4f11a364f (patch) | |
| tree | f0f8e89877aceb4bb1c906925c270d38c01be372 /src/comp/middle | |
| parent | Teach fold about ty_rec. (diff) | |
| download | rust-6c5a05b819c4dc7e3c47056a61a27fa4f11a364f.tar.xz rust-6c5a05b819c4dc7e3c47056a61a27fa4f11a364f.zip | |
rustc: Implement the block syntax discussed on the mailing list
Diffstat (limited to 'src/comp/middle')
| -rw-r--r-- | src/comp/middle/fold.rs | 14 | ||||
| -rw-r--r-- | src/comp/middle/trans.rs | 13 | ||||
| -rw-r--r-- | src/comp/middle/typeck.rs | 43 |
3 files changed, 44 insertions, 26 deletions
diff --git a/src/comp/middle/fold.rs b/src/comp/middle/fold.rs index ff8f5505..c97dceb4 100644 --- a/src/comp/middle/fold.rs +++ b/src/comp/middle/fold.rs @@ -529,7 +529,19 @@ fn fold_block[ENV](&ENV env, ast_fold[ENV] fld, &block blk) -> block { for (@ast.stmt s in blk.node.stmts) { append[@ast.stmt](stmts, fold_stmt[ENV](env_, fld, s)); } - ret respan(blk.span, rec(stmts=stmts with blk.node)); + + auto expr = none[@ast.expr]; + alt (blk.node.expr) { + case (some[@ast.expr](?e)) { + expr = some[@ast.expr](fold_expr[ENV](env_, fld, e)); + } + case (none[@ast.expr]) { + // empty + } + } + + // FIXME: should we reindex? + ret respan(blk.span, rec(stmts=stmts, expr=expr, index=blk.node.index)); } fn fold_arg[ENV](&ENV env, ast_fold[ENV] fld, &arg a) -> arg { diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 9aa367d5..8caaf5f7 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -1488,6 +1488,19 @@ impure fn trans_block(@block_ctxt cx, &ast.block b) -> result { } } + alt (b.node.expr) { + case (some[@ast.expr](?e)) { + r = trans_expr(bcx, e); + bcx = r.bcx; + if (is_terminated(bcx)) { + ret r; + } + } + case (none[@ast.expr]) { + r = res(bcx, C_nil()); + } + } + bcx = trans_block_cleanups(bcx, bcx); ret res(bcx, r.val); } diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 0aabcac3..58f723bd 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -398,19 +398,6 @@ fn collect_item_types(@ast.crate crate) -> tup(@ast.crate, @ty_table) { // Expression utilities -fn last_expr_of_block(&ast.block bloc) -> option.t[@ast.expr] { - auto len = _vec.len[@ast.stmt](bloc.node.stmts); - if (len == 0u) { - ret none[@ast.expr]; - } - auto last_stmt = bloc.node.stmts.(len - 1u); - alt (last_stmt.node) { - case (ast.stmt_expr(?e)) { ret some[@ast.expr](e); } - case (_) { ret none[@ast.expr]; } - } -} - - fn field_num(session.session sess, &span sp, &ast.ident id) -> uint { let uint accum = 0u; let uint i = 0u; @@ -546,7 +533,7 @@ fn stmt_ty(@ast.stmt s) -> @ty { } fn block_ty(&ast.block b) -> @ty { - alt (last_expr_of_block(b)) { + alt (b.node.expr) { case (some[@ast.expr](?e)) { ret expr_ty(e); } case (none[@ast.expr]) { ret plain_ty(ty_nil); } } @@ -965,18 +952,12 @@ fn demand_expr(&fn_ctxt fcx, @ty expected, @ast.expr e) -> @ast.expr { // Type unification over typed blocks. fn demand_block(&fn_ctxt fcx, @ty expected, &ast.block bloc) -> ast.block { - alt (last_expr_of_block(bloc)) { + alt (bloc.node.expr) { case (some[@ast.expr](?e_0)) { auto e_1 = demand_expr(fcx, expected, e_0); - - auto len = _vec.len[@ast.stmt](bloc.node.stmts); - auto last_stmt_0 = bloc.node.stmts.(len - 1u); - auto prev_stmts = _vec.pop[@ast.stmt](bloc.node.stmts); - auto last_stmt_1 = @fold.respan[ast.stmt_](last_stmt_0.span, - ast.stmt_expr(e_1)); - auto stmts_1 = prev_stmts + vec(last_stmt_1); - - auto block_ = rec(stmts=stmts_1, index=bloc.node.index); + auto block_ = rec(stmts=bloc.node.stmts, + expr=some[@ast.expr](e_1), + index=bloc.node.index); ret fold.respan[ast.block_](bloc.span, block_); } case (none[@ast.expr]) { @@ -1386,8 +1367,18 @@ fn check_block(&fn_ctxt fcx, &ast.block block) -> ast.block { for (@ast.stmt s in block.node.stmts) { append[@ast.stmt](stmts, check_stmt(fcx, s)); } + + auto expr = none[@ast.expr]; + alt (block.node.expr) { + case (none[@ast.expr]) { /* empty */ } + case (some[@ast.expr](?e)) { + expr = some[@ast.expr](check_expr(fcx, e)); + } + } + ret fold.respan[ast.block_](block.span, - rec(stmts=stmts, index=block.node.index)); + rec(stmts=stmts, expr=expr, + index=block.node.index)); } fn check_fn(&@crate_ctxt ccx, &span sp, ast.ident ident, &ast._fn f, @@ -1411,8 +1402,10 @@ fn check_fn(&@crate_ctxt ccx, &span sp, ast.ident ident, &ast._fn f, locals = local_ty_table, ccx = ccx); + // TODO: Make sure the type of the block agrees with the function type. auto block_t = check_block(fcx, f.body); auto block_wb = writeback(fcx, block_t); + auto fn_t = rec(inputs=f.inputs, output=f.output, body=block_wb); auto item = ast.item_fn(ident, fn_t, ty_params, id, fn_ann); ret @fold.respan[ast.item_](sp, item); |