about summary refs log tree commit diff
path: root/src/comp/syntax
diff options
context:
space:
mode:
authorMarijn Haverbeke <marijnh@gmail.com>2011-10-21 14:11:24 +0200
committerMarijn Haverbeke <marijnh@gmail.com>2011-10-21 14:24:14 +0200
commit71147024962318033ade76ba741d1ecc1dfae3ce (patch)
tree42b750199d41f59916ac0542aa141fb254bd9be0 /src/comp/syntax
parent0ce40f60e79598c198851154cc978375ed5e7747 (diff)
Change the way block calls are parsed, mark them as block-calls.
This makes it possible to omit the semicolon after the block, and will
cause the pretty-printer to properly print such calls (if
pretty-printing of blocks wasn't so broken). Block calls (with the
block outside of the parentheses) can now only occur at statement
level, and their value can not be used. When calling a block-style
function that returns a useful value, the block must be put insde the
parentheses.

Issue #1054
Diffstat (limited to 'src/comp/syntax')
-rw-r--r--src/comp/syntax/ast.rs2
-rw-r--r--src/comp/syntax/ast_util.rs2
-rw-r--r--src/comp/syntax/ext/fmt.rs2
-rw-r--r--src/comp/syntax/fold.rs5
-rw-r--r--src/comp/syntax/parse/parser.rs35
-rw-r--r--src/comp/syntax/print/pprust.rs16
-rw-r--r--src/comp/syntax/visit.rs2
7 files changed, 37 insertions, 27 deletions
diff --git a/src/comp/syntax/ast.rs b/src/comp/syntax/ast.rs
index a971653c5f1..9abab553331 100644
--- a/src/comp/syntax/ast.rs
+++ b/src/comp/syntax/ast.rs
@@ -184,7 +184,7 @@ type expr = {id: node_id, node: expr_, span: span};
 tag expr_ {
     expr_vec([@expr], mutability);
     expr_rec([field], option::t<@expr>);
-    expr_call(@expr, [@expr]);
+    expr_call(@expr, [@expr], bool);
     expr_tup([@expr]);
     expr_self_method(ident);
     expr_bind(@expr, [option::t<@expr>]);
diff --git a/src/comp/syntax/ast_util.rs b/src/comp/syntax/ast_util.rs
index 3d4fe27d980..b10ce87a697 100644
--- a/src/comp/syntax/ast_util.rs
+++ b/src/comp/syntax/ast_util.rs
@@ -163,7 +163,7 @@ fn is_exported(i: ident, m: _mod) -> bool {
 }
 
 pure fn is_call_expr(e: @expr) -> bool {
-    alt e.node { expr_call(_, _) { true } _ { false } }
+    alt e.node { expr_call(_, _, _) { true } _ { false } }
 }
 
 fn is_constraint_arg(e: @expr) -> bool {
diff --git a/src/comp/syntax/ext/fmt.rs b/src/comp/syntax/ext/fmt.rs
index b51db707daf..f3fb25acaf9 100644
--- a/src/comp/syntax/ext/fmt.rs
+++ b/src/comp/syntax/ext/fmt.rs
@@ -79,7 +79,7 @@ fn pieces_to_expr(cx: ext_ctxt, sp: span, pieces: [piece], args: [@ast::expr])
     fn make_call(cx: ext_ctxt, sp: span, fn_path: [ast::ident],
                  args: [@ast::expr]) -> @ast::expr {
         let pathexpr = make_path_expr(cx, sp, fn_path);
-        let callexpr = ast::expr_call(pathexpr, args);
+        let callexpr = ast::expr_call(pathexpr, args, false);
         ret @{id: cx.next_id(), node: callexpr, span: sp};
     }
     fn make_rec_expr(cx: ext_ctxt, sp: span,
diff --git a/src/comp/syntax/fold.rs b/src/comp/syntax/fold.rs
index 276967b792b..e79ca1adf98 100644
--- a/src/comp/syntax/fold.rs
+++ b/src/comp/syntax/fold.rs
@@ -348,8 +348,9 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ {
                      option::map(fld.fold_expr, maybe_expr))
           }
           expr_tup(elts) { expr_tup(vec::map(fld.fold_expr, elts)) }
-          expr_call(f, args) {
-            expr_call(fld.fold_expr(f), fld.map_exprs(fld.fold_expr, args))
+          expr_call(f, args, blk) {
+            expr_call(fld.fold_expr(f), fld.map_exprs(fld.fold_expr, args),
+                      blk)
           }
           expr_self_method(id) { expr_self_method(fld.fold_ident(id)) }
           expr_bind(f, args) {
diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs
index 1a29a033f56..8f632165772 100644
--- a/src/comp/syntax/parse/parser.rs
+++ b/src/comp/syntax/parse/parser.rs
@@ -977,7 +977,7 @@ fn parse_bottom_expr(p: parser) -> @ast::expr {
             parse_seq(token::LPAREN, token::RPAREN, some(token::COMMA),
                       parse_expr, p);
         hi = es.span.hi;
-        ex = ast::expr_call(f, es.node);
+        ex = ast::expr_call(f, es.node, false);
     } else if p.peek() == token::MOD_SEP ||
                   is_ident(p.peek()) && !is_word(p, "true") &&
                       !is_word(p, "false") {
@@ -1051,7 +1051,7 @@ fn parse_dot_or_call_expr_with(p: parser, e: @ast::expr) -> @ast::expr {
                 let es = parse_seq(token::LPAREN, token::RPAREN,
                                    some(token::COMMA), parse_expr, p);
                 hi = es.span.hi;
-                let nd = ast::expr_call(e, es.node);
+                let nd = ast::expr_call(e, es.node, false);
                 e = mk_expr(p, lo, hi, nd);
             }
           }
@@ -1073,19 +1073,6 @@ fn parse_dot_or_call_expr_with(p: parser, e: @ast::expr) -> @ast::expr {
               t { unexpected(p, t); }
             }
           }
-          token::LBRACE. when is_bar(p.look_ahead(1u)) {
-            p.bump();
-            let blk = parse_fn_block_expr(p);
-            alt e.node {
-              ast::expr_call(f, args) {
-                e = @{node: ast::expr_call(f, args + [blk]) with *e};
-              }
-              _ {
-                e = mk_expr(p, lo, p.get_last_hi_pos(),
-                            ast::expr_call(e, [blk]));
-              }
-            }
-          }
           _ { ret e; }
         }
     }
@@ -1569,7 +1556,6 @@ fn parse_source_stmt(p: parser) -> @ast::stmt {
         let decl = parse_let(p);
         ret @spanned(lo, decl.span.hi, ast::stmt_decl(decl, p.get_id()));
     } else {
-
         let item_attrs;
         alt parse_outer_attrs_or_ext(p) {
           none. { item_attrs = []; }
@@ -1589,7 +1575,6 @@ fn parse_source_stmt(p: parser) -> @ast::stmt {
             }
         }
 
-
         alt maybe_item {
           some(i) {
             let hi = i.span.hi;
@@ -1599,6 +1584,21 @@ fn parse_source_stmt(p: parser) -> @ast::stmt {
           none. {
             // Remainder are line-expr stmts.
             let e = parse_expr(p);
+            // See if it is a block call
+            if p.peek() == token::LBRACE && is_bar(p.look_ahead(1u)) {
+                p.bump();
+                let blk = parse_fn_block_expr(p);
+                alt e.node {
+                  ast::expr_call(f, args, false) {
+                    e = @{node: ast::expr_call(f, args + [blk], true)
+                        with *e};
+                  }
+                  _ {
+                    e = mk_expr(p, lo, p.get_last_hi_pos(),
+                                ast::expr_call(e, [blk], true));
+                  }
+                }
+            }
             ret @spanned(lo, e.span.hi, ast::stmt_expr(e, p.get_id()));
           }
           _ { p.fatal("expected statement"); }
@@ -1624,6 +1624,7 @@ fn expr_has_value(e: @ast::expr) -> bool {
       ast::expr_for(_, _, blk) | ast::expr_do_while(blk, _) {
         !option::is_none(blk.node.expr)
       }
+      ast::expr_call(_, _, true) { false }
       _ { true }
     }
 }
diff --git a/src/comp/syntax/print/pprust.rs b/src/comp/syntax/print/pprust.rs
index 9a7944f47c8..91e3f2ffb59 100644
--- a/src/comp/syntax/print/pprust.rs
+++ b/src/comp/syntax/print/pprust.rs
@@ -727,11 +727,19 @@ fn print_expr(s: ps, &&expr: @ast::expr) {
         commasep_exprs(s, inconsistent, exprs);
         pclose(s);
       }
-      ast::expr_call(func, args) {
+      ast::expr_call(func, args, has_block) {
         print_expr_parens_if_not_bot(s, func);
-        popen(s);
-        commasep_exprs(s, inconsistent, args);
-        pclose(s);
+        let base_args = args, blk = none;
+        if has_block { blk = some(vec::pop(base_args)); }
+        if !has_block || vec::len(base_args) > 0u {
+            popen(s);
+            commasep_exprs(s, inconsistent, base_args);
+            pclose(s);
+        }
+        if has_block {
+            nbsp(s);
+            print_expr(s, option::get(blk));
+        }
       }
       ast::expr_self_method(ident) {
         word(s.s, "self.");
diff --git a/src/comp/syntax/visit.rs b/src/comp/syntax/visit.rs
index 3cd44fe10da..0725611eb04 100644
--- a/src/comp/syntax/visit.rs
+++ b/src/comp/syntax/visit.rs
@@ -245,7 +245,7 @@ fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) {
         visit_expr_opt(base, e, v);
       }
       expr_tup(elts) { for el in elts { v.visit_expr(el, e, v); } }
-      expr_call(callee, args) {
+      expr_call(callee, args, _) {
         visit_exprs(args, e, v);
         v.visit_expr(callee, e, v);
       }