1use crate::ast::{self, annotation, kw};
2use wast::parser::{Parse, Parser, Result};
3
4pub struct Wat<'a> {
8 pub module: Module<'a>,
10}
11
12impl<'a> Parse<'a> for Wat<'a> {
13 fn parse(parser: Parser<'a>) -> Result<Self> {
14 let module = if !parser.peek2::<kw::module>() {
15 parse_text_module(parser.cur_span(), None, None, parser)?
16 } else {
17 parser.parens(|parser| parser.parse())?
18 };
19 Ok(Wat { module })
20 }
21}
22
23pub struct Module<'a> {
25 pub core: wast::Module<'a>,
27 pub adapters: Vec<Adapter<'a>>,
30}
31
32impl Module<'_> {
33 pub fn encode(&mut self) -> std::result::Result<Vec<u8>, wast::Error> {
35 let names = self.core.resolve()?;
36 let core = match &self.core.kind {
37 wast::ModuleKind::Text(list) => &list[..],
38 wast::ModuleKind::Binary(_) => &[],
39 };
40 crate::resolve::resolve(core, &mut self.adapters, &names)?;
41 let mut core = self.core.encode()?;
42 crate::binary::append(&self.adapters, &mut core);
43 Ok(core)
44 }
45}
46
47impl<'a> Parse<'a> for Module<'a> {
48 fn parse(parser: Parser<'a>) -> Result<Module<'a>> {
49 if parser.peek2::<kw::binary>() {
52 return Ok(Module {
53 core: parser.parse()?,
54 adapters: Vec::new(),
55 });
56 }
57
58 let span = parser.parse::<kw::module>()?.0;
59 let name = parser.parse()?;
60 let annotation = parser.parse()?;
61 parse_text_module(span, name, annotation, parser)
62 }
63}
64
65fn parse_text_module<'a>(
66 span: wast::Span,
67 id: Option<wast::Id<'a>>,
68 name: Option<wast::NameAnnotation<'a>>,
69 parser: Parser<'a>,
70) -> Result<Module<'a>> {
71 let _r = parser.register_annotation("custom");
72 let _r = parser.register_annotation("interface");
73
74 let mut fields = Vec::new();
75 let mut adapters = Vec::new();
76 while !parser.is_empty() {
77 parser.parens(|parser| {
78 if parser.peek::<annotation::interface>() {
79 adapters.push(parser.parse()?);
80 } else {
81 fields.push(parser.parse()?);
82 }
83 Ok(())
84 })?;
85 }
86 Ok(Module {
87 core: wast::Module {
88 span,
89 id,
90 name,
91 kind: wast::ModuleKind::Text(fields),
92 },
93 adapters,
94 })
95}
96
97pub enum Adapter<'a> {
99 Type(ast::Type<'a>),
101 Import(ast::Import<'a>),
103 Export(ast::Export<'a>),
105 Func(ast::Func<'a>),
107 Implement(ast::Implement<'a>),
109}
110
111impl<'a> Parse<'a> for Adapter<'a> {
112 fn parse(parser: Parser<'a>) -> Result<Adapter<'a>> {
113 parser.parse::<annotation::interface>()?;
114 let mut l = parser.lookahead1();
115 if l.peek::<kw::r#type>() {
116 return Ok(Adapter::Type(parser.parse()?));
117 }
118 if l.peek::<kw::import>() {
119 return Ok(Adapter::Import(parser.parse()?));
120 }
121 if l.peek::<kw::export>() {
122 return Ok(Adapter::Export(parser.parse()?));
123 }
124 if l.peek::<kw::func>() {
125 return Ok(Adapter::Func(parser.parse()?));
126 }
127 if l.peek::<kw::implement>() {
128 return Ok(Adapter::Implement(parser.parse()?));
129 }
130 Err(l.error())
131 }
132}