From 378c0087ca7572cd17726c704fe04d57bf4687af Mon Sep 17 00:00:00 2001 From: Brian Anderson <andersrb@gmail.com> Date: Sun, 30 Jan 2011 17:18:19 -0500 Subject: [PATCH] Parse 'be' statement. Pass tailcall tests. No actual tailcalls yet. --- src/Makefile | 3 +++ src/comp/front/ast.rs | 1 + src/comp/front/parser.rs | 7 +++++++ src/comp/middle/fold.rs | 13 +++++++++++++ src/comp/middle/trans.rs | 9 +++++++++ src/comp/middle/typeck.rs | 15 +++++++++++++++ 6 files changed, 48 insertions(+) diff --git a/src/Makefile b/src/Makefile index 02bd8708601..5c3f297f788 100644 --- a/src/Makefile +++ b/src/Makefile @@ -517,6 +517,9 @@ TEST_XFAILS_RUSTC := $(filter-out \ simple-obj.rs \ stateful-obj.rs \ str-idx.rs \ + tail-call-arg-leak.rs \ + tail-cps.rs \ + tail-direct.rs \ type-in-nested-module.rs \ type-param.rs \ tup.rs \ diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs index 5f315e58262..756a7ad1e6b 100644 --- a/src/comp/front/ast.rs +++ b/src/comp/front/ast.rs @@ -116,6 +116,7 @@ type stmt = spanned[stmt_]; tag stmt_ { stmt_decl(@decl); stmt_ret(option.t[@expr]); + stmt_be(@expr); stmt_log(@expr); stmt_check_expr(@expr); stmt_fail; diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index 8d1309352bb..a1b519ba7f5 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -1200,6 +1200,12 @@ impure fn parse_stmt(parser p) -> @ast.stmt { } } + case (token.BE) { + p.bump(); + auto e = parse_expr(p); + ret @spanned(lo, e.span, ast.stmt_be(e)); + } + case (token.LET) { auto decl = parse_let(p); auto hi = p.get_span(); @@ -1340,6 +1346,7 @@ fn stmt_ends_with_semi(@ast.stmt stmt) -> bool { } } case (ast.stmt_ret(_)) { ret true; } + case (ast.stmt_be(_)) { ret true; } case (ast.stmt_log(_)) { ret true; } case (ast.stmt_check_expr(_)) { ret true; } case (ast.stmt_fail) { ret true; } diff --git a/src/comp/middle/fold.rs b/src/comp/middle/fold.rs index 7e5c2d26aef..9194f734bee 100644 --- a/src/comp/middle/fold.rs +++ b/src/comp/middle/fold.rs @@ -176,6 +176,9 @@ type ast_fold[ENV] = (fn(&ENV e, &span sp, &option.t[@expr] rv) -> @stmt) fold_stmt_ret, + (fn(&ENV e, &span sp, + @expr e) -> @stmt) fold_stmt_be, + (fn(&ENV e, &span sp, @expr e) -> @stmt) fold_stmt_log, @@ -636,6 +639,11 @@ fn fold_stmt[ENV](&ENV env, ast_fold[ENV] fld, &@stmt s) -> @stmt { ret fld.fold_stmt_ret(env_, s.span, oee); } + case (ast.stmt_be(?e)) { + auto ee = fold_expr(env_, fld, e); + ret fld.fold_stmt_be(env_, s.span, ee); + } + case (ast.stmt_log(?e)) { auto ee = fold_expr(env_, fld, e); ret fld.fold_stmt_log(env_, s.span, ee); @@ -1136,6 +1144,10 @@ fn identity_fold_stmt_ret[ENV](&ENV env, &span sp, ret @respan(sp, ast.stmt_ret(rv)); } +fn identity_fold_stmt_be[ENV](&ENV env, &span sp, @expr x) -> @stmt { + ret @respan(sp, ast.stmt_be(x)); +} + fn identity_fold_stmt_log[ENV](&ENV e, &span sp, @expr x) -> @stmt { ret @respan(sp, ast.stmt_log(x)); } @@ -1366,6 +1378,7 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] { fold_stmt_decl = bind identity_fold_stmt_decl[ENV](_,_,_), fold_stmt_ret = bind identity_fold_stmt_ret[ENV](_,_,_), + fold_stmt_be = bind identity_fold_stmt_be[ENV](_,_,_), fold_stmt_log = bind identity_fold_stmt_log[ENV](_,_,_), fold_stmt_check_expr = bind identity_fold_stmt_check_expr[ENV](_,_,_), diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 2a9c32da5e4..499ab027d50 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -3128,6 +3128,11 @@ fn trans_ret(@block_ctxt cx, &option.t[@ast.expr] e) -> result { ret res(bcx, C_nil()); } +fn trans_be(@block_ctxt cx, @ast.expr e) -> result { + // FIXME: So this isn't actually a tail call + ret trans_ret(cx, some(e)); +} + fn init_local(@block_ctxt cx, @ast.local local) -> result { // Make a note to drop this slot on the way out. @@ -3178,6 +3183,10 @@ fn trans_stmt(@block_ctxt cx, &ast.stmt s) -> result { bcx = trans_ret(cx, e).bcx; } + case (ast.stmt_be(?e)) { + bcx = trans_be(cx, e).bcx; + } + case (ast.stmt_expr(?e)) { bcx = trans_expr(cx, e).bcx; } diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 5b14eea4101..7a2b0616d2b 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -1719,6 +1719,21 @@ fn check_stmt(&@fn_ctxt fcx, &@ast.stmt stmt) -> @ast.stmt { } } + case (ast.stmt_be(?expr)) { + alt (expr.node) { + case (ast.expr_call(_, _, _)) { + auto expr_0 = check_expr(fcx, expr); + auto expr_1 = demand_expr(fcx, fcx.ret_ty, expr_0); + ret @fold.respan[ast.stmt_](stmt.span, + ast.stmt_be(expr_1)); + } + case (_) { + fcx.ccx.sess.err("Non-call expression in tail call"); + fail; + } + } + } + case (ast.stmt_log(?expr)) { auto expr_t = check_expr(fcx, expr); ret @fold.respan[ast.stmt_](stmt.span, ast.stmt_log(expr_t));