about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2012-06-18 17:42:09 -0700
committerBrian Anderson <banderson@mozilla.com>2012-06-18 17:42:30 -0700
commit1ec5a5c635dba820246cbb4c7bea031b6add3b07 (patch)
tree532bcd395a250706f08436d6b83e7fdba4a5c23c /src/libsyntax
parentee9e5b9d201d876c07b00663e2df224eb170a0f2 (diff)
downloadrust-1ec5a5c635dba820246cbb4c7bea031b6add3b07.tar.gz
rust-1ec5a5c635dba820246cbb4c7bea031b6add3b07.zip
Add 'do' expressions
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs2
-rw-r--r--src/libsyntax/fold.rs1
-rw-r--r--src/libsyntax/parse/parser.rs19
-rw-r--r--src/libsyntax/parse/token.rs2
-rw-r--r--src/libsyntax/print/pprust.rs3
-rw-r--r--src/libsyntax/visit.rs3
6 files changed, 28 insertions, 2 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 5f2a5b2accb..a356e716a9a 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -318,6 +318,8 @@ enum expr_ {
     // easily type this (a function returning nil on the inside but bool on
     // the outside).
     expr_loop_body(@expr),
+    // Like expr_loop_body but for 'do' blocks
+    expr_do_body(@expr),
     expr_block(blk),
 
     /*
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 0d5966db4f5..7ddbfb52e94 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -415,6 +415,7 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ {
           }
           expr_unary(binop, ohs) { expr_unary(binop, fld.fold_expr(ohs)) }
           expr_loop_body(f) { expr_loop_body(fld.fold_expr(f)) }
+          expr_do_body(f) { expr_do_body(fld.fold_expr(f)) }
           expr_lit(_) { copy e }
           expr_cast(expr, ty) { expr_cast(fld.fold_expr(expr), ty) }
           expr_addr_of(m, ohs) { expr_addr_of(m, fld.fold_expr(ohs)) }
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 08eaa779291..45badde0016 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -772,6 +772,8 @@ class parser {
             ret pexpr(self.parse_if_expr());
         } else if self.eat_keyword("for") {
             ret pexpr(self.parse_for_expr());
+        } else if self.eat_keyword("do") {
+            ret pexpr(self.parse_do_expr());
         } else if self.eat_keyword("while") {
             ret pexpr(self.parse_while_expr());
         } else if self.eat_keyword("loop") {
@@ -1312,6 +1314,23 @@ class parser {
         }
     }
 
+    fn parse_do_expr() -> @expr {
+        let lo = self.last_span;
+        let call = self.parse_expr_res(RESTRICT_STMT_EXPR);
+        alt call.node {
+          expr_call(f, args, true) {
+            let b_arg = vec::last(args);
+            let last = self.mk_expr(b_arg.span.lo, b_arg.span.hi,
+                                    expr_do_body(b_arg));
+            @{node: expr_call(f, vec::init(args) + [last], true)
+              with *call}
+          }
+          _ {
+            self.span_fatal(lo, "`do` must be followed by a block call");
+          }
+        }
+    }
+
     fn parse_while_expr() -> @expr {
         let lo = self.last_span.lo;
         let cond = self.parse_expr();
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 7fb6165f7f1..ec14778dc02 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -287,7 +287,7 @@ fn restricted_keyword_table() -> hashmap<str, ()> {
         "assert",
         "be", "break",
         "check", "claim", "class", "const", "cont", "copy", "crust",
-        "drop",
+        "do", "drop",
         "else", "enum", "export",
         "fail", "false", "fn", "for",
         "if", "iface", "impl", "import",
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 43b498eae62..e0e30dc72fc 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1048,6 +1048,9 @@ fn print_expr(s: ps, &&expr: @ast::expr) {
       ast::expr_loop_body(body) {
         print_expr(s, body);
       }
+      ast::expr_do_body(body) {
+        print_expr(s, body);
+      }
       ast::expr_block(blk) {
         // containing cbox, will be closed by print-block at }
         cbox(s, indent_unit);
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index a7db0fe0851..4a68850674d 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -382,7 +382,8 @@ fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) {
         for args.each {|eo| visit_expr_opt(eo, e, v); }
       }
       expr_binary(_, a, b) { v.visit_expr(a, e, v); v.visit_expr(b, e, v); }
-      expr_addr_of(_, x) | expr_unary(_, x) | expr_loop_body(x) |
+      expr_addr_of(_, x) | expr_unary(_, x) |
+      expr_loop_body(x) | expr_do_body(x) |
       expr_check(_, x) | expr_assert(x) {
         v.visit_expr(x, e, v);
       }