wat_ast/
import_desc.rs

1use wast::parser::{Parse, Parser, Result};
2
3use crate::{Atom, Expr, Index, SExpr, TypeUse};
4
5#[derive(Debug, Clone, PartialEq, Eq)]
6pub enum ImportDesc {
7    Func(ImportDescFunc),
8}
9
10impl SExpr for ImportDesc {
11    fn car(&self) -> String {
12        match self {
13            Self::Func(d) => d.car(),
14        }
15    }
16
17    fn cdr(&self) -> Vec<Expr> {
18        match self {
19            Self::Func(d) => d.cdr(),
20        }
21    }
22}
23
24impl Parse<'_> for ImportDesc {
25    fn parse(parser: Parser<'_>) -> Result<Self> {
26        let mut l = parser.lookahead1();
27
28        if l.peek::<wast::kw::func>() {
29            Ok(Self::Func(parser.parse::<ImportDescFunc>()?))
30        } else {
31            Err(l.error())
32        }
33    }
34}
35
36/// https://webassembly.github.io/spec/core/text/modules.html#text-importdesc
37#[derive(Debug, Clone, PartialEq, Eq)]
38pub struct ImportDescFunc {
39    idx:      Option<Index>,
40    type_use: TypeUse,
41}
42
43impl ImportDescFunc {
44    pub fn new(idx: Option<Index>, type_use: TypeUse) -> Self {
45        Self { idx, type_use }
46    }
47}
48
49impl SExpr for ImportDescFunc {
50    fn car(&self) -> String {
51        "func".to_owned()
52    }
53
54    fn cdr(&self) -> Vec<Expr> {
55        let mut v = Vec::new();
56
57        if let Some(ref idx) = self.idx {
58            v.push(Expr::Atom(Atom::new(idx.to_string())));
59        }
60
61        v.append(&mut self.type_use.exprs());
62
63        v
64    }
65}
66
67impl Parse<'_> for ImportDescFunc {
68    fn parse(parser: Parser<'_>) -> Result<Self> {
69        parser.parse::<wast::kw::func>()?;
70
71        let idx = parser.parse::<Option<Index>>()?;
72        let type_use = parser.parse::<TypeUse>()?;
73
74        Ok(Self { idx, type_use })
75    }
76}