py_ast/semantic/
mangle.rs

1use std::{borrow::Cow, fmt::Debug, marker::PhantomData};
2
3#[derive(Debug, Clone)]
4pub enum ManglePrefix {
5    Mod(String),
6    Type(String),
7}
8
9#[derive(Debug, Clone)]
10pub enum MangleItem<'m> {
11    Fn {
12        name: Cow<'m, str>,
13        /// must be [`MangleItem::Type`]
14        params: Vec<MangleUnit<'m>>,
15    },
16    Type {
17        ty: Cow<'m, str>,
18    },
19    Val(),
20}
21
22#[derive(Debug, Clone)]
23pub struct MangleUnit<'m> {
24    pub prefix: Cow<'m, [ManglePrefix]>,
25    pub item: MangleItem<'m>,
26}
27
28pub trait Mangle: Sized + Send + Sync + 'static {
29    fn mangle(unit: MangleUnit) -> String;
30
31    fn demangle(str: &str) -> MangleUnit<'static>;
32}
33
34pub type DefaultMangler = ChineseMangler;
35
36pub struct ChineseMangler;
37
38impl Mangle for ChineseMangler {
39    fn mangle(unit: MangleUnit) -> String {
40        fn mangle_prefex(prefix: &[ManglePrefix]) -> String {
41            prefix.iter().fold(String::new(), |buffer, pf| match pf {
42                ManglePrefix::Mod(s) | ManglePrefix::Type(s) => buffer + &format!("{s}的"),
43            })
44        }
45
46        let prefix = mangle_prefex(&unit.prefix);
47
48        match unit.item {
49            MangleItem::Fn { name, params } => {
50                use std::fmt::Write;
51                let mut output = format!("{prefix}{name} 参");
52                for param in params.into_iter() {
53                    write!(&mut output, " {}", Self::mangle(param)).ok();
54                }
55                format!("{output} 结")
56            }
57            MangleItem::Type { ty } => prefix + &ty,
58            MangleItem::Val() => todo!(),
59        }
60    }
61
62    fn demangle(_str: &str) -> MangleUnit<'static> {
63        todo!()
64    }
65}
66
67#[derive(Debug, Clone)]
68pub struct Mangler<M: Mangle> {
69    prefix: Vec<ManglePrefix>,
70    _m: PhantomData<M>,
71}
72
73impl<M: Mangle> Default for Mangler<M> {
74    fn default() -> Self {
75        Self {
76            prefix: Default::default(),
77            _m: Default::default(),
78        }
79    }
80}
81
82impl<M: Mangle> Mangler<M> {
83    pub fn new(prefix: Vec<ManglePrefix>) -> Mangler<M> {
84        Mangler {
85            prefix,
86            _m: PhantomData,
87        }
88    }
89
90    fn mangle_unit<'m>(&'m self, item: MangleItem<'m>) -> MangleUnit<'m> {
91        MangleUnit {
92            prefix: Cow::Borrowed(&self.prefix),
93            item,
94        }
95    }
96
97    pub fn mangle(&self, item: MangleItem) -> String {
98        let unit = self.mangle_unit(item);
99        M::mangle(unit)
100    }
101
102    pub fn mangle_ty(&self, ty: &py_ir::types::TypeDefine) -> MangleUnit {
103        match ty {
104            py_ir::types::TypeDefine::Primitive(pty) => self.mangle_unit(MangleItem::Type {
105                ty: Cow::Owned(pty.to_string()),
106            }),
107            py_ir::types::TypeDefine::Complex(_) => todo!(),
108        }
109    }
110
111    pub fn mangle_fn(&self, name: &str, sign: &py_declare::defs::FnSign) -> String {
112        let params = sign
113            .params
114            .iter()
115            .map(|param| self.mangle_ty(&param.ty))
116            .collect::<Vec<_>>();
117        self.mangle(MangleItem::Fn {
118            name: Cow::Borrowed(name),
119            params,
120        })
121    }
122}