1use crate::ast::{self, kw};
2use wast::parser::{Parse, Parser, Result};
3
4pub struct Func<'a> {
6 pub span: wast::Span,
8 pub name: Option<wast::Id<'a>>,
10 pub export: Option<&'a str>,
12 pub ty: ast::TypeUse<'a>,
14 pub kind: FuncKind<'a>,
16}
17
18pub enum FuncKind<'a> {
20 Import {
22 module: &'a str,
24 name: &'a str,
26 },
27
28 #[allow(missing_docs)]
30 Inline { instrs: ast::Instructions<'a> },
31}
32
33impl<'a> Parse<'a> for Func<'a> {
34 fn parse(parser: Parser<'a>) -> Result<Func<'a>> {
35 let span = parser.parse::<kw::func>()?.0;
36 let name = parser.parse()?;
37 let export = if parser.peek2::<kw::export>() {
38 Some(parser.parens(|p| {
39 p.parse::<kw::export>()?;
40 p.parse()
41 })?)
42 } else {
43 None
44 };
45
46 let (ty, kind) = if parser.peek2::<kw::import>() {
47 let (module, name) = parser.parens(|p| {
48 p.parse::<kw::import>()?;
49 Ok((p.parse()?, p.parse()?))
50 })?;
51 (parser.parse()?, FuncKind::Import { module, name })
52 } else {
53 let ty = parser.parse()?;
54 let instrs = parser.parse()?;
55 (ty, FuncKind::Inline { instrs })
56 };
57
58 Ok(Func {
59 span,
60 name,
61 export,
62 ty,
63 kind,
64 })
65 }
66}
67
68#[allow(missing_docs)]
70pub struct Instructions<'a> {
71 pub instrs: Vec<ast::Instruction<'a>>,
72}
73
74impl<'a> Parse<'a> for Instructions<'a> {
75 fn parse(parser: Parser<'a>) -> Result<Instructions<'a>> {
76 let mut instrs = Vec::new();
77 while !parser.is_empty() {
78 instrs.push(parser.parse()?);
79 }
80 Ok(Instructions { instrs })
81 }
82}