1#![no_std]
2extern crate alloc;
3use alloc::{
4 borrow::ToOwned,
5 collections::BTreeMap,
6 format,
7 string::{String, ToString},
8 vec,
9 vec::Vec,
10};
11use core::fmt::{self, Display};
12use derive_more::Display;
13use nom::{
14 bytes::complete::{is_not, tag, take, take_while_m_n},
15 character::complete::{alpha1, alphanumeric1, char, multispace0},
16 combinator::opt,
17 error::Error,
18 multi::{many0, separated_list0},
19 sequence::{delimited},
20 IResult, Parser,
21};
22use core::convert::identity as tuple;
23use sha3::{Digest, Sha3_256};
24#[derive(Clone, Eq, PartialEq, PartialOrd, Ord)]
25pub struct Attr {
26 pub name: String,
27 pub value: String,
28}
29
30impl Attr{
31 pub fn as_wasm_abi(&self) -> Option<usize>{
32 if self.name == "wasmAbiVer"{
33 Some(usize::from_str_radix(&self.value, 16).ok()? + 1)
34 }else{
35 None
36 }
37 }
38 pub fn from_wasm_abi(ver: usize) -> Option<Self>{
39 if ver == 0{
40 None
41 }else{
42 let ver = ver - 1;
43 Some(Self { name: "wasmAbiVer".to_owned(), value: format!("{ver:x}") })
44 }
45 }
46}
47
48pub fn merge(a: Vec<Attr>, b: Vec<Attr>) -> Vec<Attr> {
49 let mut m = BTreeMap::new();
50 for x in a.into_iter().chain(b) {
51 m.insert(x.name, x.value);
52 }
53 return m
54 .into_iter()
55 .map(|(a, b)| Attr { name: a, value: b })
56 .collect();
57}
58
59pub fn parse_balanced(mut a: &str) -> IResult<&str, String> {
60 let mut v = Vec::default();
61 let mut i = 0;
62 loop {
63 let (b, x) = nom::character::complete::anychar(a)?;
64 match x {
65 '[' => i += 1,
66 ']' => {
67 if i == 0 {
68 return Ok((a, v.into_iter().collect()));
69 }
70 i -= 1;
71 }
72 _ => {}
73 }
74 a = b;
75 v.push(x)
76 }
77}
78
79pub fn parse_attr(a: &str) -> IResult<&str, Attr> {
80 let (a, _) = multispace0(a)?;
81 let (a, _) = char('[')(a)?;
82 let (a, _) = multispace0(a)?;
83 let (a, name) = alphanumeric1(a)?;
84 let (a, _) = multispace0(a)?;
85 let (a, _) = char('=')(a)?;
86 let (a, _) = multispace0(a)?;
87 let (a, value) = parse_balanced(a)?;
88 let (a, _) = char(']')(a)?;
89 let (a, _) = multispace0(a)?;
90 return Ok((
91 a,
92 Attr {
93 name: name.to_owned(),
94 value,
95 },
96 ));
97}
98
99pub fn parse_attrs(a: &str) -> IResult<&str, Vec<Attr>> {
100 let (a, mut b) = many0(parse_attr).parse(a)?;
101 b.sort_by_key(|a| a.name.clone());
102 Ok((a, b))
103}
104
105impl Display for Attr {
106 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
107 write!(f, "[{}={}]", self.name, self.value)
108 }
109}
110#[non_exhaustive]
111#[derive(Display, Clone, Eq, PartialEq, PartialOrd, Ord)]
112pub enum ResTy {
113 #[display("")]
114 None,
115 #[display("{}", hex::encode(_0))]
116 Of([u8; 32]),
117 #[display("this")]
118 This,
119}
120pub fn parse_resty(a: &str) -> IResult<&str, ResTy> {
121 if let Some(a) = a.strip_prefix("this") {
122 return Ok((a, ResTy::This));
124 }
125 let (a, d) = opt(take_while_m_n(64, 64, |a: char| a.is_digit(16))).parse(a)?;
126 return Ok((
127 a,
128 match d {
129 Some(d) => {
130 let mut b = [0u8; 32];
131 hex::decode_to_slice(d, &mut b).unwrap();
132 ResTy::Of(b)
133 }
134 None => ResTy::None,
135 },
136 ));
137}
138#[non_exhaustive]
139#[derive(Display, Clone, Eq, PartialEq, PartialOrd, Ord)]
140pub enum Arg {
141 I32,
142 I64,
143 F32,
144 F64,
145 #[display(
146 "{}R{}{}{}",
147 ann.iter().map(|a|a.to_string()).collect::<Vec<_>>().join(""),
148 ty,
149 if *nullable{"n"}else{""},
150 if *take{""}else{"&"}
151 )]
152 Resource {
153 ty: ResTy,
154 nullable: bool,
155 take: bool,
156 ann: Vec<Attr>,
157 },
158 }
161pub fn parse_arg(a: &str) -> IResult<&str, Arg> {
162 let (a, ann) = parse_attrs(a)?;
163 let (a, _) = multispace0(a)?;
164 match a.strip_prefix("R") {
166 Some(b) => {
167 let (a, d) = parse_resty(b)?;
178 let (a, k) = opt(tag("n")).parse(a)?;
179 let (a, take) = opt(tag("&")).parse(a)?;
180 return Ok((
181 a,
182 Arg::Resource {
183 ty: d,
184 nullable: k.is_some(),
185 take: take.is_none(),
186 ann,
187 },
188 ));
189 }
190 None => {
195 let (a, c) = take(3usize)(a)?;
196 match c {
197 "I32" => return Ok((a, Arg::I32)),
198 "I64" => return Ok((a, Arg::I64)),
199 "F32" => return Ok((a, Arg::F32)),
200 "F64" => return Ok((a, Arg::F64)),
201 _ => return Err(nom::Err::Error(Error::new(a, nom::error::ErrorKind::Tag))),
202 }
203 }
204 }
205 todo!()
206}
207#[derive(Display, Clone, Eq, PartialEq, PartialOrd, Ord)]
208#[display(
209 "{}({}) -> ({})",
210 ann.iter().map(|a|a.to_string()).collect::<Vec<_>>().join(""),
211 params.iter().map(|a|a.to_string()).collect::<Vec<_>>().join(","),
212 rets.iter().map(|a|a.to_string()).collect::<Vec<_>>().join(",")
213)]
214pub struct Sig {
215 pub ann: Vec<Attr>,
216 pub params: Vec<Arg>,
217 pub rets: Vec<Arg>,
218}
219pub fn parse_sig(a: &str) -> IResult<&str, Sig> {
220 let (a, b) = parse_attrs(a)?;
221 let (a, _) = multispace0(a)?;
222 let mut d = delimited(char('('), separated_list0(char(','), parse_arg), char(')'));
223 let (a, params) = d.parse(a)?;
224 let (a, _) = multispace0(a)?;
225 let (a, _) = tag("->")(a)?;
226 let (a, _) = multispace0(a)?;
227 let (a, rets) = d.parse(a)?;
228 return Ok((
229 a,
230 Sig {
231 params,
232 rets,
233 ann: b,
234 },
235 ));
236}
237#[derive(Clone, Eq, PartialEq, PartialOrd, Ord)]
238pub struct Interface {
239 pub methods: BTreeMap<String, Sig>,
240 pub ann: Vec<Attr>,
241}
242impl Display for Interface {
243 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
244 for a in self.ann.iter() {
245 write!(f, "{a}")?;
246 }
247 write!(f, "{}", "{")?;
248 let mut x = self.methods.iter().collect::<Vec<_>>();
249 x.sort_by_key(|a| a.0);
250 for (i, (a, b)) in x.into_iter().enumerate() {
251 if i != 0 {
252 write!(f, ";")?;
253 }
254 write!(f, "{}{}", a, b)?;
255 }
256 return write!(f, "{}", "}");
257 }
258}
259pub fn parse_interface(a: &str) -> IResult<&str, Interface> {
260 pub fn go(a: &str) -> IResult<&str, Interface> {
261 let (a, s) = separated_list0(char(';'), tuple((multispace0, alphanumeric1, parse_sig))).parse(a)?;
262 let (a, _) = multispace0(a)?;
263 return Ok((
264 a,
265 Interface {
266 methods: s.into_iter().map(|(_, a, b)| (a.to_owned(), b)).collect(),
267 ann: vec![],
268 },
269 ));
270 }
271 let (a, _) = multispace0(a)?;
272 let (a, b) = parse_attrs(a)?;
273 let (a, mut c) = delimited(char('{'), go, char('}')).parse(a)?;
274 c.ann = b;
275 return Ok((a, c));
276}
277impl Interface {
278 pub fn rid(&self) -> [u8; 32] {
279 use core::fmt::Write;
281 let mut s = Sha3_256::default();
282 s.update(self.to_string());
283 return s.finalize().try_into().unwrap();
284 }
285 pub fn rid_str(&self) -> String {
286 return hex::encode(self.rid());
287 }
288}
289pub mod info;
290pub fn retuple(a: Vec<Arg>) -> Interface {
291 Interface {
292 methods: a
293 .into_iter()
294 .enumerate()
295 .map(|(a, b)| {
296 (
297 format!("v{a}"),
298 Sig {
299 ann: vec![],
300 params: vec![],
301 rets: vec![b],
302 },
303 )
304 })
305 .collect(),
306 ann: vec![],
307 }
308}