Skip to main content

xidl_parser/typed_ast/
expr.rs

1use serde::{Deserialize, Serialize};
2use xidl_parser_derive::Parser;
3
4use crate::typed_ast::Identifier;
5
6#[derive(Debug, Clone, Parser, Serialize, Deserialize)]
7pub struct ConstExpr(pub OrExpr);
8
9#[derive(Debug, Clone, Parser, Serialize, Deserialize)]
10pub enum OrExpr {
11    XorExpr(XorExpr),
12    OrExpr(Box<OrExpr>, XorExpr),
13}
14
15#[derive(Debug, Clone, Parser, Serialize, Deserialize)]
16pub enum XorExpr {
17    AndExpr(AndExpr),
18    XorExpr(Box<XorExpr>, AndExpr),
19}
20
21#[derive(Debug, Clone, Parser, Serialize, Deserialize)]
22pub enum AndExpr {
23    ShiftExpr(ShiftExpr),
24    AndExpr(Box<AndExpr>, ShiftExpr),
25}
26
27#[derive(Debug, Clone, Parser, Serialize, Deserialize)]
28pub enum ShiftExpr {
29    AddExpr(AddExpr),
30    LeftShiftExpr(Box<ShiftExpr>, AddExpr),
31    RightShiftExpr(Box<ShiftExpr>, AddExpr),
32}
33
34#[derive(Debug, Clone, Parser, Serialize, Deserialize)]
35pub enum AddExpr {
36    MultExpr(MultExpr),
37    AddExpr(Box<AddExpr>, MultExpr),
38    SubExpr(Box<AddExpr>, MultExpr),
39}
40
41#[derive(Debug, Clone, Parser, Serialize, Deserialize)]
42pub enum MultExpr {
43    UnaryExpr(UnaryExpr),
44    MultExpr(Box<MultExpr>, UnaryExpr),
45    DivExpr(Box<MultExpr>, UnaryExpr),
46    ModExpr(Box<MultExpr>, UnaryExpr),
47}
48
49#[derive(Debug, Clone, Parser, Serialize, Deserialize)]
50pub enum UnaryExpr {
51    UnaryExpr(UnaryOperator, PrimaryExpr),
52    PrimaryExpr(PrimaryExpr),
53}
54
55#[derive(Debug, Clone, Parser, Serialize, Deserialize)]
56pub enum PrimaryExpr {
57    ScopedName(ScopedName),
58    Literal(Literal),
59    ConstExpr(Box<ConstExpr>),
60}
61
62#[derive(Debug, Clone, Serialize, Deserialize)]
63pub enum UnaryOperator {
64    Add,
65    Sub,
66    Not,
67}
68
69impl<'a> crate::parser::FromTreeSitter<'a> for UnaryOperator {
70    fn from_node(
71        node: tree_sitter::Node<'a>,
72        ctx: &mut crate::parser::ParseContext<'a>,
73    ) -> crate::error::ParserResult<Self> {
74        #[allow(clippy::never_loop)]
75        for ch in node.children(&mut node.walk()) {
76            return match ctx.node_text(&ch)? {
77                "+" => Ok(Self::Add),
78                "-" => Ok(Self::Sub),
79                "~" => Ok(Self::Not),
80                _ => Err(crate::error::ParseError::UnexpectedNode(format!(
81                    "parent: {}, got: {}",
82                    node.kind(),
83                    ch.kind()
84                ))),
85            };
86        }
87        unreachable!()
88    }
89}
90
91#[derive(Debug, Clone, Parser, Serialize, Deserialize)]
92pub struct ScopedName {
93    #[ts(id = "scoped_name")]
94    pub scoped_name: Option<Box<ScopedName>>,
95    pub identifier: Identifier,
96    #[ts(id = "-", text)]
97    pub node_text: String,
98}
99
100#[derive(Debug, Clone, Parser, Serialize, Deserialize)]
101pub enum Literal {
102    IntegerLiteral(IntegerLiteral),
103    FloatingPtLiteral(FloatingPtLiteral),
104    // FixedPtLiteral,
105    CharLiteral(String),
106    WideCharacterLiteral(String),
107    StringLiteral(String),
108    WideStringLiteral(String),
109    BooleanLiteral(BooleanLiteral),
110}
111
112#[derive(Debug, Clone, Serialize, Deserialize)]
113pub enum BooleanLiteral {
114    True,
115    False,
116}
117
118impl BooleanLiteral {
119    pub fn as_bool(&self) -> bool {
120        matches!(self, Self::True)
121    }
122}
123
124impl<'a> crate::parser::FromTreeSitter<'a> for BooleanLiteral {
125    fn from_node(
126        node: tree_sitter::Node<'a>,
127        ctx: &mut crate::parser::ParseContext<'a>,
128    ) -> crate::error::ParserResult<Self> {
129        match ctx.node_text(&node)?.to_ascii_lowercase().as_str() {
130            "true" => Ok(Self::True),
131            "false" => Ok(Self::False),
132            value => Err(crate::error::ParseError::UnexpectedNode(format!(
133                "parent: {}, got: {}",
134                node.kind(),
135                value
136            ))),
137        }
138    }
139}
140
141#[derive(Debug, Clone, Parser, Serialize, Deserialize)]
142pub enum IntegerLiteral {
143    BinNumber(String),
144    OctNumber(String),
145    DecNumber(String),
146    HexNumber(String),
147}
148
149#[derive(Debug, Clone, Serialize, Deserialize)]
150pub struct FloatingPtLiteral {
151    pub sign: Option<IntegerSign>,
152    pub integer: DecNumber,
153    pub fraction: DecNumber,
154}
155
156impl<'a> crate::parser::FromTreeSitter<'a> for FloatingPtLiteral {
157    fn from_node(
158        node: tree_sitter::Node<'a>,
159        ctx: &mut crate::parser::ParseContext<'a>,
160    ) -> crate::error::ParserResult<Self> {
161        assert_eq!(
162            node.kind_id(),
163            xidl_parser_derive::node_id!("floating_pt_literal")
164        );
165        let mut sign = None;
166        let mut integer = None;
167        let mut fraction = None;
168        for ch in node.children(&mut node.walk()) {
169            match ch.kind_id() {
170                xidl_parser_derive::node_id!("integer_sign") => {
171                    sign = Some(crate::parser::FromTreeSitter::from_node(ch, ctx)?);
172                }
173                xidl_parser_derive::node_id!("dec_number") => {
174                    let inter = crate::parser::FromTreeSitter::from_node(ch, ctx)?;
175                    if integer.is_none() {
176                        integer = Some(inter);
177                    } else {
178                        fraction = Some(inter);
179                    }
180                }
181
182                _ => {}
183            }
184        }
185        Ok(Self {
186            sign,
187            integer: integer.unwrap(),
188            fraction: fraction.unwrap(),
189        })
190    }
191}
192
193#[derive(Debug, Clone, Serialize, Deserialize)]
194pub enum IntegerSign {
195    Plus,
196    Minus,
197}
198
199impl IntegerSign {
200    pub fn as_str(&self) -> &'static str {
201        match self {
202            Self::Plus => "+",
203            Self::Minus => "-",
204        }
205    }
206}
207
208impl<'a> crate::parser::FromTreeSitter<'a> for IntegerSign {
209    fn from_node(
210        node: tree_sitter::Node<'a>,
211        ctx: &mut crate::parser::ParseContext<'a>,
212    ) -> crate::error::ParserResult<Self> {
213        let text = ctx.node_text(&node)?;
214        match text {
215            "+" => Ok(Self::Plus),
216            "-" => Ok(Self::Minus),
217            _ => Err(crate::error::ParseError::UnexpectedNode(format!(
218                "parent: {}, got: {}",
219                node.kind(),
220                text
221            ))),
222        }
223    }
224}
225
226#[derive(Debug, Clone, Parser, Serialize, Deserialize)]
227#[ts(transparent)]
228pub struct DecNumber(pub String);