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 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);