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