aboutsummaryrefslogtreecommitdiff
path: root/src/comp/middle
diff options
context:
space:
mode:
authorPatrick Walton <[email protected]>2010-11-29 17:11:03 -0800
committerPatrick Walton <[email protected]>2010-11-29 17:11:41 -0800
commit6c5a05b819c4dc7e3c47056a61a27fa4f11a364f (patch)
treef0f8e89877aceb4bb1c906925c270d38c01be372 /src/comp/middle
parentTeach fold about ty_rec. (diff)
downloadrust-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.rs14
-rw-r--r--src/comp/middle/trans.rs13
-rw-r--r--src/comp/middle/typeck.rs43
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);