wat_ast/
export.rs

1use wast::parser::{Cursor, Parse, Parser, Peek, Result};
2
3use crate::{Atom, Expr, FunctionSectionEntry, SExpr};
4
5/// https://webassembly.github.io/spec/core/text/modules.html#text-global-abbrev
6#[derive(Debug, Clone, PartialEq, Eq)]
7pub struct InlineExport {
8    name: String,
9}
10
11impl InlineExport {
12    pub fn new(name: String) -> Self {
13        Self { name }
14    }
15}
16
17impl SExpr for InlineExport {
18    fn car(&self) -> String {
19        "export".to_owned()
20    }
21
22    fn cdr(&self) -> Vec<Expr> {
23        vec![Expr::Atom(Atom::new(format!(r#""{}""#, self.name)))]
24    }
25}
26
27impl Parse<'_> for InlineExport {
28    fn parse(parser: Parser<'_>) -> Result<Self> {
29        parser.parse::<wast::kw::export>()?;
30
31        let name = parser.parse::<String>()?;
32
33        Ok(Self { name })
34    }
35}
36
37#[derive(Debug, Clone, PartialEq, Eq)]
38pub struct Export {
39    name: String,
40    desc: ExportDesc,
41}
42
43impl Export {
44    pub fn new(name: String, desc: ExportDesc) -> Self {
45        Self { name, desc }
46    }
47}
48
49impl SExpr for Export {
50    fn car(&self) -> String {
51        "export".to_owned()
52    }
53
54    fn cdr(&self) -> Vec<Expr> {
55        vec![
56            Expr::Atom(Atom::new(format!(r#""{}""#, self.name))),
57            Expr::SExpr(Box::new(self.desc.clone())),
58        ]
59    }
60}
61
62impl Parse<'_> for Export {
63    fn parse(parser: Parser<'_>) -> Result<Self> {
64        parser.parse::<wast::kw::export>()?;
65
66        let name = parser.parse::<String>()?;
67        let desc = parser.parse::<ExportDesc>()?;
68
69        Ok(Self { name, desc })
70    }
71}
72
73impl Peek for Export {
74    fn peek(cursor: Cursor<'_>) -> bool {
75        cursor.integer().is_some()
76    }
77
78    fn display() -> &'static str {
79        "integer"
80    }
81}
82
83#[derive(Debug, Clone, PartialEq, Eq)]
84pub enum ExportDesc {
85    Func(Box<FunctionSectionEntry>),
86}
87
88impl SExpr for ExportDesc {
89    fn car(&self) -> String {
90        match self {
91            Self::Func(f) => f.car(),
92        }
93    }
94
95    fn cdr(&self) -> Vec<Expr> {
96        match self {
97            Self::Func(f) => f.cdr(),
98        }
99    }
100}
101
102impl Parse<'_> for ExportDesc {
103    fn parse(parser: Parser<'_>) -> Result<Self> {
104        let mut l = parser.lookahead1();
105
106        if l.peek::<wast::kw::func>() {
107            Ok(Self::Func(Box::new(
108                parser.parse::<FunctionSectionEntry>()?,
109            )))
110        } else {
111            Err(l.error())
112        }
113    }
114}