@@ -10,7 +10,12 @@ import util::interner;
10
10
import ast:: { node_id, spanned} ;
11
11
import front:: attr;
12
12
13
- tag restriction { UNRESTRICTED ; RESTRICT_NO_CALL_EXPRS ; RESTRICT_NO_BAR_OP ; }
13
+ tag restriction {
14
+ UNRESTRICTED ;
15
+ RESTRICT_STMT_EXPR ;
16
+ RESTRICT_NO_CALL_EXPRS ;
17
+ RESTRICT_NO_BAR_OP ;
18
+ }
14
19
15
20
tag file_type { CRATE_FILE ; SOURCE_FILE ; }
16
21
@@ -977,35 +982,54 @@ fn parse_syntax_ext_naked(p: parser, lo: uint) -> @ast::expr {
977
982
978
983
fn parse_dot_or_call_expr ( p : parser ) -> @ast:: expr {
979
984
let b = parse_bottom_expr ( p) ;
980
- if expr_has_value ( b) { parse_dot_or_call_expr_with ( p, b) }
981
- else { b }
985
+ parse_dot_or_call_expr_with ( p, b)
986
+ }
987
+
988
+ fn permits_call ( p : parser ) -> bool {
989
+ ret p. get_restriction ( ) != RESTRICT_NO_CALL_EXPRS ;
982
990
}
983
991
984
992
fn parse_dot_or_call_expr_with ( p : parser , e : @ast:: expr ) -> @ast:: expr {
985
993
let lo = e. span . lo ;
986
994
let hi = e. span . hi ;
987
995
let e = e;
988
- while true {
996
+ while ! expr_is_complete ( p , e ) {
989
997
alt p. peek ( ) {
990
- token:: LPAREN . {
991
- if p. get_restriction ( ) == RESTRICT_NO_CALL_EXPRS {
992
- ret e;
993
- } else {
994
- // Call expr.
995
- let es = parse_seq ( token:: LPAREN , token:: RPAREN ,
996
- seq_sep ( token:: COMMA ) , parse_expr, p) ;
997
- hi = es. span . hi ;
998
- let nd = ast:: expr_call ( e, es. node , false ) ;
999
- e = mk_expr ( p, lo, hi, nd) ;
998
+ // expr(...)
999
+ token:: LPAREN . when permits_call ( p) {
1000
+ let es = parse_seq ( token:: LPAREN , token:: RPAREN ,
1001
+ seq_sep ( token:: COMMA ) , parse_expr, p) ;
1002
+ hi = es. span . hi ;
1003
+ let nd = ast:: expr_call ( e, es. node , false ) ;
1004
+ e = mk_expr ( p, lo, hi, nd) ;
1005
+ }
1006
+
1007
+ // expr { || ... }
1008
+ token:: LBRACE . when is_bar ( p. look_ahead ( 1 u) ) && permits_call ( p) {
1009
+ p. bump ( ) ;
1010
+ let blk = parse_fn_block_expr ( p) ;
1011
+ alt e. node {
1012
+ ast:: expr_call ( f, args, false ) {
1013
+ e = @{ node: ast:: expr_call ( f, args + [ blk] , true )
1014
+ with * e} ;
1015
+ }
1016
+ _ {
1017
+ e = mk_expr ( p, lo, p. get_last_hi_pos ( ) ,
1018
+ ast:: expr_call ( e, [ blk] , true ) ) ;
1019
+ }
1000
1020
}
1001
1021
}
1022
+
1023
+ // expr[...]
1002
1024
token:: LBRACKET . {
1003
1025
p . bump ( ) ;
1004
1026
let ix = parse_expr ( p) ;
1005
1027
hi = ix. span . hi ;
1006
1028
expect ( p, token:: RBRACKET ) ;
1007
1029
e = mk_expr ( p, lo, hi, ast:: expr_index ( e, ix) ) ;
1008
1030
}
1031
+
1032
+ // expr.f
1009
1033
token:: DOT . {
1010
1034
p . bump ( ) ;
1011
1035
alt p. peek ( ) {
@@ -1022,6 +1046,7 @@ fn parse_dot_or_call_expr_with(p: parser, e: @ast::expr) -> @ast::expr {
1022
1046
t { unexpected( p, t) ; }
1023
1047
}
1024
1048
}
1049
+
1025
1050
_ { ret e; }
1026
1051
}
1027
1052
}
@@ -1126,7 +1151,7 @@ const ternary_prec: int = 0;
1126
1151
1127
1152
fn parse_more_binops ( p : parser , lhs : @ast:: expr , min_prec : int ) ->
1128
1153
@ast:: expr {
1129
- if ! expr_has_value ( lhs) { ret lhs; }
1154
+ if expr_is_complete ( p , lhs) { ret lhs; }
1130
1155
let peeked = p. peek ( ) ;
1131
1156
if peeked == token:: BINOP ( token:: OR ) &&
1132
1157
p. get_restriction ( ) == RESTRICT_NO_BAR_OP { ret lhs; }
@@ -1550,61 +1575,40 @@ fn parse_stmt(p: parser) -> @ast::stmt {
1550
1575
}
1551
1576
}
1552
1577
1553
- let maybe_item = parse_item ( p, item_attrs) ;
1554
-
1555
- // If we have attributes then we should have an item
1556
- if vec:: len ( item_attrs) > 0 u {
1557
- alt maybe_item {
1558
- some( _) { /* fallthrough */ }
1559
- _ { ret p. fatal ( "expected item" ) ; }
1560
- }
1561
- }
1562
-
1563
- alt maybe_item {
1578
+ alt parse_item( p, item_attrs) {
1564
1579
some ( i) {
1565
1580
let hi = i. span . hi ;
1566
1581
let decl = @spanned ( lo, hi, ast:: decl_item ( i) ) ;
1567
1582
ret @spanned ( lo, hi, ast:: stmt_decl ( decl, p. get_id ( ) ) ) ;
1568
1583
}
1569
- none. {
1570
- // Remainder are line-expr stmts.
1571
- let e = parse_expr ( p) ;
1572
- // See if it is a block call
1573
- if expr_has_value ( e) && p. peek ( ) == token:: LBRACE &&
1574
- is_bar ( p. look_ahead ( 1 u) ) {
1575
- p. bump ( ) ;
1576
- let blk = parse_fn_block_expr ( p) ;
1577
- alt e. node {
1578
- ast:: expr_call ( f, args, false ) {
1579
- e = @{ node: ast:: expr_call ( f, args + [ blk] , true )
1580
- with * e} ;
1581
- }
1582
- _ {
1583
- e = mk_expr ( p, lo, p. get_last_hi_pos ( ) ,
1584
- ast:: expr_call ( e, [ blk] , true ) ) ;
1585
- }
1586
- }
1587
- }
1588
- ret @spanned ( lo, e. span . hi , ast:: stmt_expr ( e, p. get_id ( ) ) ) ;
1589
- }
1590
- _ { p. fatal ( "expected statement" ) ; }
1584
+ none ( ) { /* fallthrough */ }
1591
1585
}
1586
+
1587
+ // If we have attributes then we should have an item
1588
+ if vec:: len ( item_attrs) > 0 u {
1589
+ ret p. fatal ( "expected item" ) ;
1590
+ }
1591
+
1592
+ // Remainder are line-expr stmts.
1593
+ let e = parse_expr_res ( p, RESTRICT_STMT_EXPR ) ;
1594
+ ret @spanned ( lo, e. span . hi , ast:: stmt_expr ( e, p. get_id ( ) ) ) ;
1592
1595
}
1593
1596
}
1594
1597
1595
- fn expr_has_value ( e : @ast:: expr ) -> bool {
1598
+ fn expr_is_complete ( p : parser , e : @ast:: expr ) -> bool {
1599
+ ret p. get_restriction ( ) == RESTRICT_STMT_EXPR &&
1600
+ !expr_requires_semi_to_be_stmt ( e) ;
1601
+ }
1602
+
1603
+ fn expr_requires_semi_to_be_stmt ( e : @ast:: expr ) -> bool {
1596
1604
alt e. node {
1597
1605
ast:: expr_if ( _, th, els) | ast:: expr_if_check ( _, th, els) {
1598
1606
if option:: is_none ( els) { false }
1599
1607
else { !option:: is_none ( th. node . expr ) ||
1600
- expr_has_value ( option:: get ( els) ) }
1608
+ expr_requires_semi_to_be_stmt ( option:: get ( els) ) }
1601
1609
}
1602
1610
ast:: expr_alt ( _, arms) {
1603
- let found_expr = false ;
1604
- for arm in arms {
1605
- if !option:: is_none ( arm. body . node . expr ) { found_expr = true ; }
1606
- }
1607
- found_expr
1611
+ vec:: any ( { |arm| !option:: is_none ( arm. body . node . expr ) } , arms)
1608
1612
}
1609
1613
ast:: expr_block ( blk) | ast:: expr_while ( _, blk) |
1610
1614
ast:: expr_for ( _, _, blk) | ast:: expr_do_while ( blk, _) {
@@ -1615,19 +1619,11 @@ fn expr_has_value(e: @ast::expr) -> bool {
1615
1619
}
1616
1620
}
1617
1621
1618
- fn stmt_is_expr ( stmt : @ast:: stmt ) -> bool {
1619
- ret alt stmt. node {
1620
- ast:: stmt_expr ( e, _) { expr_has_value ( e) }
1621
- _ { false }
1622
- } ;
1623
- }
1624
-
1625
1622
fn stmt_to_expr ( stmt : @ast:: stmt ) -> option:: t < @ast:: expr > {
1626
- ret if stmt_is_expr ( stmt) {
1627
- alt stmt. node {
1628
- ast:: stmt_expr ( e, _) { some ( e) }
1629
- }
1630
- } else { none } ;
1623
+ alt stmt. node {
1624
+ ast:: stmt_expr ( e, _) { some ( e) }
1625
+ ast:: stmt_decl ( _, _) { none }
1626
+ }
1631
1627
}
1632
1628
1633
1629
fn stmt_ends_with_semi ( stmt : ast:: stmt ) -> bool {
@@ -1639,7 +1635,7 @@ fn stmt_ends_with_semi(stmt: ast::stmt) -> bool {
1639
1635
}
1640
1636
}
1641
1637
ast:: stmt_expr ( e, _) {
1642
- ret expr_has_value ( e) ;
1638
+ ret expr_requires_semi_to_be_stmt ( e) ;
1643
1639
}
1644
1640
}
1645
1641
}
0 commit comments