@@ -92,27 +92,42 @@ pub struct Local<'a> {
92
92
pub ty : ValType < ' a > ,
93
93
}
94
94
95
+ /// Parser for `local` instruction.
96
+ ///
97
+ /// A single `local` instruction can generate multiple locals, hence this parser
98
+ pub struct LocalParser < ' a > {
99
+ /// All the locals associated with this `local` instruction.
100
+ pub locals : Vec < Local < ' a > > ,
101
+ }
102
+
103
+ impl < ' a > Parse < ' a > for LocalParser < ' a > {
104
+ fn parse ( parser : Parser < ' a > ) -> Result < Self > {
105
+ let mut locals = Vec :: new ( ) ;
106
+ parser. parse :: < kw:: local > ( ) ?;
107
+ if !parser. is_empty ( ) {
108
+ let id: Option < _ > = parser. parse ( ) ?;
109
+ let name: Option < _ > = parser. parse ( ) ?;
110
+ let ty = parser. parse ( ) ?;
111
+ let parse_more = id. is_none ( ) && name. is_none ( ) ;
112
+ locals. push ( Local { id, name, ty } ) ;
113
+ while parse_more && !parser. is_empty ( ) {
114
+ locals. push ( Local {
115
+ id : None ,
116
+ name : None ,
117
+ ty : parser. parse ( ) ?,
118
+ } ) ;
119
+ }
120
+ }
121
+ Ok ( LocalParser { locals } )
122
+ }
123
+ }
124
+
95
125
impl < ' a > Local < ' a > {
96
126
pub ( crate ) fn parse_remainder ( parser : Parser < ' a > ) -> Result < Vec < Local < ' a > > > {
97
127
let mut locals = Vec :: new ( ) ;
98
128
while parser. peek2 :: < kw:: local > ( ) ? {
99
129
parser. parens ( |p| {
100
- p. parse :: < kw:: local > ( ) ?;
101
- if p. is_empty ( ) {
102
- return Ok ( ( ) ) ;
103
- }
104
- let id: Option < _ > = p. parse ( ) ?;
105
- let name: Option < _ > = p. parse ( ) ?;
106
- let ty = p. parse ( ) ?;
107
- let parse_more = id. is_none ( ) && name. is_none ( ) ;
108
- locals. push ( Local { id, name, ty } ) ;
109
- while parse_more && !p. is_empty ( ) {
110
- locals. push ( Local {
111
- id : None ,
112
- name : None ,
113
- ty : p. parse ( ) ?,
114
- } ) ;
115
- }
130
+ locals. extend ( p. parse :: < LocalParser > ( ) ?. locals ) ;
116
131
Ok ( ( ) )
117
132
} ) ?;
118
133
}
0 commit comments