1use wast::parser::{self, Parse, Parser};
2
3use crate::{Atom, Expr, Index, Param, Result, SExpr};
4
5#[derive(Debug, Clone, PartialEq, Eq)]
7pub struct TypeUse {
8 type_def: Option<Type>,
9 params: Vec<Param>,
10 results: Vec<Result>,
11}
12
13impl TypeUse {
14 pub fn new(
15 type_def: Option<Type>,
16 params: Vec<Param>,
17 results: Vec<Result>,
18 ) -> Self {
19 Self {
20 type_def,
21 params,
22 results,
23 }
24 }
25
26 pub(crate) fn exprs(&self) -> Vec<Expr> {
27 let mut v = Vec::new();
28
29 if let Some(ref type_def) = self.type_def {
30 v.push(Expr::SExpr(Box::new(type_def.clone())));
31 }
32
33 v.append(
34 &mut self
35 .params
36 .iter()
37 .map(|p| Expr::SExpr(Box::new(p.clone())))
38 .collect(),
39 );
40 v.append(
41 &mut self
42 .results
43 .iter()
44 .map(|r| Expr::SExpr(Box::new(r.clone())))
45 .collect(),
46 );
47
48 v
49 }
50}
51
52impl Parse<'_> for TypeUse {
53 fn parse(parser: Parser<'_>) -> parser::Result<Self> {
54 let mut type_def = None;
55
56 if parser.peek2::<wast::kw::r#type>() {
57 type_def = Some(parser.parens(Type::parse)?);
58 }
59
60 let mut params = Vec::new();
61 let mut results = Vec::new();
62
63 while !parser.is_empty() {
64 if parser.peek2::<wast::kw::param>() {
65 params.push(parser.parens(Param::parse)?)
66 } else {
67 break;
68 }
69 }
70
71 while !parser.is_empty() {
72 if parser.peek2::<wast::kw::result>() {
73 results.push(parser.parens(Result::parse)?)
74 } else {
75 break;
76 }
77 }
78
79 Ok(Self {
80 type_def,
81 params,
82 results,
83 })
84 }
85}
86
87#[derive(Debug, Clone, PartialEq, Eq)]
88pub struct Type {
89 pub idx: Index,
90}
91
92impl SExpr for Type {
93 fn car(&self) -> String {
94 "type".to_owned()
95 }
96
97 fn cdr(&self) -> Vec<Expr> {
98 vec![Expr::Atom(Atom::new(self.idx.to_string()))]
99 }
100}
101
102impl Parse<'_> for Type {
103 fn parse(parser: Parser<'_>) -> parser::Result<Self> {
104 parser.parse::<wast::kw::r#type>()?;
105
106 let idx = parser.parse::<Index>()?;
107
108 Ok(Self { idx })
109 }
110}