wit_text/ast/
implement.rs

1use crate::ast::{self, kw};
2use wast::parser::{Parse, Parser, Result};
3
4/// A means of implementing a core wasm imported function with an adapter
5/// function.
6pub struct Implement<'a> {
7    /// Where this directive was defined
8    pub span: wast::Span,
9    /// What's being implemented
10    pub implemented: Implemented<'a>,
11    /// How it's being implemented
12    pub implementation: Implementation<'a>,
13}
14
15/// Different ways to specify what's being implemented
16pub enum Implemented<'a> {
17    /// A specification of what's being impelmented by module/name
18    #[allow(missing_docs)]
19    ByName { module: &'a str, name: &'a str },
20
21    /// A specification using an index
22    ByIndex(wast::Index<'a>),
23}
24
25/// Different ways to specify an implementation
26pub enum Implementation<'a> {
27    /// A specification using an index
28    ByIndex(wast::Index<'a>),
29
30    /// An inline definition of what's being implemented
31    Inline {
32        /// The type that this function has
33        ty: ast::TypeUse<'a>,
34        /// Body of the implementation
35        instrs: ast::Instructions<'a>,
36    },
37}
38
39impl<'a> Parse<'a> for Implement<'a> {
40    fn parse(parser: Parser<'a>) -> Result<Implement<'a>> {
41        let span = parser.parse::<kw::implement>()?.0;
42
43        let implemented = parser.parens(|parser| {
44            if parser.peek::<kw::func>() {
45                parser.parse::<kw::func>()?;
46                Ok(Implemented::ByIndex(parser.parse()?))
47            } else {
48                parser.parse::<kw::import>()?;
49                Ok(Implemented::ByName {
50                    module: parser.parse()?,
51                    name: parser.parse()?,
52                })
53            }
54        })?;
55
56        let implementation = if parser.peek2::<kw::func>() {
57            parser.parens(|parser| {
58                parser.parse::<kw::func>()?;
59                Ok(Implementation::ByIndex(parser.parse()?))
60            })?
61        } else {
62            Implementation::Inline {
63                ty: parser.parse()?,
64                instrs: parser.parse()?,
65            }
66        };
67
68        Ok(Implement {
69            span,
70            implemented,
71            implementation,
72        })
73    }
74}