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