1use crate::ast::kw;
2use wast::parser::{Parse, Parser, Result};
3
4#[derive(Clone)]
6pub struct Type<'a> {
7 pub name: Option<wast::Id<'a>>,
9 pub params: Vec<(Option<wast::Id<'a>>, ValType)>,
11 pub results: Vec<ValType>,
13}
14
15fn finish_parse<'a>(
16 parser: Parser<'a>,
17 params: &mut Vec<(Option<wast::Id<'a>>, ValType)>,
18 results: &mut Vec<ValType>,
19) -> Result<()> {
20 while parser.peek2::<kw::param>() {
21 params.push(parser.parens(|p| {
22 p.parse::<kw::param>()?;
23 let id = p.parse()?;
24 let ty = p.parse()?;
25 Ok((id, ty))
26 })?);
27 }
28 while parser.peek2::<kw::result>() {
29 results.push(parser.parens(|p| {
30 p.parse::<kw::result>()?;
31 p.parse()
32 })?);
33 }
34 Ok(())
35}
36
37impl<'a> Parse<'a> for Type<'a> {
38 fn parse(parser: Parser<'a>) -> Result<Type<'a>> {
39 parser.parse::<kw::r#type>()?;
40 let name = parser.parse()?;
41
42 let mut params = Vec::new();
43 let mut results = Vec::new();
44 parser.parens(|p| {
45 p.parse::<kw::func>()?;
46 finish_parse(parser, &mut params, &mut results)
47 })?;
48
49 Ok(Type {
50 name,
51 params,
52 results,
53 })
54 }
55}
56
57#[derive(Clone, PartialEq, Eq, Hash)]
59#[allow(missing_docs)]
60pub enum ValType {
61 String,
62 Externref,
63 S8,
64 S16,
65 S32,
66 S64,
67 I32,
68 I64,
69 U8,
70 U16,
71 U32,
72 U64,
73 F32,
74 F64,
75}
76
77impl<'a> Parse<'a> for ValType {
78 fn parse(parser: Parser<'a>) -> Result<Self> {
79 let mut l = parser.lookahead1();
80 if l.peek::<kw::s8>() {
81 parser.parse::<kw::s8>()?;
82 return Ok(ValType::S8);
83 }
84 if l.peek::<kw::s16>() {
85 parser.parse::<kw::s16>()?;
86 return Ok(ValType::S16);
87 }
88 if l.peek::<kw::s32>() {
89 parser.parse::<kw::s32>()?;
90 return Ok(ValType::S32);
91 }
92 if l.peek::<kw::s64>() {
93 parser.parse::<kw::s64>()?;
94 return Ok(ValType::S64);
95 }
96 if l.peek::<kw::u8>() {
97 parser.parse::<kw::u8>()?;
98 return Ok(ValType::U8);
99 }
100 if l.peek::<kw::u16>() {
101 parser.parse::<kw::u16>()?;
102 return Ok(ValType::U16);
103 }
104 if l.peek::<kw::u32>() {
105 parser.parse::<kw::u32>()?;
106 return Ok(ValType::U32);
107 }
108 if l.peek::<kw::u64>() {
109 parser.parse::<kw::u64>()?;
110 return Ok(ValType::U64);
111 }
112 if l.peek::<kw::f32>() {
113 parser.parse::<kw::f32>()?;
114 return Ok(ValType::F32);
115 }
116 if l.peek::<kw::f64>() {
117 parser.parse::<kw::f64>()?;
118 return Ok(ValType::F64);
119 }
120 if l.peek::<kw::i32>() {
121 parser.parse::<kw::i32>()?;
122 return Ok(ValType::I32);
123 }
124 if l.peek::<kw::i64>() {
125 parser.parse::<kw::i64>()?;
126 return Ok(ValType::I64);
127 }
128 if l.peek::<kw::externref>() {
129 parser.parse::<kw::externref>()?;
130 return Ok(ValType::Externref);
131 }
132 if l.peek::<kw::anyref>() {
133 parser.parse::<kw::anyref>()?;
134 return Ok(ValType::Externref);
135 }
136 if l.peek::<kw::string>() {
137 parser.parse::<kw::string>()?;
138 return Ok(ValType::String);
139 }
140 Err(l.error())
141 }
142}
143
144#[derive(Clone)]
146pub struct TypeUse<'a> {
147 pub index_span: Option<wast::Span>,
149 pub index: Option<wast::Index<'a>>,
151 pub ty: Type<'a>,
153}
154
155impl<'a> Parse<'a> for TypeUse<'a> {
156 fn parse(parser: Parser<'a>) -> Result<Self> {
157 let index = if parser.peek2::<kw::r#type>() {
158 Some(parser.parens(|parser| {
159 parser.parse::<kw::r#type>()?;
160 Ok((parser.cur_span(), parser.parse()?))
161 })?)
162 } else {
163 None
164 };
165 let (index_span, index) = match index {
166 Some((a, b)) => (Some(a), Some(b)),
167 None => (None, None),
168 };
169 let mut params = Vec::new();
170 let mut results = Vec::new();
171 finish_parse(parser, &mut params, &mut results)?;
172
173 Ok(TypeUse {
174 index,
175 index_span,
176 ty: Type {
177 name: None,
178 params,
179 results,
180 },
181 })
182 }
183}