Move all non-decl/non-expr stmts to exprs.

This commit is contained in:
Graydon Hoare 2011-02-14 17:46:28 -08:00
parent 88cb966363
commit f1f33abdeb
6 changed files with 212 additions and 193 deletions

View file

@ -116,11 +116,6 @@ tag mode {
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;
stmt_expr(@expr);
}
@ -165,6 +160,11 @@ tag expr_ {
expr_index(@expr, @expr, ann);
expr_path(path, option.t[def], ann);
expr_ext(vec[@expr], option.t[@expr], ann);
expr_fail;
expr_ret(option.t[@expr]);
expr_be(@expr);
expr_log(@expr);
expr_check_expr(@expr);
}
type lit = spanned[lit_];

View file

@ -598,6 +598,59 @@ impure fn parse_bottom_expr(parser p) -> @ast.expr {
ex = ast.expr_ext(es.node, none[@ast.expr], ast.ann_none);
}
case (token.FAIL) {
p.bump();
ex = ast.expr_fail;
}
case (token.LOG) {
p.bump();
auto e = parse_expr(p);
auto hi = e.span;
ex = ast.expr_log(e);
}
case (token.CHECK) {
p.bump();
alt (p.peek()) {
case (token.LPAREN) {
auto e = parse_expr(p);
auto hi = e.span;
ex = ast.expr_check_expr(e);
}
case (_) {
p.get_session().unimpl("constraint-check stmt");
}
}
}
case (token.RET) {
p.bump();
alt (p.peek()) {
case (token.SEMI) {
ex = ast.expr_ret(none[@ast.expr]);
}
case (_) {
auto e = parse_expr(p);
hi = e.span;
ex = ast.expr_ret(some[@ast.expr](e));
}
}
}
case (token.BE) {
p.bump();
auto e = parse_expr(p);
// FIXME: Is this the right place for this check?
if /*check*/ (ast.is_call_expr(e)) {
hi = e.span;
ex = ast.expr_be(e);
}
else {
p.err("Non-call expression in tail call");
}
}
case (_) {
auto lit = parse_lit(p);
hi = lit.span;
@ -1203,59 +1256,6 @@ impure fn parse_stmt(parser p) -> @ast.stmt {
auto lo = p.get_span();
alt (p.peek()) {
case (token.LOG) {
p.bump();
auto e = parse_expr(p);
auto hi = p.get_span();
ret @spanned(lo, hi, ast.stmt_log(e));
}
case (token.CHECK) {
p.bump();
alt (p.peek()) {
case (token.LPAREN) {
auto e = parse_expr(p);
auto hi = p.get_span();
ret @spanned(lo, hi, ast.stmt_check_expr(e));
}
case (_) {
p.get_session().unimpl("constraint-check stmt");
}
}
}
case (token.FAIL) {
p.bump();
ret @spanned(lo, p.get_span(), ast.stmt_fail);
}
case (token.RET) {
p.bump();
alt (p.peek()) {
case (token.SEMI) {
ret @spanned(lo, p.get_span(),
ast.stmt_ret(none[@ast.expr]));
}
case (_) {
auto e = parse_expr(p);
ret @spanned(lo, e.span,
ast.stmt_ret(some[@ast.expr](e)));
}
}
}
case (token.BE) {
p.bump();
auto e = parse_expr(p);
// FIXME: Is this the right place for this check?
if /*check*/ (ast.is_call_expr(e)) {
ret @spanned(lo, e.span, ast.stmt_be(e));
}
else {
p.err("Non-call expression in tail call");
}
}
case (token.LET) {
auto decl = parse_let(p);
auto hi = p.get_span();
@ -1396,11 +1396,6 @@ fn stmt_ends_with_semi(@ast.stmt stmt) -> bool {
case (ast.decl_item(_)) { ret false; }
}
}
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; }
case (ast.stmt_expr(?e)) {
alt (e.node) {
case (ast.expr_vec(_,_)) { ret true; }
@ -1423,6 +1418,11 @@ fn stmt_ends_with_semi(@ast.stmt stmt) -> bool {
case (ast.expr_field(_,_,_)) { ret true; }
case (ast.expr_index(_,_,_)) { ret true; }
case (ast.expr_path(_,_,_)) { ret true; }
case (ast.expr_fail) { ret true; }
case (ast.expr_ret(_)) { ret true; }
case (ast.expr_be(_)) { ret true; }
case (ast.expr_log(_)) { ret true; }
case (ast.expr_check_expr(_)) { ret true; }
}
}
}

View file

@ -149,6 +149,20 @@ type ast_fold[ENV] =
&option.t[def] d,
ann a) -> @expr) fold_expr_path,
(fn(&ENV e, &span sp) -> @expr) fold_expr_fail,
(fn(&ENV e, &span sp,
&option.t[@expr] rv) -> @expr) fold_expr_ret,
(fn(&ENV e, &span sp,
@expr e) -> @expr) fold_expr_be,
(fn(&ENV e, &span sp,
@expr e) -> @expr) fold_expr_log,
(fn(&ENV e, &span sp,
@expr e) -> @expr) fold_expr_check_expr,
// Decl folds.
(fn(&ENV e, &span sp,
@ast.local local) -> @decl) fold_decl_local,
@ -177,18 +191,6 @@ type ast_fold[ENV] =
(fn(&ENV e, &span sp,
@decl decl) -> @stmt) fold_stmt_decl,
(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,
(fn(&ENV e, &span sp,
@expr e) -> @stmt) fold_stmt_check_expr,
(fn(&ENV e, &span sp,
@expr e) -> @stmt) fold_stmt_expr,
@ -622,6 +624,37 @@ fn fold_expr[ENV](&ENV env, ast_fold[ENV] fld, &@expr e) -> @expr {
auto p_ = fold_path(env_, fld, p);
ret fld.fold_expr_path(env_, e.span, p_, r, t);
}
case (ast.expr_fail) {
ret fld.fold_expr_fail(env_, e.span);
}
case (ast.expr_ret(?oe)) {
auto oee = none[@expr];
alt (oe) {
case (some[@expr](?x)) {
oee = some(fold_expr(env_, fld, x));
}
case (_) { /* fall through */ }
}
ret fld.fold_expr_ret(env_, e.span, oee);
}
case (ast.expr_be(?x)) {
auto ee = fold_expr(env_, fld, x);
ret fld.fold_expr_be(env_, e.span, ee);
}
case (ast.expr_log(?x)) {
auto ee = fold_expr(env_, fld, x);
ret fld.fold_expr_log(env_, e.span, ee);
}
case (ast.expr_check_expr(?x)) {
auto ee = fold_expr(env_, fld, x);
ret fld.fold_expr_check_expr(env_, e.span, ee);
}
}
ret e;
@ -642,36 +675,6 @@ fn fold_stmt[ENV](&ENV env, ast_fold[ENV] fld, &@stmt s) -> @stmt {
ret fld.fold_stmt_decl(env_, s.span, dd);
}
case (ast.stmt_ret(?oe)) {
auto oee = none[@expr];
alt (oe) {
case (some[@expr](?e)) {
oee = some(fold_expr(env_, fld, e));
}
case (_) { /* fall through */ }
}
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);
}
case (ast.stmt_check_expr(?e)) {
auto ee = fold_expr(env_, fld, e);
ret fld.fold_stmt_check_expr(env_, s.span, ee);
}
case (ast.stmt_fail) {
ret s;
}
case (ast.stmt_expr(?e)) {
auto ee = fold_expr(env_, fld, e);
ret fld.fold_stmt_expr(env_, s.span, ee);
@ -1118,6 +1121,27 @@ fn identity_fold_expr_path[ENV](&ENV env, &span sp,
ret @respan(sp, ast.expr_path(p, d, a));
}
fn identity_fold_expr_fail[ENV](&ENV env, &span sp) -> @expr {
ret @respan(sp, ast.expr_fail);
}
fn identity_fold_expr_ret[ENV](&ENV env, &span sp,
&option.t[@expr] rv) -> @expr {
ret @respan(sp, ast.expr_ret(rv));
}
fn identity_fold_expr_be[ENV](&ENV env, &span sp, @expr x) -> @expr {
ret @respan(sp, ast.expr_be(x));
}
fn identity_fold_expr_log[ENV](&ENV e, &span sp, @expr x) -> @expr {
ret @respan(sp, ast.expr_log(x));
}
fn identity_fold_expr_check_expr[ENV](&ENV e, &span sp, @expr x) -> @expr {
ret @respan(sp, ast.expr_check_expr(x));
}
// Decl identities.
@ -1158,23 +1182,6 @@ fn identity_fold_stmt_decl[ENV](&ENV env, &span sp, @decl d) -> @stmt {
ret @respan(sp, ast.stmt_decl(d));
}
fn identity_fold_stmt_ret[ENV](&ENV env, &span sp,
&option.t[@expr] rv) -> @stmt {
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));
}
fn identity_fold_stmt_check_expr[ENV](&ENV e, &span sp, @expr x) -> @stmt {
ret @respan(sp, ast.stmt_check_expr(x));
}
fn identity_fold_stmt_expr[ENV](&ENV e, &span sp, @expr x) -> @stmt {
ret @respan(sp, ast.stmt_expr(x));
}
@ -1387,6 +1394,12 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
fold_expr_field = bind identity_fold_expr_field[ENV](_,_,_,_,_),
fold_expr_index = bind identity_fold_expr_index[ENV](_,_,_,_,_),
fold_expr_path = bind identity_fold_expr_path[ENV](_,_,_,_,_),
fold_expr_fail = bind identity_fold_expr_fail[ENV](_,_),
fold_expr_ret = bind identity_fold_expr_ret[ENV](_,_,_),
fold_expr_be = bind identity_fold_expr_be[ENV](_,_,_),
fold_expr_log = bind identity_fold_expr_log[ENV](_,_,_),
fold_expr_check_expr
= bind identity_fold_expr_check_expr[ENV](_,_,_),
fold_decl_local = bind identity_fold_decl_local[ENV](_,_,_),
fold_decl_item = bind identity_fold_decl_item[ENV](_,_,_),
@ -1397,11 +1410,6 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
fold_pat_tag = bind identity_fold_pat_tag[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](_,_,_),
fold_stmt_expr = bind identity_fold_stmt_expr[ENV](_,_,_),
fold_item_const= bind identity_fold_item_const[ENV](_,_,_,_,_,_,_),

View file

@ -3106,6 +3106,26 @@ fn trans_expr(@block_ctxt cx, @ast.expr e) -> result {
ret trans_rec(cx, args, base, ann);
}
case (ast.expr_fail) {
ret trans_fail(cx, e.span, "explicit failure");
}
case (ast.expr_log(?a)) {
ret trans_log(cx, a);
}
case (ast.expr_check_expr(?a)) {
ret trans_check_expr(cx, a);
}
case (ast.expr_ret(?e)) {
ret trans_ret(cx, e);
}
case (ast.expr_be(?e)) {
ret trans_be(cx, e);
}
// lval cases fall through to trans_lval and then
// possibly load the result (if it's non-structural).
@ -3255,26 +3275,6 @@ fn init_local(@block_ctxt cx, @ast.local local) -> result {
fn trans_stmt(@block_ctxt cx, &ast.stmt s) -> result {
auto bcx = cx;
alt (s.node) {
case (ast.stmt_log(?a)) {
bcx = trans_log(cx, a).bcx;
}
case (ast.stmt_check_expr(?a)) {
bcx = trans_check_expr(cx, a).bcx;
}
case (ast.stmt_fail) {
bcx = trans_fail(cx, s.span, "explicit failure").bcx;
}
case (ast.stmt_ret(?e)) {
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;
}

View file

@ -686,6 +686,12 @@ fn expr_ty(@ast.expr expr) -> @t {
case (ast.expr_field(_, _, ?ann)) { ret ann_to_type(ann); }
case (ast.expr_index(_, _, ?ann)) { ret ann_to_type(ann); }
case (ast.expr_path(_, _, ?ann)) { ret ann_to_type(ann); }
case (ast.expr_fail) { ret plain_ty(ty_nil); }
case (ast.expr_log(_)) { ret plain_ty(ty_nil); }
case (ast.expr_check_expr(_)) { ret plain_ty(ty_nil); }
case (ast.expr_ret(_)) { ret plain_ty(ty_nil); }
case (ast.expr_be(_)) { ret plain_ty(ty_nil); }
}
fail;
}

View file

@ -1037,6 +1037,11 @@ fn demand_expr_full(&@fn_ctxt fcx, @ty.t expected, @ast.expr e,
ann_to_type(ann), adk);
e_1 = ast.expr_path(pth, d, ast.ann_type(t));
}
case (ast.expr_fail) { e_1 = e.node; }
case (ast.expr_log(_)) { e_1 = e.node; }
case (ast.expr_ret(_)) { e_1 = e.node; }
case (ast.expr_be(_)) { e_1 = e.node; }
case (ast.expr_check_expr(_)) { e_1 = e.node; }
}
ret @fold.respan[ast.expr_](e.span, e_1);
@ -1287,6 +1292,52 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
ast.ann_type(t)));
}
case (ast.expr_fail) {
ret expr;
}
case (ast.expr_ret(?expr_opt)) {
alt (expr_opt) {
case (none[@ast.expr]) {
auto nil = plain_ty(ty.ty_nil);
if (!are_compatible(fcx, fcx.ret_ty, nil)) {
fcx.ccx.sess.err("ret; in function "
+ "returning non-nil");
}
ret expr;
}
case (some[@ast.expr](?e)) {
auto expr_0 = check_expr(fcx, e);
auto expr_1 = demand_expr(fcx, fcx.ret_ty, expr_0);
ret @fold.respan[ast.expr_](expr.span,
ast.expr_ret(some(expr_1)));
}
}
}
case (ast.expr_be(?e)) {
/* FIXME: prove instead of check */
check ast.is_call_expr(e);
auto expr_0 = check_expr(fcx, e);
auto expr_1 = demand_expr(fcx, fcx.ret_ty, expr_0);
ret @fold.respan[ast.expr_](expr.span,
ast.expr_be(expr_1));
}
case (ast.expr_log(?e)) {
auto expr_t = check_expr(fcx, e);
ret @fold.respan[ast.expr_](expr.span, ast.expr_log(expr_t));
}
case (ast.expr_check_expr(?e)) {
auto expr_t = check_expr(fcx, e);
demand(fcx, expr.span, plain_ty(ty.ty_bool), expr_ty(expr_t));
ret @fold.respan[ast.expr_](expr.span,
ast.expr_check_expr(expr_t));
}
case (ast.expr_assign(?lhs, ?rhs, _)) {
auto lhs_0 = check_expr(fcx, lhs);
auto rhs_0 = check_expr(fcx, rhs);
@ -1806,52 +1857,6 @@ fn check_stmt(&@fn_ctxt fcx, &@ast.stmt stmt) -> @ast.stmt {
ret stmt;
}
case (ast.stmt_ret(?expr_opt)) {
alt (expr_opt) {
case (none[@ast.expr]) {
auto nil = plain_ty(ty.ty_nil);
if (!are_compatible(fcx, fcx.ret_ty, nil)) {
fcx.ccx.sess.err("ret; in function "
+ "returning non-nil");
}
ret stmt;
}
case (some[@ast.expr](?expr)) {
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_ret(some(expr_1)));
}
}
}
case (ast.stmt_be(?expr)) {
/* FIXME: prove instead of check */
check ast.is_call_expr(expr);
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 (ast.stmt_log(?expr)) {
auto expr_t = check_expr(fcx, expr);
ret @fold.respan[ast.stmt_](stmt.span, ast.stmt_log(expr_t));
}
case (ast.stmt_check_expr(?expr)) {
auto expr_t = check_expr(fcx, expr);
demand(fcx, expr.span, plain_ty(ty.ty_bool), expr_ty(expr_t));
ret @fold.respan[ast.stmt_](stmt.span,
ast.stmt_check_expr(expr_t));
}
case (ast.stmt_fail) {
ret stmt;
}
case (ast.stmt_expr(?expr)) {
auto expr_t = check_expr(fcx, expr);
ret @fold.respan[ast.stmt_](stmt.span, ast.stmt_expr(expr_t));