Skip to main content

xidl_parser/hir/
compound.rs

1use super::*;
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Serialize, Deserialize, Clone)]
5pub enum ConstrTypeDcl {
6    StructForwardDcl(StructForwardDcl),
7    StructDcl(StructDcl),
8    EnumDcl(EnumDcl),
9    UnionForwardDcl(UnionForwardDcl),
10    UnionDef(UnionDef),
11    BitsetDcl(BitsetDcl),
12    BitmaskDcl(BitmaskDcl),
13}
14
15#[derive(Debug, Serialize, Deserialize, Clone)]
16pub struct UnionForwardDcl {
17    pub annotations: Vec<Annotation>,
18    pub ident: String,
19}
20
21#[derive(Debug, Serialize, Deserialize, Clone)]
22pub struct UnionDef {
23    pub annotations: Vec<Annotation>,
24    pub ident: String,
25    pub switch_type_spec: SwitchTypeSpec,
26    pub case: Vec<Case>,
27}
28
29#[derive(Debug, Serialize, Deserialize, Clone)]
30pub struct Case {
31    pub label: Vec<CaseLabel>,
32    pub element: ElementSpec,
33}
34
35#[derive(Debug, Serialize, Deserialize, Clone)]
36pub enum CaseLabel {
37    Value(ConstExpr),
38    Default,
39}
40
41#[derive(Debug, Serialize, Deserialize, Clone)]
42pub struct ElementSpec {
43    pub annotations: Vec<Annotation>,
44    pub ty: ElementSpecTy,
45    pub value: Declarator,
46    pub field_id: Option<u32>,
47}
48
49#[derive(Debug, Serialize, Deserialize, Clone)]
50pub enum ElementSpecTy {
51    TypeSpec(TypeSpec),
52    ConstrTypeDcl(ConstrTypeDcl),
53}
54
55#[derive(Debug, Serialize, Deserialize, Clone)]
56pub enum SwitchTypeSpec {
57    IntegerType(IntegerType),
58    CharType,
59    WideCharType,
60    BooleanType,
61    ScopedName(ScopedName),
62    OctetType,
63}
64
65#[derive(Debug, Serialize, Deserialize, Clone)]
66pub struct BitsetDcl {
67    pub annotations: Vec<Annotation>,
68    pub ident: String,
69    pub parent: Option<ScopedName>,
70    pub field: Vec<BitField>,
71}
72
73#[derive(Clone, Debug, Serialize, Deserialize)]
74pub enum BitFieldType {
75    Bool,
76    Octec,
77    SignedInt,
78    UnsignedInt,
79}
80
81#[derive(Debug, Serialize, Deserialize, Clone)]
82pub struct BitField {
83    pub ident: String,
84    pub pos: PositiveIntConst,
85    pub ty: Option<BitFieldType>,
86}
87
88#[derive(Debug, Serialize, Deserialize, Clone)]
89pub struct BitmaskDcl {
90    pub annotations: Vec<Annotation>,
91    pub ident: String,
92    pub value: Vec<BitValue>,
93}
94
95#[derive(Debug, Serialize, Deserialize, Clone)]
96pub struct BitValue {
97    pub position: usize,
98    pub annotations: Vec<Annotation>,
99    pub ident: String,
100}
101
102impl UnionDef {
103    pub fn serialize_kind(&self, config: &SerializeConfig) -> SerializeKind {
104        config.resolve_for_annotations(&self.annotations)
105    }
106}
107
108impl BitsetDcl {
109    pub fn serialize_kind(&self, config: &SerializeConfig) -> SerializeKind {
110        config.resolve_for_annotations(&self.annotations)
111    }
112}
113
114impl BitmaskDcl {
115    pub fn serialize_kind(&self, config: &SerializeConfig) -> SerializeKind {
116        config.resolve_for_annotations(&self.annotations)
117    }
118}
119
120impl From<crate::typed_ast::ConstrTypeDcl> for ConstrTypeDcl {
121    fn from(value: crate::typed_ast::ConstrTypeDcl) -> Self {
122        match value {
123            crate::typed_ast::ConstrTypeDcl::StructDcl(value) => value.into(),
124            crate::typed_ast::ConstrTypeDcl::UnionDcl(value) => value.into(),
125            crate::typed_ast::ConstrTypeDcl::EnumDcl(value) => Self::EnumDcl(value.into()),
126            crate::typed_ast::ConstrTypeDcl::BitsetDcl(value) => Self::BitsetDcl(value.into()),
127            crate::typed_ast::ConstrTypeDcl::BitmaskDcl(value) => Self::BitmaskDcl(value.into()),
128        }
129    }
130}
131
132impl From<crate::typed_ast::StructDcl> for ConstrTypeDcl {
133    fn from(value: crate::typed_ast::StructDcl) -> Self {
134        match value {
135            crate::typed_ast::StructDcl::StructForwardDcl(value) => {
136                Self::StructForwardDcl(value.into())
137            }
138            crate::typed_ast::StructDcl::StructDef(value) => Self::StructDcl(value.into()),
139        }
140    }
141}
142
143impl From<crate::typed_ast::UnionDcl> for ConstrTypeDcl {
144    fn from(value: crate::typed_ast::UnionDcl) -> Self {
145        match value {
146            crate::typed_ast::UnionDcl::UnionForwardDcl(value) => {
147                Self::UnionForwardDcl(value.into())
148            }
149            crate::typed_ast::UnionDcl::UnionDef(value) => Self::UnionDef(value.into()),
150        }
151    }
152}
153
154impl From<crate::typed_ast::UnionForwardDcl> for UnionForwardDcl {
155    fn from(value: crate::typed_ast::UnionForwardDcl) -> Self {
156        Self {
157            annotations: vec![],
158            ident: value.0.0,
159        }
160    }
161}
162
163impl From<crate::typed_ast::UnionDef> for UnionDef {
164    fn from(value: crate::typed_ast::UnionDef) -> Self {
165        let mut cases = value
166            .case
167            .into_iter()
168            .map(Case::from)
169            .collect::<Vec<Case>>();
170        let mut member_ids = std::collections::HashMap::new();
171        let mut next_field_id = 1u32;
172
173        for case in &mut cases {
174            let name = declarator_name(&case.element.value).to_string();
175            if let Some(id) = case.element.field_id {
176                let entry = member_ids.entry(name.clone()).or_insert(id);
177                case.element.field_id = Some(*entry);
178            } else if let Some(existing) = member_ids.get(&name) {
179                case.element.field_id = Some(*existing);
180            } else {
181                member_ids.insert(name, next_field_id);
182                case.element.field_id = Some(next_field_id);
183                next_field_id += 1;
184            }
185        }
186
187        Self {
188            annotations: vec![],
189            ident: value.ident.0,
190            switch_type_spec: value.switch_type_spec.into(),
191            case: cases,
192        }
193    }
194}
195
196impl From<crate::typed_ast::Case> for Case {
197    fn from(value: crate::typed_ast::Case) -> Self {
198        Self {
199            label: value.label.into_iter().map(Into::into).collect(),
200            element: value.element.into(),
201        }
202    }
203}
204
205impl From<crate::typed_ast::CaseLabel> for CaseLabel {
206    fn from(value: crate::typed_ast::CaseLabel) -> Self {
207        match value {
208            crate::typed_ast::CaseLabel::Case(value) => Self::Value(value.into()),
209            crate::typed_ast::CaseLabel::Default => Self::Default,
210        }
211    }
212}
213
214impl From<crate::typed_ast::ElementSpec> for ElementSpec {
215    fn from(value: crate::typed_ast::ElementSpec) -> Self {
216        let annotations = expand_annotations(value.annotations);
217        Self {
218            field_id: annotation_id_value(&annotations),
219            annotations,
220            ty: value.ty.into(),
221            value: value.value.into(),
222        }
223    }
224}
225
226impl From<crate::typed_ast::ElementSpecTy> for ElementSpecTy {
227    fn from(value: crate::typed_ast::ElementSpecTy) -> Self {
228        match value {
229            crate::typed_ast::ElementSpecTy::TypeSpec(value) => Self::TypeSpec(value.into()),
230            crate::typed_ast::ElementSpecTy::ConstrTypeDcl(value) => {
231                Self::ConstrTypeDcl(value.into())
232            }
233        }
234    }
235}
236
237impl From<crate::typed_ast::SwitchTypeSpec> for SwitchTypeSpec {
238    fn from(value: crate::typed_ast::SwitchTypeSpec) -> Self {
239        match value {
240            crate::typed_ast::SwitchTypeSpec::IntegerType(value) => Self::IntegerType(value.into()),
241            crate::typed_ast::SwitchTypeSpec::CharType(_) => Self::CharType,
242            crate::typed_ast::SwitchTypeSpec::WideCharType(_) => Self::WideCharType,
243            crate::typed_ast::SwitchTypeSpec::BooleanType(_) => Self::BooleanType,
244            crate::typed_ast::SwitchTypeSpec::ScopedName(value) => Self::ScopedName(value.into()),
245            crate::typed_ast::SwitchTypeSpec::OctetType(_) => Self::OctetType,
246        }
247    }
248}
249
250impl From<crate::typed_ast::BitsetDcl> for BitsetDcl {
251    fn from(value: crate::typed_ast::BitsetDcl) -> Self {
252        let mut field = Vec::new();
253        for bitfield in value.field {
254            let pos = bitfield.spec.pos;
255            let ty = bitfield.spec.dst_ty.map(Into::into);
256            for ident in bitfield.ident {
257                field.push(BitField {
258                    ident: ident.0,
259                    pos: pos.clone().into(),
260                    ty: ty.clone(),
261                });
262            }
263        }
264
265        Self {
266            annotations: vec![],
267            ident: value.ident.0,
268            parent: value.parent.map(Into::into),
269            field,
270        }
271    }
272}
273
274impl From<crate::typed_ast::DestinationType> for BitFieldType {
275    fn from(value: crate::typed_ast::DestinationType) -> Self {
276        match value {
277            crate::typed_ast::DestinationType::BooleanType(_) => Self::Bool,
278            crate::typed_ast::DestinationType::OctetType(_) => Self::Octec,
279            crate::typed_ast::DestinationType::IntegerType(value) => {
280                if matches!(value, crate::typed_ast::IntegerType::SignedInt(_)) {
281                    Self::SignedInt
282                } else {
283                    Self::UnsignedInt
284                }
285            }
286        }
287    }
288}
289
290impl From<crate::typed_ast::BitmaskDcl> for BitmaskDcl {
291    fn from(value: crate::typed_ast::BitmaskDcl) -> Self {
292        let mut bits = vec![];
293        for (idx, bitvalue) in value.value.into_iter().enumerate() {
294            let mut position = idx;
295            for annotation in &bitvalue.annotations {
296                let crate::typed_ast::AnnotationName::Builtin(name) = &annotation.name else {
297                    continue;
298                };
299                if !name.eq_ignore_ascii_case("position") {
300                    continue;
301                }
302
303                let Some(crate::typed_ast::AnnotationParams::Raw(v)) = &annotation.params else {
304                    continue;
305                };
306
307                if let Ok(v) = v.parse::<usize>() {
308                    position = v;
309                }
310            }
311            let mut bit: BitValue = bitvalue.into();
312            bit.position = position;
313            bits.push(bit);
314        }
315        Self {
316            annotations: vec![],
317            ident: value.ident.0,
318            value: bits,
319        }
320    }
321}
322
323impl From<crate::typed_ast::BitValue> for BitValue {
324    fn from(value: crate::typed_ast::BitValue) -> Self {
325        Self {
326            position: 0,
327            annotations: expand_annotations(value.annotations),
328            ident: value.ident.0,
329        }
330    }
331}
332
333fn declarator_name(value: &Declarator) -> &str {
334    match value {
335        Declarator::SimpleDeclarator(value) => &value.0,
336        Declarator::ArrayDeclarator(value) => &value.ident,
337    }
338}