Skip to content

Commit

Permalink
Extract LocalParser for parsing local. (#1156) (#1161)
Browse files Browse the repository at this point in the history
Extract `LocalParser` so that it is possible to parse `local`
instruction outside of a `func` and from outside the crate.
  • Loading branch information
anoopelias authored Aug 9, 2023
1 parent 3e1fb68 commit 06aa46e
Showing 1 changed file with 31 additions and 16 deletions.
47 changes: 31 additions & 16 deletions crates/wast/src/core/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,27 +92,42 @@ pub struct Local<'a> {
pub ty: ValType<'a>,
}

/// Parser for `local` instruction.
///
/// A single `local` instruction can generate multiple locals, hence this parser
pub struct LocalParser<'a> {
/// All the locals associated with this `local` instruction.
pub locals: Vec<Local<'a>>,
}

impl<'a> Parse<'a> for LocalParser<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
let mut locals = Vec::new();
parser.parse::<kw::local>()?;
if !parser.is_empty() {
let id: Option<_> = parser.parse()?;
let name: Option<_> = parser.parse()?;
let ty = parser.parse()?;
let parse_more = id.is_none() && name.is_none();
locals.push(Local { id, name, ty });
while parse_more && !parser.is_empty() {
locals.push(Local {
id: None,
name: None,
ty: parser.parse()?,
});
}
}
Ok(LocalParser { locals })
}
}

impl<'a> Local<'a> {
pub(crate) fn parse_remainder(parser: Parser<'a>) -> Result<Vec<Local<'a>>> {
let mut locals = Vec::new();
while parser.peek2::<kw::local>()? {
parser.parens(|p| {
p.parse::<kw::local>()?;
if p.is_empty() {
return Ok(());
}
let id: Option<_> = p.parse()?;
let name: Option<_> = p.parse()?;
let ty = p.parse()?;
let parse_more = id.is_none() && name.is_none();
locals.push(Local { id, name, ty });
while parse_more && !p.is_empty() {
locals.push(Local {
id: None,
name: None,
ty: p.parse()?,
});
}
locals.extend(p.parse::<LocalParser>()?.locals);
Ok(())
})?;
}
Expand Down

0 comments on commit 06aa46e

Please sign in to comment.