Add basic front-end support for 'for each' loops.
This commit is contained in:
parent
15a01f5c36
commit
4a72a23171
@ -151,6 +151,7 @@ tag expr_ {
|
||||
expr_if(@expr, block, vec[tup(@expr, block)], option.t[block], ann);
|
||||
expr_while(@expr, block, ann);
|
||||
expr_for(@decl, @expr, block, ann);
|
||||
expr_for_each(@decl, @expr, block, ann);
|
||||
expr_do_while(block, @expr, ann);
|
||||
expr_alt(@expr, vec[arm], ann);
|
||||
expr_block(block, ann);
|
||||
|
@ -1049,8 +1049,14 @@ impure fn parse_head_local(parser p) -> @ast.decl {
|
||||
impure fn parse_for_expr(parser p) -> @ast.expr {
|
||||
auto lo = p.get_span();
|
||||
auto hi = lo;
|
||||
auto is_each = false;
|
||||
|
||||
expect(p, token.FOR);
|
||||
if (p.peek() == token.EACH) {
|
||||
is_each = true;
|
||||
p.bump();
|
||||
}
|
||||
|
||||
expect (p, token.LPAREN);
|
||||
|
||||
auto decl = parse_head_local(p);
|
||||
@ -1060,9 +1066,16 @@ impure fn parse_for_expr(parser p) -> @ast.expr {
|
||||
expect(p, token.RPAREN);
|
||||
auto body = parse_block(p);
|
||||
hi = body.span;
|
||||
ret @spanned(lo, hi, ast.expr_for(decl, seq, body, ast.ann_none));
|
||||
if (is_each) {
|
||||
ret @spanned(lo, hi, ast.expr_for_each(decl, seq, body,
|
||||
ast.ann_none));
|
||||
} else {
|
||||
ret @spanned(lo, hi, ast.expr_for(decl, seq, body,
|
||||
ast.ann_none));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impure fn parse_while_expr(parser p) -> @ast.expr {
|
||||
auto lo = p.get_span();
|
||||
auto hi = lo;
|
||||
@ -1422,6 +1435,8 @@ fn stmt_ends_with_semi(@ast.stmt stmt) -> bool {
|
||||
case (ast.expr_cast(_,_,_)) { ret true; }
|
||||
case (ast.expr_if(_,_,_,_,_)) { ret false; }
|
||||
case (ast.expr_for(_,_,_,_)) { ret false; }
|
||||
case (ast.expr_for_each(_,_,_,_))
|
||||
{ ret false; }
|
||||
case (ast.expr_while(_,_,_)) { ret false; }
|
||||
case (ast.expr_do_while(_,_,_)) { ret false; }
|
||||
case (ast.expr_alt(_,_,_)) { ret false; }
|
||||
|
@ -112,6 +112,10 @@ type ast_fold[ENV] =
|
||||
@decl decl, @expr seq, &block body,
|
||||
ann a) -> @expr) fold_expr_for,
|
||||
|
||||
(fn(&ENV e, &span sp,
|
||||
@decl decl, @expr seq, &block body,
|
||||
ann a) -> @expr) fold_expr_for_each,
|
||||
|
||||
(fn(&ENV e, &span sp,
|
||||
@expr cond, &block body,
|
||||
ann a) -> @expr) fold_expr_while,
|
||||
@ -574,6 +578,13 @@ fn fold_expr[ENV](&ENV env, ast_fold[ENV] fld, &@expr e) -> @expr {
|
||||
ret fld.fold_expr_for(env_, e.span, ddecl, sseq, bbody, t);
|
||||
}
|
||||
|
||||
case (ast.expr_for_each(?decl, ?seq, ?body, ?t)) {
|
||||
auto ddecl = fold_decl(env_, fld, decl);
|
||||
auto sseq = fold_expr(env_, fld, seq);
|
||||
auto bbody = fold_block(env_, fld, body);
|
||||
ret fld.fold_expr_for_each(env_, e.span, ddecl, sseq, bbody, t);
|
||||
}
|
||||
|
||||
case (ast.expr_while(?cnd, ?body, ?t)) {
|
||||
auto ccnd = fold_expr(env_, fld, cnd);
|
||||
auto bbody = fold_block(env_, fld, body);
|
||||
@ -1087,6 +1098,12 @@ fn identity_fold_expr_for[ENV](&ENV env, &span sp,
|
||||
ret @respan(sp, ast.expr_for(d, seq, body, a));
|
||||
}
|
||||
|
||||
fn identity_fold_expr_for_each[ENV](&ENV env, &span sp,
|
||||
@decl d, @expr seq,
|
||||
&block body, ann a) -> @expr {
|
||||
ret @respan(sp, ast.expr_for_each(d, seq, body, a));
|
||||
}
|
||||
|
||||
fn identity_fold_expr_while[ENV](&ENV env, &span sp,
|
||||
@expr cond, &block body, ann a) -> @expr {
|
||||
ret @respan(sp, ast.expr_while(cond, body, a));
|
||||
@ -1402,6 +1419,8 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
|
||||
fold_expr_cast = bind identity_fold_expr_cast[ENV](_,_,_,_,_),
|
||||
fold_expr_if = bind identity_fold_expr_if[ENV](_,_,_,_,_,_,_),
|
||||
fold_expr_for = bind identity_fold_expr_for[ENV](_,_,_,_,_,_),
|
||||
fold_expr_for_each
|
||||
= bind identity_fold_expr_for_each[ENV](_,_,_,_,_,_),
|
||||
fold_expr_while = bind identity_fold_expr_while[ENV](_,_,_,_,_),
|
||||
fold_expr_do_while
|
||||
= bind identity_fold_expr_do_while[ENV](_,_,_,_,_),
|
||||
|
@ -565,6 +565,9 @@ fn update_env_for_expr(&env e, @ast.expr x) -> env {
|
||||
case (ast.expr_for(?d, _, _, _)) {
|
||||
ret rec(scopes = cons[scope](scope_loop(d), @e.scopes) with e);
|
||||
}
|
||||
case (ast.expr_for_each(?d, _, _, _)) {
|
||||
ret rec(scopes = cons[scope](scope_loop(d), @e.scopes) with e);
|
||||
}
|
||||
case (_) { }
|
||||
}
|
||||
ret e;
|
||||
|
@ -2116,6 +2116,15 @@ fn trans_for(@block_ctxt cx,
|
||||
bind inner(_, local, _, _, body));
|
||||
}
|
||||
|
||||
fn trans_for_each(@block_ctxt cx,
|
||||
@ast.decl decl,
|
||||
@ast.expr seq,
|
||||
&ast.block body) -> result {
|
||||
cx.fcx.ccx.sess.unimpl("for each loop");
|
||||
fail;
|
||||
}
|
||||
|
||||
|
||||
fn trans_while(@block_ctxt cx, @ast.expr cond,
|
||||
&ast.block body) -> result {
|
||||
|
||||
@ -3035,6 +3044,10 @@ fn trans_expr(@block_ctxt cx, @ast.expr e) -> result {
|
||||
ret trans_for(cx, decl, seq, body);
|
||||
}
|
||||
|
||||
case (ast.expr_for_each(?decl, ?seq, ?body, _)) {
|
||||
ret trans_for_each(cx, decl, seq, body);
|
||||
}
|
||||
|
||||
case (ast.expr_while(?cond, ?body, _)) {
|
||||
ret trans_while(cx, cond, body);
|
||||
}
|
||||
|
@ -676,6 +676,8 @@ fn expr_ty(@ast.expr expr) -> @t {
|
||||
case (ast.expr_cast(_, _, ?ann)) { ret ann_to_type(ann); }
|
||||
case (ast.expr_if(_, _, _, _, ?ann)) { ret ann_to_type(ann); }
|
||||
case (ast.expr_for(_, _, _, ?ann)) { ret ann_to_type(ann); }
|
||||
case (ast.expr_for_each(_, _, _, ?ann))
|
||||
{ ret ann_to_type(ann); }
|
||||
case (ast.expr_while(_, _, ?ann)) { ret ann_to_type(ann); }
|
||||
case (ast.expr_do_while(_, _, ?ann)) { ret ann_to_type(ann); }
|
||||
case (ast.expr_alt(_, _, ?ann)) { ret ann_to_type(ann); }
|
||||
|
@ -995,6 +995,10 @@ fn demand_expr_full(&@fn_ctxt fcx, @ty.t expected, @ast.expr e,
|
||||
auto t = demand(fcx, e.span, expected, ann_to_type(ann));
|
||||
e_1 = ast.expr_for(decl, seq, bloc, ast.ann_type(t));
|
||||
}
|
||||
case (ast.expr_for_each(?decl, ?seq, ?bloc, ?ann)) {
|
||||
auto t = demand(fcx, e.span, expected, ann_to_type(ann));
|
||||
e_1 = ast.expr_for_each(decl, seq, bloc, ast.ann_type(t));
|
||||
}
|
||||
case (ast.expr_while(?cond, ?bloc, ?ann)) {
|
||||
auto t = demand(fcx, e.span, expected, ann_to_type(ann));
|
||||
e_1 = ast.expr_while(cond, bloc, ast.ann_type(t));
|
||||
@ -1448,6 +1452,17 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
|
||||
body_1, ann));
|
||||
}
|
||||
|
||||
case (ast.expr_for_each(?decl, ?seq, ?body, _)) {
|
||||
auto decl_1 = check_decl_local(fcx, decl);
|
||||
auto seq_1 = check_expr(fcx, seq);
|
||||
auto body_1 = check_block(fcx, body);
|
||||
|
||||
auto ann = ast.ann_type(plain_ty(ty.ty_nil));
|
||||
ret @fold.respan[ast.expr_](expr.span,
|
||||
ast.expr_for_each(decl_1, seq_1,
|
||||
body_1, ann));
|
||||
}
|
||||
|
||||
case (ast.expr_while(?cond, ?body, _)) {
|
||||
auto cond_0 = check_expr(fcx, cond);
|
||||
auto cond_1 = demand_expr(fcx, plain_ty(ty.ty_bool), cond_0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user