use crate::ast::{self, kw};
use wast::parser::{Parse, Parser, Result};
pub struct Implement<'a> {
pub span: wast::Span,
pub implemented: Implemented<'a>,
pub implementation: Implementation<'a>,
}
pub enum Implemented<'a> {
#[allow(missing_docs)]
ByName { module: &'a str, name: &'a str },
ByIndex(wast::Index<'a>),
}
pub enum Implementation<'a> {
ByIndex(wast::Index<'a>),
Inline {
ty: ast::TypeUse<'a>,
instrs: ast::Instructions<'a>,
},
}
impl<'a> Parse<'a> for Implement<'a> {
fn parse(parser: Parser<'a>) -> Result<Implement<'a>> {
let span = parser.parse::<kw::implement>()?.0;
let implemented = parser.parens(|parser| {
if parser.peek::<kw::func>() {
parser.parse::<kw::func>()?;
Ok(Implemented::ByIndex(parser.parse()?))
} else {
parser.parse::<kw::import>()?;
Ok(Implemented::ByName {
module: parser.parse()?,
name: parser.parse()?,
})
}
})?;
let implementation = if parser.peek2::<kw::func>() {
parser.parens(|parser| {
parser.parse::<kw::func>()?;
Ok(Implementation::ByIndex(parser.parse()?))
})?
} else {
Implementation::Inline {
ty: parser.parse()?,
instrs: parser.parse()?,
}
};
Ok(Implement {
span,
implemented,
implementation,
})
}
}