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