@@ -736,7 +736,29 @@ fn mk_lit_u32(p: parser, i: u32) -> @ast::expr {
736
736
ret @{ id : p. get_id ( ) , node : ast:: expr_lit ( lv_lit) , span : span} ;
737
737
}
738
738
739
- fn parse_bottom_expr ( p : parser ) -> @ast:: expr {
739
+ // We don't allow single-entry tuples in the true AST; that indicates a
740
+ // parenthesized expression. However, we preserve them temporarily while
741
+ // parsing because `(while{...})+3` parses differently from `while{...}+3`.
742
+ //
743
+ // To reflect the fact that the @ast::expr is not a true expr that should be
744
+ // part of the AST, we wrap such expressions in the pexpr tag. They
745
+ // can then be converted to true expressions by a call to `to_expr()`.
746
+ tag pexpr {
747
+ pexpr( @ast : : expr) ;
748
+ }
749
+
750
+ fn mk_pexpr ( p : parser , lo : uint , hi : uint , node : ast:: expr_ ) -> pexpr {
751
+ ret pexpr ( mk_expr ( p, lo, hi, node) ) ;
752
+ }
753
+
754
+ fn to_expr ( e : pexpr ) -> @ast:: expr {
755
+ alt e. node {
756
+ ast:: expr_tup ( es) when vec:: len ( es) == 1 u { es[ 0 u] }
757
+ _ { * e }
758
+ }
759
+ }
760
+
761
+ fn parse_bottom_expr ( p : parser ) -> pexpr {
740
762
let lo = p. get_lo_pos ( ) ;
741
763
let hi = p. get_hi_pos ( ) ;
742
764
@@ -747,15 +769,19 @@ fn parse_bottom_expr(p: parser) -> @ast::expr {
747
769
hi = p. get_hi_pos ( ) ;
748
770
p. bump ( ) ;
749
771
let lit = @spanned ( lo, hi, ast:: lit_nil) ;
750
- ret mk_expr ( p, lo, hi, ast:: expr_lit ( lit) ) ;
772
+ ret mk_pexpr ( p, lo, hi, ast:: expr_lit ( lit) ) ;
751
773
}
752
774
let es = [ parse_expr ( p) ] ;
753
775
while p. peek ( ) == token:: COMMA { p. bump ( ) ; es += [ parse_expr ( p) ] ; }
754
776
hi = p. get_hi_pos ( ) ;
755
777
expect ( p, token:: RPAREN ) ;
756
- if vec:: len ( es) == 1 u {
757
- ret mk_expr ( p, lo, hi, es[ 0 ] . node ) ;
758
- } else { ret mk_expr ( p, lo, hi, ast:: expr_tup ( es) ) ; }
778
+
779
+ // Note: we retain the expr_tup() even for simple
780
+ // parenthesized expressions, but only for a "little while".
781
+ // This is so that wrappers around parse_bottom_expr()
782
+ // can tell whether the expression was parenthesized or not,
783
+ // which affects expr_is_complete().
784
+ ret mk_pexpr( p, lo, hi, ast:: expr_tup ( es) ) ;
759
785
} else if p. peek ( ) == token:: LBRACE {
760
786
p. bump ( ) ;
761
787
if is_word ( p, "mutable" ) ||
@@ -775,34 +801,34 @@ fn parse_bottom_expr(p: parser) -> @ast::expr {
775
801
expect ( p, token:: RBRACE ) ;
776
802
ex = ast:: expr_rec ( fields, base) ;
777
803
} else if is_bar ( p. peek ( ) ) {
778
- ret parse_fn_block_expr ( p) ;
804
+ ret pexpr ( parse_fn_block_expr ( p) ) ;
779
805
} else {
780
806
let blk = parse_block_tail ( p, lo, ast:: default_blk) ;
781
- ret mk_expr ( p, blk. span . lo , blk. span . hi , ast:: expr_block ( blk) ) ;
807
+ ret mk_pexpr ( p, blk. span . lo , blk. span . hi , ast:: expr_block ( blk) ) ;
782
808
}
783
809
} else if eat_word ( p, "if" ) {
784
- ret parse_if_expr ( p) ;
810
+ ret pexpr ( parse_if_expr ( p) ) ;
785
811
} else if eat_word ( p, "for" ) {
786
- ret parse_for_expr ( p) ;
812
+ ret pexpr ( parse_for_expr ( p) ) ;
787
813
} else if eat_word ( p, "while" ) {
788
- ret parse_while_expr ( p) ;
814
+ ret pexpr ( parse_while_expr ( p) ) ;
789
815
} else if eat_word ( p, "do" ) {
790
- ret parse_do_while_expr ( p) ;
816
+ ret pexpr ( parse_do_while_expr ( p) ) ;
791
817
} else if eat_word ( p, "alt" ) {
792
- ret parse_alt_expr ( p) ;
818
+ ret pexpr ( parse_alt_expr ( p) ) ;
793
819
} else if eat_word ( p, "fn" ) {
794
820
let proto = parse_fn_ty_proto ( p) ;
795
- ret parse_fn_expr ( p, proto) ;
821
+ ret pexpr ( parse_fn_expr ( p, proto) ) ;
796
822
} else if eat_word ( p, "block" ) {
797
- ret parse_fn_expr ( p, ast:: proto_block) ;
823
+ ret pexpr ( parse_fn_expr ( p, ast:: proto_block) ) ;
798
824
} else if eat_word ( p, "lambda" ) {
799
- ret parse_fn_expr ( p, ast:: proto_shared ( ast:: sugar_sexy) ) ;
825
+ ret pexpr ( parse_fn_expr ( p, ast:: proto_shared ( ast:: sugar_sexy) ) ) ;
800
826
} else if eat_word ( p, "sendfn" ) {
801
- ret parse_fn_expr ( p, ast:: proto_send) ;
827
+ ret pexpr ( parse_fn_expr ( p, ast:: proto_send) ) ;
802
828
} else if eat_word ( p, "unchecked" ) {
803
- ret parse_block_expr ( p, lo, ast:: unchecked_blk) ;
829
+ ret pexpr ( parse_block_expr ( p, lo, ast:: unchecked_blk) ) ;
804
830
} else if eat_word ( p, "unsafe" ) {
805
- ret parse_block_expr ( p, lo, ast:: unsafe_blk) ;
831
+ ret pexpr ( parse_block_expr ( p, lo, ast:: unsafe_blk) ) ;
806
832
} else if p. peek ( ) == token:: LBRACKET {
807
833
p. bump ( ) ;
808
834
let mut = parse_mutability( p) ;
@@ -816,15 +842,16 @@ fn parse_bottom_expr(p: parser) -> @ast::expr {
816
842
expect ( p, token:: GT ) ;
817
843
818
844
/* hack: early return to take advantage of specialized function */
819
- ret mk_mac_expr ( p, lo, p. get_hi_pos ( ) , ast:: mac_embed_type ( ty) ) ;
845
+ ret pexpr( mk_mac_expr ( p, lo, p. get_hi_pos ( ) ,
846
+ ast:: mac_embed_type ( ty) ) ) ;
820
847
} else if p. peek ( ) == token:: POUND_LBRACE {
821
848
p. bump ( ) ;
822
849
let blk = ast:: mac_embed_block (
823
850
parse_block_tail ( p, lo, ast:: default_blk) ) ;
824
- ret mk_mac_expr ( p, lo, p. get_hi_pos ( ) , blk) ;
851
+ ret pexpr ( mk_mac_expr ( p, lo, p. get_hi_pos ( ) , blk) ) ;
825
852
} else if p. peek ( ) == token:: ELLIPSIS {
826
853
p. bump ( ) ;
827
- ret mk_mac_expr ( p, lo, p. get_hi_pos ( ) , ast:: mac_ellipsis) ;
854
+ ret pexpr ( mk_mac_expr ( p, lo, p. get_hi_pos ( ) , ast:: mac_ellipsis) ) ;
828
855
} else if eat_word ( p, "obj" ) {
829
856
// Anonymous object
830
857
@@ -941,7 +968,7 @@ fn parse_bottom_expr(p: parser) -> @ast::expr {
941
968
hi = lit. span . hi ;
942
969
ex = ast:: expr_lit ( @lit) ;
943
970
}
944
- ret mk_expr ( p, lo, hi, ex) ;
971
+ ret mk_pexpr ( p, lo, hi, ex) ;
945
972
}
946
973
947
974
fn parse_block_expr ( p : parser ,
@@ -977,7 +1004,7 @@ fn parse_syntax_ext_naked(p: parser, lo: uint) -> @ast::expr {
977
1004
ret mk_mac_expr ( p, lo, hi, ast:: mac_invoc ( pth, e, none) ) ;
978
1005
}
979
1006
980
- fn parse_dot_or_call_expr ( p : parser ) -> @ast :: expr {
1007
+ fn parse_dot_or_call_expr ( p : parser ) -> pexpr {
981
1008
let b = parse_bottom_expr ( p) ;
982
1009
parse_dot_or_call_expr_with ( p, b)
983
1010
}
@@ -986,33 +1013,33 @@ fn permits_call(p: parser) -> bool {
986
1013
ret p. get_restriction ( ) != RESTRICT_NO_CALL_EXPRS ;
987
1014
}
988
1015
989
- fn parse_dot_or_call_expr_with ( p : parser , e : @ast:: expr ) -> @ast:: expr {
1016
+ fn parse_dot_or_call_expr_with ( p : parser , e0 : pexpr ) -> pexpr {
1017
+ let e = e0;
990
1018
let lo = e. span . lo ;
991
1019
let hi = e. span . hi ;
992
- let e = e;
993
1020
while !expr_is_complete ( p, e) {
994
1021
alt p. peek ( ) {
995
1022
// expr(...)
996
1023
token:: LPAREN . when permits_call ( p) {
997
1024
let es = parse_seq ( token:: LPAREN , token:: RPAREN ,
998
1025
seq_sep ( token:: COMMA ) , parse_expr, p) ;
999
1026
hi = es. span . hi ;
1000
- let nd = ast:: expr_call ( e , es. node , false ) ;
1001
- e = mk_expr ( p, lo, hi, nd) ;
1027
+ let nd = ast:: expr_call ( to_expr ( e ) , es. node , false ) ;
1028
+ e = mk_pexpr ( p, lo, hi, nd) ;
1002
1029
}
1003
1030
1004
- // expr { || ... }
1031
+ // expr {|| ... }
1005
1032
token:: LBRACE . when is_bar ( p. look_ahead ( 1 u) ) && permits_call ( p) {
1006
1033
p. bump ( ) ;
1007
1034
let blk = parse_fn_block_expr ( p) ;
1008
1035
alt e. node {
1009
1036
ast:: expr_call ( f, args, false ) {
1010
- e = @{ node: ast:: expr_call ( f, args + [ blk] , true )
1011
- with * e } ;
1037
+ e = pexpr ( @{ node: ast:: expr_call ( f, args + [ blk] , true )
1038
+ with * to_expr ( e ) } ) ;
1012
1039
}
1013
1040
_ {
1014
- e = mk_expr ( p, lo, p. get_last_hi_pos ( ) ,
1015
- ast:: expr_call ( e , [ blk] , true ) ) ;
1041
+ e = mk_pexpr ( p, lo, p. get_last_hi_pos ( ) ,
1042
+ ast:: expr_call ( to_expr ( e ) , [ blk] , true ) ) ;
1016
1043
}
1017
1044
}
1018
1045
}
@@ -1023,7 +1050,7 @@ fn parse_dot_or_call_expr_with(p: parser, e: @ast::expr) -> @ast::expr {
1023
1050
let ix = parse_expr ( p) ;
1024
1051
hi = ix. span . hi ;
1025
1052
expect ( p, token:: RBRACKET ) ;
1026
- e = mk_expr ( p, lo, hi, ast:: expr_index ( e , ix) ) ;
1053
+ e = mk_pexpr ( p, lo, hi, ast:: expr_index ( to_expr ( e ) , ix) ) ;
1027
1054
}
1028
1055
1029
1056
// expr.f
@@ -1038,7 +1065,10 @@ fn parse_dot_or_call_expr_with(p: parser, e: @ast::expr) -> @ast::expr {
1038
1065
parse_seq_to_gt ( some ( token:: COMMA ) ,
1039
1066
{ |p| parse_ty ( p, false ) } , p)
1040
1067
} else { [ ] } ;
1041
- e = mk_expr ( p, lo, hi, ast:: expr_field ( e, p. get_str ( i) , tys) ) ;
1068
+ e = mk_pexpr ( p, lo, hi,
1069
+ ast:: expr_field ( to_expr ( e) ,
1070
+ p. get_str ( i) ,
1071
+ tys) ) ;
1042
1072
}
1043
1073
t { unexpected( p, t) ; }
1044
1074
}
@@ -1050,29 +1080,29 @@ fn parse_dot_or_call_expr_with(p: parser, e: @ast::expr) -> @ast::expr {
1050
1080
ret e;
1051
1081
}
1052
1082
1053
- fn parse_prefix_expr ( p : parser ) -> @ast :: expr {
1083
+ fn parse_prefix_expr ( p : parser ) -> pexpr {
1054
1084
let lo = p. get_lo_pos ( ) ;
1055
1085
let hi = p. get_hi_pos ( ) ;
1056
1086
1057
1087
let ex;
1058
1088
alt p. peek ( ) {
1059
1089
token:: NOT . {
1060
1090
p . bump ( ) ;
1061
- let e = parse_prefix_expr ( p) ;
1091
+ let e = to_expr ( parse_prefix_expr ( p) ) ;
1062
1092
hi = e. span . hi ;
1063
1093
ex = ast:: expr_unary ( ast:: not, e) ;
1064
1094
}
1065
1095
token:: BINOP ( b) {
1066
1096
alt b {
1067
1097
token : : MINUS . {
1068
1098
p. bump ( ) ;
1069
- let e = parse_prefix_expr ( p) ;
1099
+ let e = to_expr ( parse_prefix_expr ( p) ) ;
1070
1100
hi = e. span . hi ;
1071
1101
ex = ast:: expr_unary ( ast:: neg, e) ;
1072
1102
}
1073
1103
token:: STAR . {
1074
1104
p. bump ( ) ;
1075
- let e = parse_prefix_expr ( p) ;
1105
+ let e = to_expr ( parse_prefix_expr ( p) ) ;
1076
1106
hi = e. span . hi ;
1077
1107
ex = ast:: expr_unary ( ast:: deref, e) ;
1078
1108
}
@@ -1082,20 +1112,20 @@ fn parse_prefix_expr(p: parser) -> @ast::expr {
1082
1112
token:: AT . {
1083
1113
p . bump ( ) ;
1084
1114
let m = parse_mutability ( p) ;
1085
- let e = parse_prefix_expr ( p) ;
1115
+ let e = to_expr ( parse_prefix_expr ( p) ) ;
1086
1116
hi = e. span . hi ;
1087
1117
ex = ast:: expr_unary ( ast:: box ( m) , e) ;
1088
1118
}
1089
1119
token:: TILDE . {
1090
1120
p . bump ( ) ;
1091
1121
let m = parse_mutability ( p) ;
1092
- let e = parse_prefix_expr ( p) ;
1122
+ let e = to_expr ( parse_prefix_expr ( p) ) ;
1093
1123
hi = e. span . hi ;
1094
1124
ex = ast:: expr_unary ( ast:: uniq ( m) , e) ;
1095
1125
}
1096
1126
_ { ret parse_dot_or_call_expr ( p) ; }
1097
1127
}
1098
- ret mk_expr ( p, lo, hi, ex) ;
1128
+ ret mk_pexpr ( p, lo, hi, ex) ;
1099
1129
}
1100
1130
1101
1131
fn parse_ternary ( p : parser ) -> @ast:: expr {
@@ -1146,9 +1176,10 @@ const unop_prec: int = 100;
1146
1176
const as_prec: int = 5 ;
1147
1177
const ternary_prec: int = 0 ;
1148
1178
1149
- fn parse_more_binops ( p : parser , lhs : @ast :: expr , min_prec : int ) ->
1179
+ fn parse_more_binops ( p : parser , plhs : pexpr , min_prec : int ) ->
1150
1180
@ast:: expr {
1151
- if expr_is_complete ( p, lhs) { ret lhs; }
1181
+ let lhs = to_expr ( plhs) ;
1182
+ if expr_is_complete ( p, plhs) { ret lhs; }
1152
1183
let peeked = p. peek ( ) ;
1153
1184
if peeked == token:: BINOP ( token:: OR ) &&
1154
1185
p. get_restriction ( ) == RESTRICT_NO_BAR_OP { ret lhs; }
@@ -1157,15 +1188,15 @@ fn parse_more_binops(p: parser, lhs: @ast::expr, min_prec: int) ->
1157
1188
p. bump ( ) ;
1158
1189
let expr = parse_prefix_expr ( p) ;
1159
1190
let rhs = parse_more_binops ( p, expr, cur. prec ) ;
1160
- let bin = mk_expr ( p, lhs. span . lo , rhs. span . hi ,
1191
+ let bin = mk_pexpr ( p, lhs. span . lo , rhs. span . hi ,
1161
1192
ast:: expr_binary ( cur. op , lhs, rhs) ) ;
1162
1193
ret parse_more_binops ( p, bin, min_prec) ;
1163
1194
}
1164
1195
}
1165
1196
if as_prec > min_prec && eat_word ( p, "as" ) {
1166
1197
let rhs = parse_ty ( p, true ) ;
1167
1198
let _as =
1168
- mk_expr ( p, lhs. span . lo , rhs. span . hi , ast:: expr_cast ( lhs, rhs) ) ;
1199
+ mk_pexpr ( p, lhs. span . lo , rhs. span . hi , ast:: expr_cast ( lhs, rhs) ) ;
1169
1200
ret parse_more_binops ( p, _as, min_prec) ;
1170
1201
}
1171
1202
ret lhs;
@@ -1587,12 +1618,12 @@ fn parse_stmt(p: parser) -> @ast::stmt {
1587
1618
}
1588
1619
}
1589
1620
1590
- fn expr_is_complete ( p : parser , e : @ast :: expr ) -> bool {
1621
+ fn expr_is_complete ( p : parser , e : pexpr ) -> bool {
1591
1622
log ( debug, ( "expr_is_complete" , p. get_restriction ( ) ,
1592
- print:: pprust:: expr_to_str ( e) ,
1593
- expr_requires_semi_to_be_stmt ( e) ) ) ;
1623
+ print:: pprust:: expr_to_str ( * e) ,
1624
+ expr_requires_semi_to_be_stmt ( * e) ) ) ;
1594
1625
ret p. get_restriction ( ) == RESTRICT_STMT_EXPR &&
1595
- !expr_requires_semi_to_be_stmt ( e) ;
1626
+ !expr_requires_semi_to_be_stmt ( * e) ;
1596
1627
}
1597
1628
1598
1629
fn expr_requires_semi_to_be_stmt ( e : @ast:: expr ) -> bool {
0 commit comments