pidl_core/
lib.rs

1use derive_more::Display;
2use nom::{
3    bytes::complete::{is_not, tag, take, take_while_m_n},
4    character::complete::{alpha1, alphanumeric1, char, multispace0},
5    combinator::opt,
6    error::Error,
7    multi::{many0, separated_list0},
8    sequence::{delimited, tuple},
9    IResult,
10};
11use sha3::{Digest, Sha3_256};
12use std::{collections::BTreeMap, fmt::Display};
13#[derive(Clone, Eq, PartialEq, PartialOrd, Ord)]
14pub struct Attr {
15    pub name: String,
16    pub value: String,
17}
18
19pub fn merge(a: Vec<Attr>, b: Vec<Attr>) -> Vec<Attr> {
20    let mut m = BTreeMap::new();
21    for x in a.into_iter().chain(b) {
22        m.insert(x.name, x.value);
23    }
24    return m
25        .into_iter()
26        .map(|(a, b)| Attr { name: a, value: b })
27        .collect();
28}
29
30pub fn parse_balanced(mut a: &str) -> IResult<&str, String> {
31    let mut v = vec![];
32    let mut i = 0;
33    loop {
34        let (b, x) = nom::character::complete::anychar(a)?;
35        match x {
36            '[' => i += 1,
37            ']' => {
38                if i == 0 {
39                    return Ok((a, v.into_iter().collect()));
40                }
41                i -= 1;
42            }
43            _ => {}
44        }
45        a = b;
46        v.push(x)
47    }
48}
49
50pub fn parse_attr(a: &str) -> IResult<&str, Attr> {
51    let (a, _) = multispace0(a)?;
52    let (a, _) = char('[')(a)?;
53    let (a, _) = multispace0(a)?;
54    let (a, name) = alphanumeric1(a)?;
55    let (a, _) = multispace0(a)?;
56    let (a, _) = char('=')(a)?;
57    let (a, _) = multispace0(a)?;
58    let (a, value) = parse_balanced(a)?;
59    let (a, _) = char(']')(a)?;
60    let (a, _) = multispace0(a)?;
61    return Ok((
62        a,
63        Attr {
64            name: name.to_owned(),
65            value,
66        },
67    ));
68}
69
70pub fn parse_attrs(a: &str) -> IResult<&str, Vec<Attr>> {
71    let (a, mut b) = many0(parse_attr)(a)?;
72    b.sort_by_key(|a| a.name.clone());
73    Ok((a, b))
74}
75
76impl Display for Attr {
77    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
78        write!(f, "[{}={}]", self.name, self.value)
79    }
80}
81
82#[derive(Display, Clone, Eq, PartialEq, PartialOrd, Ord)]
83pub enum ResTy {
84    #[display(fmt = "{}", "hex::encode(_0)")]
85    Of([u8; 32]),
86    #[display(fmt = "this")]
87    This,
88}
89pub fn parse_resty(a: &str) -> IResult<&str, ResTy> {
90    if let Some(a) = a.strip_prefix("this") {
91        // let (a, k) = opt(tag("n"))(a)?;
92        return Ok((a, ResTy::This));
93    }
94    let (a, d) = take_while_m_n(64, 64, |a: char| a.is_digit(16))(a)?;
95    return Ok((
96        a,{
97       
98                let mut b = [0u8; 32];
99                hex::decode_to_slice(d, &mut b).unwrap();
100                ResTy::Of(b)
101        }
102
103    ));
104}
105#[derive(Display, Clone, Eq, PartialEq, PartialOrd, Ord)]
106pub enum Arg {
107    #[display(fmt="{}@{}{}","ann.iter().map(|a|a.to_string()).collect::<Vec<_>>().join(\"\")","name","params.iter().map(|a|a.to_string()).map(|b|format!(\"({b})\")).collect::<Vec<_>>().join(\"\")")]
108    Prim{
109        name: String,
110        ann: Vec<Attr>,
111        params: Vec<Arg>,
112    },
113    #[display(
114        fmt = "{}R{}",
115        "ann.iter().map(|a|a.to_string()).collect::<Vec<_>>().join(\"\")",
116        "ty",
117    )]
118    Resource {
119        ty: ResTy,
120        ann: Vec<Attr>,
121    },
122    // #[display(fmt = "{}", _0)]
123    // Func(Sig),
124}
125pub fn parse_arg(a: &str) -> IResult<&str, Arg> {
126    let (a, ann) = parse_attrs(a)?;
127    let (a, _) = multispace0(a)?;
128    // let (c,b) = take(1usize)(a)?;
129    match a.strip_prefix("R") {
130        Some(b) => {
131            // if let Some(a) = b.strip_prefix("this"){
132            //     let (a, k) = opt(tag("n"))(a)?;
133            //     return Ok((
134            //         a,
135            //         Arg::Resource {
136            //             ty: ResTy::This,
137            //             nullable: k.is_some(),
138            //         },
139            //     ));
140            // }
141            let (a, d) = parse_resty(b)?;
142            return Ok((
143                a,
144                Arg::Resource {
145                    ty: d,
146                    ann,
147                },
148            ));
149        }
150        // "(" => {
151        //     let (a, x) = parse_sig(a)?;
152        //     return Ok((a, Arg::Func(x)));
153        // }
154        None => match a.strip_prefix("@"){
155            None => todo!(),
156            Some(a) => {
157                let (a,k) = alphanumeric1(a)?;
158                let (a,l) = many0(delimited(tag("("), parse_arg, tag(")")))(a)?;
159                return Ok((a,Arg::Prim { name: k.to_owned(), ann: ann, params: l }));
160            }
161        }
162    }
163    todo!()
164}
165#[derive(Display, Clone, Eq, PartialEq, PartialOrd, Ord)]
166#[display(
167    fmt = "{}({}) -> ({})",
168    "ann.iter().map(|a|a.to_string()).collect::<Vec<_>>().join(\"\")",
169    "params.iter().map(|a|a.to_string()).collect::<Vec<_>>().join(\",\")",
170    "rets.iter().map(|a|a.to_string()).collect::<Vec<_>>().join(\",\")"
171)]
172pub struct Sig {
173    pub ann: Vec<Attr>,
174    pub params: Vec<Arg>,
175    pub rets: Vec<Arg>,
176}
177pub fn parse_sig(a: &str) -> IResult<&str, Sig> {
178    let (a, b) = parse_attrs(a)?;
179    let (a, _) = multispace0(a)?;
180    let mut d = delimited(char('('), separated_list0(char(','), parse_arg), char(')'));
181    let (a, params) = d(a)?;
182    let (a, _) = multispace0(a)?;
183    let (a, _) = tag("->")(a)?;
184    let (a, _) = multispace0(a)?;
185    let (a, rets) = d(a)?;
186    return Ok((
187        a,
188        Sig {
189            params,
190            rets,
191            ann: b,
192        },
193    ));
194}
195#[derive(Clone, Eq, PartialEq, PartialOrd, Ord)]
196pub struct Interface {
197    pub methods: BTreeMap<String, Sig>,
198    pub ann: Vec<Attr>,
199}
200impl Display for Interface {
201    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
202        for a in self.ann.iter() {
203            write!(f, "{a}")?;
204        }
205        write!(f, "{}", "{")?;
206        let mut x = self.methods.iter().collect::<Vec<_>>();
207        x.sort_by_key(|a| a.0);
208        for (i, (a, b)) in x.into_iter().enumerate() {
209            if i != 0 {
210                write!(f, ";")?;
211            }
212            write!(f, "{}{}", a, b)?;
213        }
214        return write!(f, "{}", "}");
215    }
216}
217pub fn parse_interface(a: &str) -> IResult<&str, Interface> {
218    pub fn go(a: &str) -> IResult<&str, Interface> {
219        let (a, s) = separated_list0(char(';'), tuple((multispace0, alphanumeric1, parse_sig)))(a)?;
220        let (a, _) = multispace0(a)?;
221        return Ok((
222            a,
223            Interface {
224                methods: s.into_iter().map(|(_, a, b)| (a.to_owned(), b)).collect(),
225                ann: vec![],
226            },
227        ));
228    }
229    let (a, _) = multispace0(a)?;
230    let (a, b) = parse_attrs(a)?;
231    let (a, mut c) = delimited(char('{'), go, char('}'))(a)?;
232    c.ann = b;
233    return Ok((a, c));
234}
235impl Interface {
236    pub fn rid(&self) -> [u8; 32] {
237        use std::io::Write;
238        let mut s = Sha3_256::default();
239        write!(s, "{}", self);
240        return s.finalize().try_into().unwrap();
241    }
242    pub fn rid_str(&self) -> String {
243        return hex::encode(self.rid());
244    }
245}
246pub mod info;
247pub fn retuple(a: Vec<Arg>) -> Interface {
248    Interface {
249        methods: a.into_iter().enumerate().map(|(a, b)| {
250            (
251                format!("v{a}"),
252                Sig {
253                    ann: vec![],
254                    params: vec![],
255                    rets: vec![b],
256                },
257            )
258        }).collect(),
259        ann: vec![],
260    }
261}