Skip to main content

litex/obj/
atom.rs

1use crate::prelude::*;
2use std::fmt;
3
4#[derive(Clone)]
5pub enum Atom {
6    Identifier(Identifier),
7    IdentifierWithMod(IdentifierWithMod),
8    FieldAccess(FieldAccess),
9    FieldAccessWithMod(FieldAccessWithMod),
10}
11
12#[derive(Clone)]
13pub enum IdentifierOrIdentifierWithMod {
14    Identifier(Identifier),
15    IdentifierWithMod(IdentifierWithMod),
16}
17
18impl fmt::Display for IdentifierOrIdentifierWithMod {
19    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20        match self {
21            IdentifierOrIdentifierWithMod::Identifier(i) => write!(f, "{}", i),
22            IdentifierOrIdentifierWithMod::IdentifierWithMod(m) => write!(f, "{}", m),
23        }
24    }
25}
26
27impl IdentifierOrIdentifierWithMod {
28    pub fn literally_the_same_as(&self, other: &IdentifierOrIdentifierWithMod) -> bool {
29        return self.to_string() == other.to_string();
30    }
31}
32
33#[derive(Clone)]
34pub struct Identifier {
35    pub name: String,
36}
37
38pub fn identifier_to_string(name: &str) -> String {
39    name.to_string()
40}
41
42#[derive(Clone)]
43pub struct IdentifierWithMod {
44    pub mod_name: String,
45    pub name: String,
46}
47
48pub fn identifier_with_mod_to_string(mod_name: &str, name: &str) -> String {
49    format!("{}{}{}", mod_name, MOD_SIGN, name)
50}
51
52#[derive(Clone)]
53pub struct FieldAccess {
54    pub name: String,
55    pub field: String,
56}
57
58#[derive(Clone)]
59pub struct FieldAccessWithMod {
60    pub mod_name: String,
61    pub name: String,
62    pub field: String,
63}
64
65impl fmt::Display for Atom {
66    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67        match self {
68            Atom::Identifier(atom) => write!(f, "{}", atom),
69            Atom::IdentifierWithMod(atom) => write!(f, "{}", atom),
70            Atom::FieldAccess(atom) => write!(f, "{}", atom),
71            Atom::FieldAccessWithMod(atom) => write!(f, "{}", atom),
72        }
73    }
74}
75
76impl Identifier {
77    pub fn new(name: String) -> Self {
78        Identifier { name }
79    }
80}
81
82impl From<Identifier> for Atom {
83    fn from(id: Identifier) -> Self {
84        Atom::Identifier(id)
85    }
86}
87
88impl From<IdentifierWithMod> for Atom {
89    fn from(m: IdentifierWithMod) -> Self {
90        Atom::IdentifierWithMod(m)
91    }
92}
93
94impl From<FieldAccess> for Atom {
95    fn from(f: FieldAccess) -> Self {
96        Atom::FieldAccess(f)
97    }
98}
99
100impl From<FieldAccessWithMod> for Atom {
101    fn from(f: FieldAccessWithMod) -> Self {
102        Atom::FieldAccessWithMod(f)
103    }
104}
105
106impl IdentifierWithMod {
107    pub fn new(mod_name: String, name: String) -> Self {
108        IdentifierWithMod { mod_name, name }
109    }
110}
111
112impl FieldAccess {
113    pub fn new(name: String, field: String) -> Self {
114        FieldAccess { name, field }
115    }
116
117    /// 在已有 `root.field` 上再追加一段(嵌套 struct 绑定等运行时路径;`name` 中可含 `.`)。
118    pub fn with_appended_field(&self, field_name: &str) -> FieldAccess {
119        let prefix = format!("{}{}{}", self.name, DOT_AKA_FIELD_ACCESS_SIGN, self.field);
120        FieldAccess::new(prefix, field_name.to_string())
121    }
122}
123
124impl FieldAccessWithMod {
125    pub fn new(mod_name: String, name: String, field: String) -> Self {
126        FieldAccessWithMod {
127            mod_name,
128            name,
129            field,
130        }
131    }
132
133    pub fn with_appended_field(&self, field_name: &str) -> FieldAccessWithMod {
134        let prefix = format!("{}{}{}", self.name, DOT_AKA_FIELD_ACCESS_SIGN, self.field);
135        FieldAccessWithMod::new(self.mod_name.clone(), prefix, field_name.to_string())
136    }
137}
138
139impl fmt::Display for FieldAccess {
140    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
141        write!(f, "{}", field_access_to_string(&self.name, &self.field))
142    }
143}
144
145pub fn field_access_to_string(name: &str, field: &str) -> String {
146    format!("{}{}{}", name, DOT_AKA_FIELD_ACCESS_SIGN, field)
147}
148
149impl fmt::Display for FieldAccessWithMod {
150    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
151        write!(
152            f,
153            "{}",
154            field_access_with_mod_to_string(&self.mod_name, &self.name, &self.field)
155        )
156    }
157}
158
159pub fn field_access_with_mod_to_string(mod_name: &str, name: &str, field: &str) -> String {
160    format!(
161        "{}{}{}{}{}",
162        mod_name, MOD_SIGN, name, DOT_AKA_FIELD_ACCESS_SIGN, field
163    )
164}