1use std::fmt;
2
3use wast::parser::{self, Cursor, Parse, Parser, Peek};
4
5use crate::{AsAtoms, Atom, Expr, Integer, Param, Result, SExpr};
6
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub enum ValueType {
9 I32,
10 I64,
11 F32,
12 F64,
13}
14
15impl ValueType {
16 pub fn as_expr(&self) -> Expr {
17 Expr::Atom(Atom::new(self.to_string()))
18 }
19}
20
21impl AsAtoms for ValueType {
22 fn as_atoms(&self) -> Vec<Atom> {
23 vec![Atom::new(self.to_string())]
24 }
25}
26
27impl fmt::Display for ValueType {
28 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29 match self {
30 Self::I32 => write!(f, "i32"),
31 Self::I64 => write!(f, "i64"),
32 Self::F32 => write!(f, "f32"),
33 Self::F64 => write!(f, "f64"),
34 }
35 }
36}
37
38impl Parse<'_> for ValueType {
39 fn parse(parser: Parser<'_>) -> parser::Result<Self> {
40 let mut l = parser.lookahead1();
41
42 if l.peek::<wast::kw::i32>() {
43 parser.parse::<wast::kw::i32>()?;
44 Ok(Self::I32)
45 } else if l.peek::<wast::kw::i64>() {
46 parser.parse::<wast::kw::i64>()?;
47 Ok(Self::I64)
48 } else if l.peek::<wast::kw::f32>() {
49 parser.parse::<wast::kw::f32>()?;
50 Ok(Self::F32)
51 } else if l.peek::<wast::kw::f64>() {
52 parser.parse::<wast::kw::f64>()?;
53 Ok(Self::F64)
54 } else {
55 Err(l.error())
56 }
57 }
58}
59
60impl Peek for ValueType {
61 fn peek(cursor: Cursor<'_>) -> bool {
62 wast::kw::i32::peek(cursor)
63 || wast::kw::i64::peek(cursor)
64 || wast::kw::f32::peek(cursor)
65 || wast::kw::f64::peek(cursor)
66 }
67
68 fn display() -> &'static str {
69 "a value type"
70 }
71}
72
73#[derive(Debug, Clone, PartialEq, Eq)]
75pub struct FuncType {
76 params: Vec<Param>,
77 results: Vec<Result>,
78}
79
80impl FuncType {
81 pub fn new(params: Vec<Param>, results: Vec<Result>) -> Self {
82 Self { params, results }
83 }
84}
85
86impl SExpr for FuncType {
87 fn car(&self) -> String {
88 "func".to_owned()
89 }
90
91 fn cdr(&self) -> Vec<Expr> {
92 let mut v: Vec<_> = self
93 .params
94 .iter()
95 .map(|p| Expr::SExpr(Box::new(p.clone())))
96 .collect();
97 let mut results: Vec<_> = self
98 .results
99 .iter()
100 .map(|r| Expr::SExpr(Box::new(r.clone())))
101 .collect();
102
103 v.append(&mut results);
104
105 v
106 }
107}
108
109impl Parse<'_> for FuncType {
110 fn parse(parser: Parser<'_>) -> parser::Result<Self> {
111 parser.parse::<wast::kw::func>()?;
112
113 let mut params = Vec::new();
114 let mut results = Vec::new();
115
116 while !parser.is_empty() {
117 if parser.peek2::<wast::kw::param>() {
118 params.push(parser.parens(Param::parse)?)
119 } else {
120 break;
121 }
122 }
123
124 while !parser.is_empty() {
125 if parser.peek2::<wast::kw::result>() {
126 results.push(parser.parens(Result::parse)?)
127 } else {
128 break;
129 }
130 }
131
132 Ok(Self { params, results })
133 }
134}
135
136#[derive(Debug, Clone, PartialEq, Eq)]
137pub struct Limits {
138 min: Integer,
139 max: Option<Integer>,
140}
141
142impl Limits {
143 pub fn new(min: Integer, max: Option<Integer>) -> Self {
144 Self { min, max }
145 }
146
147 pub(crate) fn exprs(&self) -> Vec<Expr> {
148 let mut v = vec![Expr::Atom(Atom::new(self.min.to_string()))];
149
150 if let Some(ref max) = self.max {
151 v.push(Expr::Atom(Atom::new(max.to_string())));
152 }
153
154 v
155 }
156}
157
158impl Parse<'_> for Limits {
159 fn parse(parser: Parser<'_>) -> parser::Result<Self> {
160 let min = parser.parse::<Integer>()?;
161 let max = parser.parse::<Option<Integer>>()?;
162
163 Ok(Self { min, max })
164 }
165}
166
167#[derive(Debug, Clone, PartialEq, Eq)]
168pub struct MemType {
169 lim: Limits,
170}
171
172impl MemType {
173 pub fn new(lim: Limits) -> Self {
174 Self { lim }
175 }
176
177 pub(crate) fn exprs(&self) -> Vec<Expr> {
178 self.lim.exprs()
179 }
180}
181
182impl Parse<'_> for MemType {
183 fn parse(parser: Parser<'_>) -> parser::Result<Self> {
184 let lim = parser.parse::<Limits>()?;
185
186 Ok(Self { lim })
187 }
188}
189
190#[derive(Debug, Clone, PartialEq, Eq)]
191pub enum GlobalType {
192 Mut(GlobalTypeMut),
193 NonMut(ValueType),
194}
195
196impl GlobalType {
197 pub(crate) fn expr(&self) -> Expr {
198 match self {
199 Self::Mut(m) => Expr::SExpr(Box::new(m.clone())),
200 Self::NonMut(v) => Expr::Atom(Atom::new(v.to_string())),
201 }
202 }
203}
204
205impl Parse<'_> for GlobalType {
206 fn parse(parser: Parser<'_>) -> parser::Result<Self> {
207 if parser.peek::<wast::LParen>() {
208 Ok(Self::Mut(parser.parens(GlobalTypeMut::parse)?))
209 } else {
210 let val_type = parser.parse::<ValueType>()?;
211
212 Ok(Self::NonMut(val_type))
213 }
214 }
215}
216
217#[derive(Debug, Clone, PartialEq, Eq)]
218pub struct GlobalTypeMut {
219 val_type: ValueType,
220}
221
222impl GlobalTypeMut {
223 pub fn new(val_type: ValueType) -> Self {
224 Self { val_type }
225 }
226}
227
228impl Parse<'_> for GlobalTypeMut {
229 fn parse(parser: Parser<'_>) -> parser::Result<Self> {
230 parser.parse::<wast::kw::r#mut>()?;
231
232 let val_type = parser.parse::<ValueType>()?;
233
234 Ok(Self { val_type })
235 }
236}
237
238impl SExpr for GlobalTypeMut {
239 fn car(&self) -> String {
240 "mut".to_owned()
241 }
242
243 fn cdr(&self) -> Vec<Expr> {
244 vec![Expr::Atom(Atom::new(self.val_type.to_string()))]
245 }
246}