wit_text/ast/
ty.rs

1use crate::ast::kw;
2use wast::parser::{Parse, Parser, Result};
3
4/// A type declaration in a wasm interface type subsection
5#[derive(Clone)]
6pub struct Type<'a> {
7    /// The optional name of this type, used to refer to it from elsewhere.
8    pub name: Option<wast::Id<'a>>,
9    /// Explicitly listed parameters with optional names, if any.
10    pub params: Vec<(Option<wast::Id<'a>>, ValType)>,
11    /// The results of this function signature.
12    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/// Possible value types that can be used in function signatures and such.
58#[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/// An inline type definition or a use of a type defined elsewhere.
145#[derive(Clone)]
146pub struct TypeUse<'a> {
147    /// Where the index was defined, if it was defined.
148    pub index_span: Option<wast::Span>,
149    /// The type declaration that this is reference.
150    pub index: Option<wast::Index<'a>>,
151    /// The inline parameters, if any.
152    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}