pit_core/
lib.rs

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        // let (a, k) = opt(tag("n"))(a)?;
104        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    // #[display(fmt = "{}", _0)]
140    // Func(Sig),
141}
142pub fn parse_arg(a: &str) -> IResult<&str, Arg> {
143    let (a, ann) = parse_attrs(a)?;
144    let (a, _) = multispace0(a)?;
145    // let (c,b) = take(1usize)(a)?;
146    match a.strip_prefix("R") {
147        Some(b) => {
148            // if let Some(a) = b.strip_prefix("this"){
149            //     let (a, k) = opt(tag("n"))(a)?;
150            //     return Ok((
151            //         a,
152            //         Arg::Resource {
153            //             ty: ResTy::This,
154            //             nullable: k.is_some(),
155            //         },
156            //     ));
157            // }
158            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        // "(" => {
172        //     let (a, x) = parse_sig(a)?;
173        //     return Ok((a, Arg::Func(x)));
174        // }
175        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::io::Write;
261        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}