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 IdentifierWithMod {
83    pub fn new(mod_name: String, name: String) -> Self {
84        IdentifierWithMod { mod_name, name }
85    }
86}
87
88impl FieldAccess {
89    pub fn new(name: String, field: String) -> Self {
90        FieldAccess { name, field }
91    }
92
93    /// 在已有 `root.field` 上再追加一段(嵌套 struct 绑定等运行时路径;`name` 中可含 `.`)。
94    pub fn with_appended_field(&self, field_name: &str) -> FieldAccess {
95        let prefix = format!(
96            "{}{}{}",
97            self.name,
98            DOT_AKA_FIELD_ACCESS_SIGN,
99            self.field
100        );
101        FieldAccess::new(prefix, field_name.to_string())
102    }
103}
104
105impl FieldAccessWithMod {
106    pub fn new(mod_name: String, name: String, field: String) -> Self {
107        FieldAccessWithMod {
108            mod_name,
109            name,
110            field,
111        }
112    }
113
114    pub fn with_appended_field(&self, field_name: &str) -> FieldAccessWithMod {
115        let prefix = format!(
116            "{}{}{}",
117            self.name,
118            DOT_AKA_FIELD_ACCESS_SIGN,
119            self.field
120        );
121        FieldAccessWithMod::new(self.mod_name.clone(), prefix, field_name.to_string())
122    }
123}
124
125impl fmt::Display for FieldAccess {
126    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
127        write!(f, "{}", field_access_to_string(&self.name, &self.field))
128    }
129}
130
131pub fn field_access_to_string(name: &str, field: &str) -> String {
132    format!(
133        "{}{}{}",
134        name,
135        DOT_AKA_FIELD_ACCESS_SIGN,
136        field
137    )
138}
139
140impl fmt::Display for FieldAccessWithMod {
141    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
142        write!(
143            f,
144            "{}",
145            field_access_with_mod_to_string(&self.mod_name, &self.name, &self.field)
146        )
147    }
148}
149
150pub fn field_access_with_mod_to_string(mod_name: &str, name: &str, field: &str) -> String {
151    format!(
152        "{}{}{}{}{}",
153        mod_name,
154        MOD_SIGN,
155        name,
156        DOT_AKA_FIELD_ACCESS_SIGN,
157        field
158    )
159}