about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@mozilla.com>2011-01-20 15:02:12 -0800
committerGraydon Hoare <graydon@mozilla.com>2011-01-20 15:02:12 -0800
commita8af013077c01901426f7cb829a98c7f1fbe6613 (patch)
tree2b48bd91d52cb31e54bc20f012a0e2d46c7a9cd9
parent7fdb6437d862d18a50f6c9d3f79f08e8d90905c4 (diff)
downloadrust-a8af013077c01901426f7cb829a98c7f1fbe6613.tar.gz
rust-a8af013077c01901426f7cb829a98c7f1fbe6613.zip
Adjust AST encoding, teach fold about linear for loops.
-rw-r--r--src/comp/front/ast.rs2
-rw-r--r--src/comp/front/parser.rs31
-rw-r--r--src/comp/middle/fold.rs18
3 files changed, 39 insertions, 12 deletions
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs
index e2ccce7bc81..6c91e91376c 100644
--- a/src/comp/front/ast.rs
+++ b/src/comp/front/ast.rs
@@ -150,7 +150,7 @@ tag expr_ {
     expr_cast(@expr, @ty, ann);
     expr_if(@expr, block, option.t[block], ann);
     expr_while(@expr, block, ann);
-    expr_for(@local, @expr, block, ann);
+    expr_for(@decl, @expr, block, ann);
     expr_do_while(block, @expr, ann);
     expr_alt(@expr, vec[arm], ann);
     expr_block(block, ann);
diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs
index ec427075911..f57add7ee89 100644
--- a/src/comp/front/parser.rs
+++ b/src/comp/front/parser.rs
@@ -891,27 +891,35 @@ impure fn parse_if_expr(parser p) -> @ast.expr {
     ret @spanned(lo, hi, ast.expr_if(cond, thn, els, ast.ann_none));
 }
 
-impure fn parse_for_expr(parser p) -> @ast.expr {
+impure fn parse_head_local(parser p) -> @ast.decl {
     auto lo = p.get_span();
-    auto hi = lo;
-
-    expect(p, token.FOR);
-    expect (p, token.LPAREN);
-
     let @ast.local local;
     if (p.peek() == token.AUTO) {
-        p.bump();
         local = parse_auto_local(p);
     } else {
         local = parse_typed_local(p);
     }
+    auto hi = p.get_span();
+    ret @spanned(lo, hi, ast.decl_local(local));
+}
+
+
+
+impure fn parse_for_expr(parser p) -> @ast.expr {
+    auto lo = p.get_span();
+    auto hi = lo;
+
+    expect(p, token.FOR);
+    expect (p, token.LPAREN);
+
+    auto decl = parse_head_local(p);
     expect(p, token.IN);
 
     auto seq = parse_expr(p);
     expect(p, token.RPAREN);
     auto body = parse_block(p);
     hi = body.span;
-    ret @spanned(lo, hi, ast.expr_for(local, seq, body, ast.ann_none));
+    ret @spanned(lo, hi, ast.expr_for(decl, seq, body, ast.ann_none));
 }
 
 impure fn parse_while_expr(parser p) -> @ast.expr {
@@ -1078,7 +1086,8 @@ impure fn parse_pat(parser p) -> @ast.pat {
     ret @spanned(lo, hi, pat);
 }
 
-impure fn parse_local(&option.t[@ast.ty] tyopt, parser p) -> @ast.local {
+impure fn parse_local_full(&option.t[@ast.ty] tyopt,
+                           parser p) -> @ast.local {
     auto ident = parse_ident(p);
     auto init = parse_initializer(p);
     ret @rec(ty = tyopt,
@@ -1091,11 +1100,11 @@ impure fn parse_local(&option.t[@ast.ty] tyopt, parser p) -> @ast.local {
 
 impure fn parse_typed_local(parser p) -> @ast.local {
     auto ty = parse_ty(p);
-    ret parse_local(some(ty), p);
+    ret parse_local_full(some(ty), p);
 }
 
 impure fn parse_auto_local(parser p) -> @ast.local {
-    ret parse_local(none[@ast.ty], p);
+    ret parse_local_full(none[@ast.ty], p);
 }
 
 impure fn parse_let(parser p) -> @ast.decl {
diff --git a/src/comp/middle/fold.rs b/src/comp/middle/fold.rs
index 618790ee14e..d8688e001f6 100644
--- a/src/comp/middle/fold.rs
+++ b/src/comp/middle/fold.rs
@@ -104,6 +104,10 @@ type ast_fold[ENV] =
          ann a) -> @expr)                         fold_expr_if,
 
      (fn(&ENV e, &span sp,
+         @decl decl, @expr seq, &block body,
+         ann a) -> @expr)                         fold_expr_for,
+
+     (fn(&ENV e, &span sp,
          @expr cond, &block body,
          ann a) -> @expr)                         fold_expr_while,
 
@@ -509,6 +513,13 @@ fn fold_expr[ENV](&ENV env, ast_fold[ENV] fld, &@expr e) -> @expr {
             ret fld.fold_expr_if(env_, e.span, ccnd, tthn, eels, t);
         }
 
+        case (ast.expr_for(?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(env_, e.span, ddecl, seq, bbody, t);
+        }
+
         case (ast.expr_while(?cnd, ?body, ?t)) {
             auto ccnd = fold_expr(env_, fld, cnd);
             auto bbody = fold_block(env_, fld, body);
@@ -950,6 +961,12 @@ fn identity_fold_expr_if[ENV](&ENV env, &span sp,
     ret @respan(sp, ast.expr_if(cond, thn, els, a));
 }
 
+fn identity_fold_expr_for[ENV](&ENV env, &span sp,
+                               @decl d, @expr seq,
+                               &block body, ann a) -> @expr {
+    ret @respan(sp, ast.expr_for(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));
@@ -1214,6 +1231,7 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
          fold_expr_lit    = bind identity_fold_expr_lit[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_while  = bind identity_fold_expr_while[ENV](_,_,_,_,_),
          fold_expr_do_while
                           = bind identity_fold_expr_do_while[ENV](_,_,_,_,_),