tergo_parser/
ast.rs

1use tokenizer::tokens::CommentedToken;
2
3use crate::Input;
4
5#[derive(Debug, Clone, PartialEq)]
6pub enum Expression<'a> {
7    Symbol(&'a CommentedToken<'a>),
8    Literal(&'a CommentedToken<'a>),
9    Comment(&'a CommentedToken<'a>),
10    Term(Box<TermExpr<'a>>),
11    Unary(&'a CommentedToken<'a>, Box<Expression<'a>>),
12    Bop(
13        &'a CommentedToken<'a>,
14        Box<Expression<'a>>,
15        Box<Expression<'a>>,
16    ),
17    MultiBop(
18        Box<Expression<'a>>,
19        Vec<(&'a CommentedToken<'a>, Box<Expression<'a>>)>,
20    ),
21    Formula(&'a CommentedToken<'a>, Box<Expression<'a>>),
22    Newline(&'a CommentedToken<'a>),
23    Whitespace(crate::Input<'a, 'a>),
24    EOF(&'a CommentedToken<'a>),
25    FunctionDef(FunctionDefinition<'a>),
26    LambdaFunction(Lambda<'a>),
27    IfExpression(IfExpression<'a>),
28    WhileExpression(WhileExpression<'a>),
29    RepeatExpression(RepeatExpression<'a>),
30    FunctionCall(FunctionCall<'a>),
31    SubsetExpression(SubsetExpression<'a>),
32    ForLoopExpression(ForLoop<'a>),
33    Break(&'a CommentedToken<'a>),
34    Continue(&'a CommentedToken<'a>),
35}
36
37impl std::fmt::Display for Expression<'_> {
38    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
39        match self {
40            Expression::Symbol(token) => f.write_fmt(format_args!("{}", Input(&[token]))),
41            Expression::Literal(token) => f.write_fmt(format_args!("{}", Input(&[token]))),
42            Expression::Comment(token) => f.write_fmt(format_args!("{}", Input(&[token]))),
43            Expression::Term(term) => f.write_fmt(format_args!("{}", term)),
44            Expression::Unary(op, expr) => f.write_fmt(format_args!("{}{}", op, expr)),
45            Expression::Bop(op, left, right) => {
46                f.write_fmt(format_args!("{} {} {}", left, Input(&[op]), right))
47            }
48            Expression::MultiBop(lhs, other) => f.write_fmt(format_args!("{} {:?}", lhs, other)),
49            Expression::Formula(tilde, term) => write!(f, "{} {}", tilde, term),
50            Expression::Newline(token) => f.write_fmt(format_args!("{}", Input(&[token]))),
51            Expression::Whitespace(tokens) => f.write_fmt(format_args!("{}", Input(tokens))),
52            Expression::EOF(token) => f.write_fmt(format_args!("{}", Input(&[token]))),
53            Expression::FunctionDef(func_def) => f.write_fmt(format_args!("{}", func_def)),
54            Expression::IfExpression(if_expression) => {
55                f.write_fmt(format_args!("{}", if_expression))
56            }
57            Expression::WhileExpression(while_expression) => {
58                f.write_fmt(format_args!("{}", while_expression))
59            }
60            Expression::RepeatExpression(repeat_expression) => {
61                f.write_fmt(format_args!("{}", repeat_expression))
62            }
63            Expression::FunctionCall(function_call) => {
64                f.write_fmt(format_args!("{}", function_call))
65            }
66            Expression::SubsetExpression(subset_expression) => {
67                f.write_fmt(format_args!("{}", subset_expression))
68            }
69            Expression::ForLoopExpression(for_loop) => f.write_fmt(format_args!("{}", for_loop)),
70            Expression::Break(token) | Expression::Continue(token) => {
71                f.write_fmt(format_args!("{}", Input(&[token])))
72            }
73            Expression::LambdaFunction(lambda) => f.write_fmt(format_args!("{}", lambda)),
74        }
75    }
76}
77
78#[derive(Debug, Clone, PartialEq)]
79pub struct ExpressionsBuffer<'a>(pub &'a [Expression<'a>]);
80impl std::fmt::Display for ExpressionsBuffer<'_> {
81    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
82        f.write_str("Expressions: [")?;
83        f.write_fmt(format_args!(
84            "{}",
85            self.0
86                .iter()
87                .map(|x| x.to_string())
88                .collect::<Vec<String>>()
89                .join("\n")
90        ))?;
91        f.write_str("]\n")
92    }
93}
94
95// Term
96#[derive(Debug, Clone, PartialEq)]
97pub struct TermExpr<'a> {
98    pub pre_delimiters: Option<&'a CommentedToken<'a>>,
99    pub term: Vec<Expression<'a>>,
100    pub post_delimiters: Option<&'a CommentedToken<'a>>,
101}
102
103impl<'a> TermExpr<'a> {
104    pub fn new(
105        pre_delimiters: Option<&'a CommentedToken<'a>>,
106        term: Vec<Expression<'a>>,
107        post_delimiters: Option<&'a CommentedToken<'a>>,
108    ) -> Self {
109        Self {
110            pre_delimiters,
111            term,
112            post_delimiters,
113        }
114    }
115}
116
117impl<'a> From<Expression<'a>> for TermExpr<'a> {
118    fn from(expr: Expression<'a>) -> Self {
119        Self::new(None, vec![expr], None)
120    }
121}
122
123impl std::fmt::Display for TermExpr<'_> {
124    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
125        f.write_fmt(format_args!(
126            "(TermExpr: {} {} {})",
127            if let Some(pre_delim) = self.pre_delimiters {
128                pre_delim.to_string()
129            } else {
130                "".to_string()
131            },
132            self.term
133                .iter()
134                .map(|e| format!("(expr: {})", e))
135                .collect::<Vec<_>>()
136                .join("\n"),
137            if let Some(post_delim) = self.post_delimiters {
138                post_delim.to_string()
139            } else {
140                "".to_string()
141            },
142        ))
143    }
144}
145
146// Function definition
147// The comma is required due to the way the parser treats comments
148// The formatter needs comments and some of them might end up squeezed into
149// the comma token
150#[derive(Debug, Clone, PartialEq)]
151pub enum Arg<'a> {
152    Proper(Option<Expression<'a>>, Option<Expression<'a>>), // Argument, comma
153    EmptyEqual(
154        Expression<'a>,
155        &'a CommentedToken<'a>,
156        Option<Expression<'a>>,
157    ), // Argument name, equal sign, comma
158}
159
160impl std::fmt::Display for Arg<'_> {
161    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
162        match self {
163            Arg::Proper(xpr, comma) => {
164                if let Some(ref xpr) = xpr {
165                    f.write_fmt(format_args!("{}", xpr))?;
166                }
167                if let Some(comma) = comma {
168                    f.write_fmt(format_args!("comma:{}", comma))?;
169                }
170            }
171            Arg::EmptyEqual(expression, equal, _) => {
172                f.write_fmt(format_args!("{}", expression))?;
173                f.write_fmt(format_args!("equal sign: {}", equal))?;
174            }
175        }
176        Ok(())
177    }
178}
179
180#[derive(Debug, Clone, PartialEq)]
181pub enum Delimiter<'a> {
182    Paren(&'a CommentedToken<'a>),
183    SingleBracket(&'a CommentedToken<'a>),
184    DoubleBracket((&'a CommentedToken<'a>, &'a CommentedToken<'a>)),
185}
186
187impl Delimiter<'_> {
188    pub fn is_inline_commented(&self) -> bool {
189        match self {
190            Delimiter::Paren(commented_token)
191            | Delimiter::SingleBracket(commented_token)
192            | Delimiter::DoubleBracket((_, commented_token)) => {
193                commented_token.inline_comment.is_some()
194            }
195        }
196    }
197}
198
199impl std::fmt::Display for Delimiter<'_> {
200    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
201        match self {
202            Delimiter::Paren(single) | Delimiter::SingleBracket(single) => {
203                f.write_fmt(format_args!("{}", single))
204            }
205            Delimiter::DoubleBracket((b1, b2)) => f.write_fmt(format_args!("{}{}", b1, b2)),
206        }
207    }
208}
209
210#[derive(Debug, Clone, PartialEq)]
211pub struct Args<'a> {
212    pub left_delimeter: Delimiter<'a>,
213    pub args: Vec<Arg<'a>>,
214    pub right_delimeter: Delimiter<'a>,
215}
216
217impl<'a> Args<'a> {
218    pub fn new(
219        left_delimeter: Delimiter<'a>,
220        args: Vec<Arg<'a>>,
221        right_delimeter: Delimiter<'a>,
222    ) -> Self {
223        Self {
224            left_delimeter,
225            args,
226            right_delimeter,
227        }
228    }
229}
230
231impl std::fmt::Display for Args<'_> {
232    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
233        f.write_fmt(format_args!(
234            "(Args: {} {} {})",
235            self.left_delimeter,
236            self.args
237                .iter()
238                .map(|arg| arg.to_string())
239                .collect::<Vec<String>>()
240                .join(" "),
241            self.right_delimeter,
242        ))
243    }
244}
245
246#[derive(Debug, Clone, PartialEq)]
247pub struct FunctionDefinition<'a> {
248    pub keyword: &'a CommentedToken<'a>,
249    pub arguments: Args<'a>,
250    pub body: Box<Expression<'a>>,
251}
252
253impl<'a> FunctionDefinition<'a> {
254    pub fn new(
255        keyword: &'a CommentedToken<'a>,
256        arguments: Args<'a>,
257        body: Box<Expression<'a>>,
258    ) -> Self {
259        Self {
260            keyword,
261            arguments,
262            body,
263        }
264    }
265}
266
267impl std::fmt::Display for FunctionDefinition<'_> {
268    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
269        f.write_fmt(format_args!(
270            "{} {} {}",
271            self.keyword, self.arguments, self.body
272        ))
273    }
274}
275
276// If expression
277#[derive(Debug, Clone, PartialEq)]
278pub struct IfConditional<'a> {
279    pub keyword: &'a CommentedToken<'a>,
280    pub left_delimiter: &'a CommentedToken<'a>,
281    pub condition: Box<Expression<'a>>,
282    pub right_delimiter: &'a CommentedToken<'a>,
283    pub body: Box<Expression<'a>>,
284}
285
286#[derive(Debug, Clone, PartialEq)]
287pub struct ElseIfConditional<'a> {
288    pub else_keyword: &'a CommentedToken<'a>,
289    pub if_conditional: IfConditional<'a>,
290}
291
292#[derive(Debug, Clone, PartialEq)]
293pub struct TrailingElse<'a> {
294    pub else_keyword: &'a CommentedToken<'a>,
295    pub body: Box<Expression<'a>>,
296}
297
298#[derive(Debug, Clone, PartialEq)]
299pub struct IfExpression<'a> {
300    pub if_conditional: IfConditional<'a>,
301    pub else_ifs: Vec<ElseIfConditional<'a>>,
302    pub trailing_else: Option<TrailingElse<'a>>,
303}
304
305impl std::fmt::Display for TrailingElse<'_> {
306    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
307        f.write_fmt(format_args!("{} {}", self.else_keyword, self.body))
308    }
309}
310
311impl std::fmt::Display for IfConditional<'_> {
312    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
313        f.write_fmt(format_args!(
314            "{} {} {} {} {}",
315            self.keyword, self.left_delimiter, self.condition, self.right_delimiter, self.body
316        ))
317    }
318}
319
320impl std::fmt::Display for ElseIfConditional<'_> {
321    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
322        f.write_fmt(format_args!(
323            "{} {}",
324            self.else_keyword, self.if_conditional
325        ))
326    }
327}
328
329impl std::fmt::Display for IfExpression<'_> {
330    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
331        f.write_fmt(format_args!("{} ", self.if_conditional))?;
332        for else_if in &self.else_ifs {
333            f.write_fmt(format_args!("{}", else_if))?;
334        }
335        match &self.trailing_else {
336            Some(trailing_else) => f.write_fmt(format_args!("{}", trailing_else)),
337            None => Ok(()),
338        }
339    }
340}
341
342// While expression
343#[derive(Debug, Clone, PartialEq)]
344pub struct WhileExpression<'a> {
345    pub while_keyword: &'a CommentedToken<'a>,
346    pub condition: Box<Expression<'a>>,
347    pub body: Box<Expression<'a>>,
348}
349
350impl std::fmt::Display for WhileExpression<'_> {
351    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
352        f.write_fmt(format_args!(
353            "({} {} {})",
354            self.while_keyword, self.condition, self.body
355        ))
356    }
357}
358
359// Repeat expresssion
360#[derive(Debug, Clone, PartialEq)]
361pub struct RepeatExpression<'a> {
362    pub repeat_keyword: &'a CommentedToken<'a>,
363    pub body: Box<Expression<'a>>,
364}
365
366impl std::fmt::Display for RepeatExpression<'_> {
367    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
368        f.write_fmt(format_args!("({} {})", self.repeat_keyword, self.body))
369    }
370}
371
372// Function call
373#[derive(Debug, Clone, PartialEq)]
374pub struct FunctionCall<'a> {
375    pub function_ref: Box<Expression<'a>>,
376    pub args: Args<'a>,
377}
378
379impl std::fmt::Display for FunctionCall<'_> {
380    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
381        f.write_fmt(format_args!("Call({} {})", self.function_ref, self.args))
382    }
383}
384
385// Subset expression
386#[derive(Debug, Clone, PartialEq)]
387pub struct SubsetExpression<'a> {
388    pub object_ref: Box<Expression<'a>>,
389    pub args: Args<'a>,
390}
391
392impl std::fmt::Display for SubsetExpression<'_> {
393    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
394        f.write_fmt(format_args!("{}{}", self.object_ref, self.args))
395    }
396}
397
398// For loop
399#[derive(Debug, Clone, PartialEq)]
400pub struct ForLoop<'a> {
401    pub keyword: &'a CommentedToken<'a>,
402    pub left_delim: Delimiter<'a>,
403    pub identifier: Box<Expression<'a>>,
404    pub in_keyword: &'a CommentedToken<'a>,
405    pub collection: Box<Expression<'a>>,
406    pub right_delim: Delimiter<'a>,
407    pub body: Box<Expression<'a>>,
408}
409
410impl std::fmt::Display for ForLoop<'_> {
411    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
412        f.write_fmt(format_args!(
413            "<{} {} {} {} {} {} {}>",
414            self.keyword,
415            self.left_delim,
416            self.identifier,
417            self.in_keyword,
418            self.collection,
419            self.right_delim,
420            self.body
421        ))
422    }
423}
424
425// Lambda
426#[derive(Debug, Clone, PartialEq)]
427pub struct Lambda<'a> {
428    pub keyword: &'a CommentedToken<'a>,
429    pub args: Args<'a>,
430    pub body: Box<Expression<'a>>,
431}
432
433impl std::fmt::Display for Lambda<'_> {
434    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
435        f.write_fmt(format_args!("{} {} {}", self.keyword, self.args, self.body))
436    }
437}