about summary refs log tree commit diff
path: root/src/comp/syntax/parse
diff options
context:
space:
mode:
authorMichael Sullivan <sully@msully.net>2011-08-12 12:58:37 -0700
committerMichael Sullivan <sully@msully.net>2011-08-15 15:48:10 -0700
commit9b50011aaeeb7ad37c83124ac5e989f2c7ff8c8d (patch)
tree5e64cd6fc7444c9a728476e5ec85e44d375bcd0d /src/comp/syntax/parse
parent814bf41d898cd0410873f6c05c03a2b34366bfde (diff)
downloadrust-9b50011aaeeb7ad37c83124ac5e989f2c7ff8c8d.tar.gz
rust-9b50011aaeeb7ad37c83124ac5e989f2c7ff8c8d.zip
Parse type inferred lambda-block expressions.
Diffstat (limited to 'src/comp/syntax/parse')
-rw-r--r--src/comp/syntax/parse/parser.rs48
1 files changed, 41 insertions, 7 deletions
diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs
index 86d61ba1f94..8b7621b9018 100644
--- a/src/comp/syntax/parse/parser.rs
+++ b/src/comp/syntax/parse/parser.rs
@@ -600,16 +600,28 @@ fn parse_ty(p: &parser, colons_before_params: bool) -> @ast::ty {
     ret parse_ty_postfix(t, p, colons_before_params);
 }
 
-fn parse_arg(p: &parser) -> ast::arg {
-    let m: ast::mode = ast::val;
-    let i: ast::ident = parse_value_ident(p);
-    expect(p, token::COLON);
+fn parse_arg_mode(p: &parser) -> ast::mode {
     if eat(p, token::BINOP(token::AND)) {
-        m = ast::alias(eat_word(p, "mutable"));
+        ast::alias(eat_word(p, "mutable"))
     } else if eat(p, token::BINOP(token::MINUS)) {
-        m = ast::move;
+        ast::move
+    } else {
+        ast::val
     }
-    let t: @ast::ty = parse_ty(p, false);
+}
+
+fn parse_arg(p: &parser) -> ast::arg {
+    let i = parse_value_ident(p);
+    expect(p, token::COLON);
+    let m = parse_arg_mode(p);
+    let t = parse_ty(p, false);
+    ret {mode: m, ty: t, ident: i, id: p.get_id()};
+}
+
+fn parse_fn_block_arg(p: &parser) -> ast::arg {
+    let m = parse_arg_mode(p);
+    let i = parse_value_ident(p);
+    let t = @spanned(p.get_lo_pos(), p.get_hi_pos(), ast::ty_infer);
     ret {mode: m, ty: t, ident: i, id: p.get_id()};
 }
 
@@ -808,6 +820,8 @@ fn parse_bottom_expr(p: &parser) -> @ast::expr {
             hi = p.get_hi_pos();
             expect(p, token::RBRACE);
             ex = ast::expr_rec(fields, base);
+        } else if p.peek() == token::BINOP(token::OR) {
+            ret parse_fn_block_expr(p);
         } else {
             let blk = parse_block_tail(p, lo);
             ret mk_expr(p, blk.span.lo, blk.span.hi, ast::expr_block(blk));
@@ -1314,6 +1328,14 @@ fn parse_fn_expr(p: &parser, proto: ast::proto) -> @ast::expr {
     ret mk_expr(p, lo, body.span.hi, ast::expr_fn(_fn));
 }
 
+fn parse_fn_block_expr(p: &parser) -> @ast::expr {
+    let lo = p.get_last_lo_pos();
+    let decl = parse_fn_block_decl(p);
+    let body = parse_block_tail(p, lo);
+    let _fn = {decl: decl, proto: ast::proto_block, body: body};
+    ret mk_expr(p, lo, body.span.hi, ast::expr_fn(_fn));
+}
+
 fn parse_else_expr(p: &parser) -> @ast::expr {
     if eat_word(p, "if") {
         ret parse_if_expr(p);
@@ -1794,6 +1816,18 @@ fn parse_fn_decl(p: &parser, purity: ast::purity, il: ast::inlineness)
     }
 }
 
+fn parse_fn_block_decl(p: &parser) -> ast::fn_decl {
+    let inputs: ast::spanned[[ast::arg]] =
+        parse_seq(token::BINOP(token::OR), token::BINOP(token::OR),
+                  some(token::COMMA), parse_fn_block_arg, p);
+    ret {inputs: inputs.node,
+         output: @spanned(p.get_lo_pos(), p.get_hi_pos(), ast::ty_infer),
+         purity: ast::impure_fn,
+         il: ast::il_normal,
+         cf: ast::return,
+         constraints: ~[]};
+}
+
 fn parse_fn(p: &parser, proto: ast::proto, purity: ast::purity,
             il: ast::inlineness) -> ast::_fn {
     let decl = parse_fn_decl(p, purity, il);