@@ -92,27 +92,42 @@ pub struct Local<'a> {
9292 pub ty : ValType < ' a > ,
9393}
9494
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+
95125impl < ' a > Local < ' a > {
96126 pub ( crate ) fn parse_remainder ( parser : Parser < ' a > ) -> Result < Vec < Local < ' a > > > {
97127 let mut locals = Vec :: new ( ) ;
98128 while parser. peek2 :: < kw:: local > ( ) ? {
99129 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 ) ;
116131 Ok ( ( ) )
117132 } ) ?;
118133 }
0 commit comments