@@ -902,7 +902,7 @@ impl<Pat: RustInputPat> RuleWithFieldsGenerateMethods<Pat> for RuleWithFields {
902
902
. collect :: < Vec < _ > > ( ) ;
903
903
let cases_node_kind = cases. iter ( ) . map ( |rule| rule. node_kind ( cx, rules) ) ;
904
904
let cases_node_kind_src = cases_node_kind. map ( |kind| kind. to_src ( ) ) ;
905
- quote ! ( { _P; #( #cases_node_kind_src => #cases_shape, ) * } )
905
+ quote ! ( { _P; _ @ #( #cases_node_kind_src => #cases_shape, ) * } )
906
906
}
907
907
Rule :: Opt ( rule) => {
908
908
let shape = child ( rule, 0 ) . generate_traverse_shape ( cx, rules, rust_fields) ;
@@ -1026,11 +1026,16 @@ where
1026
1026
} ;
1027
1027
rule_ty_def
1028
1028
+ rule_debug_impls ( cx, name, & rust_adt)
1029
- + impl_rule_from_forest ( name, & rust_adt, cx)
1029
+ + impl_rule_from_forest ( name, & rust_adt, cx, rules )
1030
1030
+ impl_rule_one_and_all ( name, rule, & rust_adt, cx, rules)
1031
1031
}
1032
1032
1033
- fn impl_rule_from_forest < Pat > ( name : IStr , rust_adt : & RustAdt , cx : & Context < Pat > ) -> Src
1033
+ fn impl_rule_from_forest < Pat > (
1034
+ name : IStr ,
1035
+ rust_adt : & RustAdt ,
1036
+ cx : & Context < Pat > ,
1037
+ rules : & mut RuleMap < ' _ > ,
1038
+ ) -> Src
1034
1039
where
1035
1040
Pat : RustInputPat ,
1036
1041
{
@@ -1051,20 +1056,30 @@ where
1051
1056
}
1052
1057
} ;
1053
1058
1054
- let methods = match rust_adt {
1059
+ let method = match rust_adt {
1055
1060
RustAdt :: Enum ( variants) => {
1056
- let variants_fields_len = variants. values ( ) . map ( |( _, variant) | match variant {
1057
- RustVariant :: Newtype ( _) => 0 ,
1058
- RustVariant :: StructLike ( v_fields) => v_fields. len ( ) ,
1059
- } ) ;
1060
- let variants_from_forest_ident = variants
1061
- . keys ( )
1062
- . map ( |& v_name| Src :: ident ( format ! ( "{}_from_forest" , & cx[ v_name] ) ) ) ;
1063
- let variants_body = variants. iter ( ) . map ( |( & v_name, ( _, variant) ) | {
1061
+ let max_fields_len = variants
1062
+ . values ( )
1063
+ . map ( |( _, variant) | match variant {
1064
+ RustVariant :: Newtype ( _) => 0 ,
1065
+ RustVariant :: StructLike ( v_fields) => v_fields. len ( ) ,
1066
+ } )
1067
+ . max ( )
1068
+ . unwrap_or ( 0 ) ;
1069
+ // HACK(eddyb) only collected to a `Vec` to avoid `rules` borrow conflicts.
1070
+ let variants_kind = variants
1071
+ . values ( )
1072
+ . map ( |( v_rule, _) | v_rule. rule . node_kind ( cx, rules) )
1073
+ . collect :: < Vec < _ > > ( ) ;
1074
+ let variants_kind_src = variants_kind
1075
+ . iter ( )
1076
+ . map ( |kind| kind. to_src ( ) )
1077
+ . collect :: < Vec < _ > > ( ) ;
1078
+ let variants_expr = variants. iter ( ) . map ( |( & v_name, ( _, variant) ) | {
1064
1079
let variant_ident = Src :: ident ( & cx[ v_name] ) ;
1065
1080
match variant {
1066
1081
RustVariant :: Newtype ( _) => quote ! ( #ident:: #variant_ident( Handle {
1067
- node: _node ,
1082
+ node: _r [ #max_fields_len ] . unwrap ( ) ,
1068
1083
forest,
1069
1084
_marker: PhantomData ,
1070
1085
} ) ) ,
@@ -1078,16 +1093,17 @@ where
1078
1093
}
1079
1094
} ) ;
1080
1095
1081
- quote ! ( #(
1082
- #[ allow( non_snake_case) ]
1083
- fn #variants_from_forest_ident(
1084
- forest: & ' a gll:: grammer:: forest:: ParseForest <' i, _G, I >,
1085
- _node: Node <' i, _G>,
1086
- _r: [ Option <Node <' i, _G>>; #variants_fields_len] ,
1087
- ) -> Self {
1088
- #variants_body
1089
- }
1090
- ) * )
1096
+ quote ! (
1097
+ fn from_forest(
1098
+ forest: & ' a gll:: grammer:: forest:: ParseForest <' i, _G, I >,
1099
+ _r: [ Option <Node <' i, _G>>; #max_fields_len + 1 ] ,
1100
+ ) -> Self {
1101
+ match _r[ #max_fields_len] . unwrap( ) . kind {
1102
+ #( #variants_kind_src => #variants_expr, ) *
1103
+ _ => unreachable!( ) ,
1104
+ }
1105
+ }
1106
+ )
1091
1107
}
1092
1108
RustAdt :: Struct ( fields) => {
1093
1109
let fields_len = fields. len ( ) ;
@@ -1101,7 +1117,6 @@ where
1101
1117
quote ! (
1102
1118
fn from_forest(
1103
1119
forest: & ' a gll:: grammer:: forest:: ParseForest <' i, _G, I >,
1104
- _node: Node <' i, _G>,
1105
1120
_r: [ Option <Node <' i, _G>>; #fields_len] ,
1106
1121
) -> Self {
1107
1122
#ident {
@@ -1114,7 +1129,7 @@ where
1114
1129
} ;
1115
1130
1116
1131
quote ! ( impl <' a, ' i, I : gll:: grammer:: input:: Input > #ident<' a, ' i, I > {
1117
- #methods
1132
+ #method
1118
1133
} )
1119
1134
}
1120
1135
@@ -1129,21 +1144,17 @@ where
1129
1144
Pat : RustInputPat ,
1130
1145
{
1131
1146
let ident = Src :: ident ( & cx[ name] ) ;
1132
- let ( consts , one , all ) = match rust_adt {
1147
+ let ( total_fields , shape ) = match rust_adt {
1133
1148
RustAdt :: Enum ( variants) => {
1134
- let variants_fields_len = variants. values ( ) . map ( |( _, variant) | match variant {
1135
- RustVariant :: Newtype ( _) => 0 ,
1136
- RustVariant :: StructLike ( v_fields) => v_fields. len ( ) ,
1137
- } ) ;
1138
- // FIXME(eddyb) figure out a more efficient way to reuse
1139
- // iterators with `quote!(...)` than `.collect::<Vec<_>>()`.
1140
- let i_ident = ( 0 ..variants. len ( ) )
1141
- . map ( |i| Src :: ident ( format ! ( "_{}" , i) ) )
1142
- . collect :: < Vec < _ > > ( ) ;
1143
- let variants_from_forest_ident = variants
1144
- . keys ( )
1145
- . map ( |& v_name| Src :: ident ( format ! ( "{}_from_forest" , & cx[ v_name] ) ) )
1146
- . collect :: < Vec < _ > > ( ) ;
1149
+ let max_fields_len = variants
1150
+ . values ( )
1151
+ . map ( |( _, variant) | match variant {
1152
+ RustVariant :: Newtype ( _) => 0 ,
1153
+ RustVariant :: StructLike ( v_fields) => v_fields. len ( ) ,
1154
+ } )
1155
+ . max ( )
1156
+ . unwrap_or ( 0 ) ;
1157
+ // HACK(eddyb) only collected to a `Vec` to avoid `rules` borrow conflicts.
1147
1158
let variants_kind = variants
1148
1159
. values ( )
1149
1160
. map ( |( v_rule, _) | v_rule. rule . node_kind ( cx, rules) )
@@ -1152,10 +1163,6 @@ where
1152
1163
. iter ( )
1153
1164
. map ( |kind| kind. to_src ( ) )
1154
1165
. collect :: < Vec < _ > > ( ) ;
1155
- let variants_shape_ident = variants
1156
- . keys ( )
1157
- . map ( |& v_name| Src :: ident ( format ! ( "{}_SHAPE" , & cx[ v_name] ) ) )
1158
- . collect :: < Vec < _ > > ( ) ;
1159
1166
let variants_shape = variants
1160
1167
. values ( )
1161
1168
. map ( |( v_rule, variant) | match variant {
@@ -1167,100 +1174,51 @@ where
1167
1174
. collect :: < Vec < _ > > ( ) ;
1168
1175
1169
1176
(
1170
- quote ! ( #(
1171
- #[ allow( non_upper_case_globals) ]
1172
- const #variants_shape_ident: traverse:: ty!( #variants_shape) = traverse:: new!( #variants_shape) ;
1173
- ) * ) ,
1174
- quote ! (
1175
- forest. one_choice( node) . and_then( |node| match node. kind {
1176
- #( #variants_kind_src => {
1177
- let mut r = [ None ; #variants_fields_len] ;
1178
- #ident:: <I >:: #variants_shape_ident
1179
- . one( forest, node, & mut r)
1180
- . map( |( ) | {
1181
- #ident:: #variants_from_forest_ident( self . forest, node, r)
1182
- } )
1183
- } ) *
1184
- _ => unreachable!( )
1185
- } )
1186
- ) ,
1187
- quote ! (
1188
- #[ derive( Clone ) ]
1189
- enum Iter <#( #i_ident) , * > {
1190
- #( #i_ident( #i_ident) ) , *
1191
- }
1192
- impl <T #( , #i_ident: Iterator <Item = T >) * > Iterator for Iter <#( #i_ident) , * >
1193
- {
1194
- type Item = T ;
1195
- fn next( & mut self ) -> Option <T > {
1196
- match self {
1197
- #( Iter :: #i_ident( iter) => iter. next( ) ) , *
1198
- }
1199
- }
1200
- }
1201
-
1202
- forest. all_choices( node) . flat_map( move |node| {
1203
- match node. kind {
1204
- #( #variants_kind_src => Iter :: #i_ident( {
1205
- #ident:: <I >:: #variants_shape_ident
1206
- . all( forest, node)
1207
- . into_iter( )
1208
- . map( move |r| {
1209
- #ident:: #variants_from_forest_ident( self . forest, node, r)
1210
- } )
1211
- } ) , ) *
1212
- _ => unreachable!( ) ,
1213
- }
1214
- } )
1215
- ) ,
1216
- )
1217
- }
1218
- RustAdt :: Struct ( fields) => {
1219
- let fields_len = fields. len ( ) ;
1220
- let shape = rule. generate_traverse_shape ( cx, rules, fields) ;
1221
- (
1222
- quote ! (
1223
- #[ allow( non_upper_case_globals) ]
1224
- const SHAPE : traverse:: ty!( #shape) = traverse:: new!( #shape) ;
1225
- ) ,
1226
- quote ! (
1227
- let mut r = [ None ; #fields_len] ;
1228
- #ident:: <I >:: SHAPE
1229
- . one( forest, node, & mut r)
1230
- . map( |( ) | #ident:: from_forest( self . forest, node, r) )
1231
- ) ,
1232
- quote ! (
1233
- #ident:: <I >:: SHAPE
1234
- . all( forest, node)
1235
- . into_iter( )
1236
- . map( move |r| {
1237
- #ident:: from_forest( self . forest, node, r)
1238
- } )
1239
- ) ,
1177
+ max_fields_len + 1 ,
1178
+ quote ! ( { _P; #max_fields_len @ #( #variants_kind_src => #variants_shape, ) * } ) ,
1240
1179
)
1241
1180
}
1181
+ RustAdt :: Struct ( fields) => (
1182
+ fields. len ( ) ,
1183
+ rule. generate_traverse_shape ( cx, rules, fields) ,
1184
+ ) ,
1242
1185
} ;
1243
1186
1244
1187
quote ! (
1245
1188
impl <' a, ' i, I : gll:: grammer:: input:: Input > #ident<' a, ' i, I > {
1246
- #consts
1189
+ const SHAPE : traverse :: ty! ( #shape ) = traverse :: new! ( #shape ) ;
1247
1190
}
1248
1191
1249
1192
impl <' a, ' i, I > Handle <' a, ' i, I , #ident<' a, ' i, I >>
1250
1193
where I : gll:: grammer:: input:: Input ,
1251
1194
{
1252
- #consts
1253
-
1254
1195
pub fn one( self ) -> Result <#ident<' a, ' i, I >, Ambiguity <Self >> {
1255
1196
let forest = self . forest;
1256
1197
let node = forest. unpack_alias( self . node) ;
1257
- #one. map_err( |gll:: grammer:: forest:: MoreThanOne | Ambiguity ( self ) )
1198
+
1199
+ let mut r = [ None ; #total_fields] ;
1200
+ #ident:: <I >:: SHAPE
1201
+ . one( forest, node, & mut r)
1202
+ . map_err( |gll:: grammer:: forest:: MoreThanOne | Ambiguity ( self ) ) ?;
1203
+
1204
+ Ok ( #ident:: from_forest( forest, r) )
1258
1205
}
1259
1206
1260
- pub fn all( self ) -> impl Iterator <Item = #ident<' a, ' i, I >> {
1207
+ pub fn all( self ) -> :: std:: iter:: Map <
1208
+ cursor:: IntoIter <
1209
+ <traverse:: ty!( #shape) as traverse:: Shape <' a, ' i, _G>>:: All ,
1210
+ [ Option <Node <' i, _G>>; #total_fields] ,
1211
+ [ Option <Node <' i, _G>>] ,
1212
+ >,
1213
+ impl FnMut ( [ Option <Node <' i, _G>>; #total_fields] ) -> #ident<' a, ' i, I >,
1214
+ > {
1261
1215
let forest = self . forest;
1262
1216
let node = forest. unpack_alias( self . node) ;
1263
- #all
1217
+
1218
+ #ident:: <I >:: SHAPE
1219
+ . all( forest, node)
1220
+ . into_iter( )
1221
+ . map( move |r| #ident:: from_forest( forest, r) )
1264
1222
}
1265
1223
}
1266
1224
)
0 commit comments