zen_expression/parser/
parser.rs

1use bumpalo::collections::Vec as BumpVec;
2use bumpalo::Bump;
3use nohash_hasher::BuildNoHashHasher;
4use rust_decimal::Decimal;
5use std::cell::{Cell, RefCell};
6use std::collections::HashMap;
7use std::fmt::Debug;
8use std::marker::PhantomData;
9use std::ops::Deref;
10
11use crate::lexer::{
12    Bracket, ComparisonOperator, Identifier, Operator, QuotationMark, TemplateString, Token,
13    TokenKind,
14};
15use crate::parser::ast::{AstNodeError, Node};
16use crate::parser::builtin::{Arity, BuiltInFunction};
17use crate::parser::error::ParserError;
18use crate::parser::standard::Standard;
19use crate::parser::unary::Unary;
20use crate::parser::NodeMetadata;
21
22macro_rules! expect {
23    ($self:ident, $token:expr) => {
24        if let Some(error_node) = $self.expect($token) {
25            return error_node;
26        }
27    };
28}
29macro_rules! afmt {
30    ($self:expr, $($arg:tt)*) => {{
31        let formatted = format!($($arg)*);
32        $self.bump.alloc_str(formatted.as_str())
33    }}
34}
35
36#[derive(Debug)]
37pub struct BaseParser;
38
39#[derive(Debug)]
40pub struct Parser<'arena, 'token_ref, Flavor> {
41    tokens: &'token_ref [Token<'arena>],
42    current: Cell<Option<&'token_ref Token<'arena>>>,
43    pub(crate) bump: &'arena Bump,
44    position: Cell<usize>,
45    depth: Cell<u8>,
46    marker_flavor: PhantomData<Flavor>,
47    has_range_operator: bool,
48    pub(crate) node_metadata:
49        Option<RefCell<HashMap<usize, NodeMetadata, BuildNoHashHasher<usize>>>>,
50}
51
52impl<'arena, 'token_ref> Parser<'arena, 'token_ref, BaseParser> {
53    pub fn try_new(
54        tokens: &'token_ref [Token<'arena>],
55        bump: &'arena Bump,
56    ) -> Result<Self, ParserError> {
57        let current = tokens.get(0);
58        let has_range_operator = tokens
59            .iter()
60            .any(|t| t.kind == TokenKind::Operator(Operator::Range));
61
62        Ok(Self {
63            tokens,
64            bump,
65            current: Cell::new(current),
66            depth: Cell::new(0),
67            position: Cell::new(0),
68            has_range_operator,
69            node_metadata: None,
70            marker_flavor: PhantomData,
71        })
72    }
73
74    pub fn standard(self) -> Parser<'arena, 'token_ref, Standard> {
75        Parser {
76            tokens: self.tokens,
77            bump: self.bump,
78            current: self.current,
79            depth: self.depth,
80            position: self.position,
81            has_range_operator: self.has_range_operator,
82            node_metadata: self.node_metadata,
83            marker_flavor: PhantomData,
84        }
85    }
86
87    pub fn unary(self) -> Parser<'arena, 'token_ref, Unary> {
88        Parser {
89            tokens: self.tokens,
90            bump: self.bump,
91            current: self.current,
92            depth: self.depth,
93            position: self.position,
94            has_range_operator: self.has_range_operator,
95            node_metadata: self.node_metadata,
96            marker_flavor: PhantomData,
97        }
98    }
99}
100
101impl<'arena, 'token_ref, Flavor> Parser<'arena, 'token_ref, Flavor> {
102    pub fn with_metadata(mut self) -> Parser<'arena, 'token_ref, Flavor> {
103        self.node_metadata = Some(Default::default());
104        self
105    }
106
107    pub(crate) fn current(&self) -> Option<&Token<'arena>> {
108        self.current.get()
109    }
110
111    pub(crate) fn current_kind(&self) -> Option<&TokenKind> {
112        self.current.get().map(|token| &token.kind)
113    }
114
115    fn token_start(&self) -> u32 {
116        match self.current() {
117            None => self.tokens.last().map(|t| t.span.1).unwrap_or_default(),
118            Some(t) => t.span.0,
119        }
120    }
121
122    #[allow(dead_code)]
123    fn token_end(&self) -> u32 {
124        match self.current() {
125            None => self.tokens.last().map(|t| t.span.1).unwrap_or_default(),
126            Some(t) => t.span.1,
127        }
128    }
129
130    pub(crate) fn prev_token_end(&self) -> u32 {
131        let Some(pos) = self.position().checked_sub(1) else {
132            return self.token_start();
133        };
134
135        match self.tokens.get(pos) {
136            None => self.token_start(),
137            Some(t) => t.span.1,
138        }
139    }
140
141    fn position(&self) -> usize {
142        self.position.get()
143    }
144
145    fn set_position(&self, position: usize) -> bool {
146        let target_token = self.tokens.get(position);
147
148        self.position.set(position);
149        self.current.set(target_token);
150
151        target_token.is_some()
152    }
153
154    pub(crate) fn depth(&self) -> u8 {
155        self.depth.get()
156    }
157
158    pub(crate) fn is_done(&self) -> bool {
159        self.current.get().is_none()
160    }
161
162    pub(crate) fn node<F>(&self, node: Node<'arena>, gen_metadata: F) -> &'arena Node<'arena>
163    where
164        F: FnOnce(MetadataHelper<'_, 'arena>) -> NodeMetadata,
165    {
166        let node = self.bump.alloc(node);
167        if let Some(node_metadata) = &self.node_metadata {
168            let metadata = {
169                let nm = node_metadata.borrow();
170                gen_metadata(MetadataHelper {
171                    node_metadata: nm.deref(),
172                    arena: PhantomData::<&'arena ()>,
173                })
174            };
175
176            let mut nm = node_metadata.borrow_mut();
177            nm.insert(node as *const Node as usize, metadata);
178        };
179
180        node
181    }
182
183    pub(crate) fn error(&self, error: AstNodeError<'arena>) -> &'arena Node<'arena> {
184        self.node(Node::Error { error, node: None }, |_| NodeMetadata {
185            span: (self.prev_token_end(), self.prev_token_end()),
186        })
187    }
188
189    pub(crate) fn error_with_node(
190        &self,
191        error: AstNodeError<'arena>,
192        node: &'arena Node<'arena>,
193    ) -> &'arena Node<'arena> {
194        self.node(
195            Node::Error {
196                error,
197                node: Some(node),
198            },
199            |_| NodeMetadata { span: (0, 0) },
200        )
201    }
202
203    pub(crate) fn next(&self) {
204        let new_position = self.position.get() + 1;
205
206        self.position.set(new_position);
207        self.current.set(self.tokens.get(new_position));
208    }
209
210    pub(crate) fn expect(&self, kind: TokenKind) -> Option<&'arena Node<'arena>> {
211        let token = self.current();
212        if token.is_some_and(|t| t.kind == kind) {
213            self.next();
214            return None;
215        }
216
217        Some(
218            self.error(AstNodeError::UnexpectedToken {
219                expected: afmt!(self, "{kind}"),
220                received: token
221                    .map(|t| afmt!(self, "{}", t.kind))
222                    .unwrap_or_else(|| afmt!(self, "None")),
223                span: token.map(|t| t.span).unwrap_or((0, 0)),
224            }),
225        )
226    }
227
228    pub(crate) fn number(&self) -> &'arena Node<'arena> {
229        let Some(token) = self.current() else {
230            return self.error(AstNodeError::MissingToken {
231                expected: afmt!(self, "Number"),
232                position: self.position(),
233            });
234        };
235
236        let Ok(decimal) = Decimal::from_str_exact(token.value) else {
237            return self.error(AstNodeError::InvalidNumber {
238                number: afmt!(self, "{}", token.value),
239                span: token.span,
240            });
241        };
242
243        self.next();
244        self.node(Node::Number(decimal), |_| NodeMetadata { span: token.span })
245    }
246
247    pub(crate) fn bool(&self) -> &'arena Node<'arena> {
248        let Some(token) = self.current() else {
249            return self.error(AstNodeError::MissingToken {
250                expected: afmt!(self, "Boolean"),
251                position: self.position(),
252            });
253        };
254
255        let TokenKind::Boolean(boolean) = token.kind else {
256            return self.error(AstNodeError::InvalidBoolean {
257                boolean: afmt!(self, "{}", token.value),
258                span: token.span,
259            });
260        };
261
262        self.next();
263        self.node(Node::Bool(boolean), |_| NodeMetadata { span: token.span })
264    }
265
266    pub(crate) fn null(&self) -> &'arena Node<'arena> {
267        let Some(token) = self.current() else {
268            return self.error(AstNodeError::MissingToken {
269                expected: afmt!(self, "Null"),
270                position: self.position(),
271            });
272        };
273
274        if token.kind != TokenKind::Identifier(Identifier::Null) {
275            return self.error(AstNodeError::UnexpectedIdentifier {
276                expected: afmt!(self, "Null"),
277                received: afmt!(self, "{}", token.value),
278                span: token.span,
279            });
280        }
281
282        self.next();
283        self.node(Node::Null, |_| NodeMetadata { span: token.span })
284    }
285
286    pub(crate) fn simple_string(&self, quote_mark: &QuotationMark) -> &'arena Node<'arena> {
287        expect!(self, TokenKind::QuotationMark(quote_mark.clone()));
288        let string_value = self.current();
289
290        let error_literal = self.expect(TokenKind::Literal);
291        let error_mark_end = self.expect(TokenKind::QuotationMark(quote_mark.clone()));
292
293        error_literal
294            .or(error_mark_end)
295            .or(string_value.map(|t| {
296                self.node(Node::String(t.value), |_| NodeMetadata {
297                    span: (t.span.0 - 1, t.span.1 + 1),
298                })
299            }))
300            .unwrap_or_else(|| {
301                self.error(AstNodeError::Custom {
302                    message: afmt!(
303                        self,
304                        "Failed to parse string `{}`",
305                        string_value.map(|s| s.value).unwrap_or_default()
306                    ),
307                    span: string_value
308                        .map(|s| s.span)
309                        .unwrap_or((self.prev_token_end(), self.prev_token_end())),
310                })
311            })
312    }
313
314    pub(crate) fn template_string<F>(&self, expression_parser: F) -> &'arena Node<'arena>
315    where
316        F: Fn(ParserContext) -> &'arena Node<'arena>,
317    {
318        expect!(self, TokenKind::QuotationMark(QuotationMark::Backtick));
319
320        let Some(mut current_token) = self.current() else {
321            return self.error(AstNodeError::MissingToken {
322                expected: afmt!(self, "Backtick (`)"),
323                position: self.position(),
324            });
325        };
326
327        let mut span = (current_token.span.0 - 1, 0u32);
328
329        let mut nodes = BumpVec::new_in(self.bump);
330        while TokenKind::QuotationMark(QuotationMark::Backtick) != current_token.kind {
331            match current_token.kind {
332                TokenKind::TemplateString(template) => match template {
333                    TemplateString::ExpressionStart => {
334                        self.next();
335                        nodes.push(expression_parser(ParserContext::Global));
336                    }
337                    TemplateString::ExpressionEnd => {
338                        self.next();
339                    }
340                },
341                TokenKind::Literal => {
342                    nodes.push(
343                        self.node(Node::String(current_token.value), |_| NodeMetadata {
344                            span: current_token.span,
345                        }),
346                    );
347                    self.next();
348                }
349                _ => {
350                    return self.error(AstNodeError::UnexpectedToken {
351                        expected: afmt!(self, "Valid TemplateString token"),
352                        received: afmt!(self, "{}", current_token.kind),
353                        span: current_token.span,
354                    })
355                }
356            }
357
358            if let Some(ct) = self.current() {
359                current_token = ct;
360                span.1 = ct.span.1;
361            } else {
362                break;
363            }
364        }
365
366        expect!(self, TokenKind::QuotationMark(QuotationMark::Backtick));
367        self.node(Node::TemplateString(nodes.into_bump_slice()), |_| {
368            NodeMetadata { span }
369        })
370    }
371
372    pub(crate) fn with_postfix<F>(
373        &self,
374        node: &'arena Node<'arena>,
375        expression_parser: F,
376    ) -> &'arena Node<'arena>
377    where
378        F: Fn(ParserContext) -> &'arena Node<'arena>,
379    {
380        let Some(postfix_token) = self.current() else {
381            return node;
382        };
383
384        let postfix_kind = PostfixKind::from(postfix_token);
385
386        let processed_token = match postfix_kind {
387            PostfixKind::Other => return node,
388            PostfixKind::MemberAccess => {
389                self.next();
390                let property_token = self.current();
391                self.next();
392
393                let property = match property_token {
394                    None => self.error_with_node(
395                        AstNodeError::Custom {
396                            message: afmt!(self, "Expected a property"),
397                            span: (self.prev_token_end(), self.prev_token_end()),
398                        },
399                        node,
400                    ),
401                    Some(t) => match is_valid_property(t) {
402                        true => self.node(Node::String(t.value), |_| NodeMetadata { span: t.span }),
403                        false => self.error_with_node(
404                            AstNodeError::InvalidProperty {
405                                property: afmt!(self, "{}", t.value),
406                                span: t.span,
407                            },
408                            node,
409                        ),
410                    },
411                };
412
413                self.node(Node::Member { node, property }, |h| NodeMetadata {
414                    span: h.span(node, property).unwrap_or_default(),
415                })
416            }
417            PostfixKind::PropertyAccess => {
418                self.next();
419                let mut from: Option<&'arena Node<'arena>> = None;
420                let mut to: Option<&'arena Node<'arena>> = None;
421
422                let Some(mut c) = self.current() else {
423                    return self.error_with_node(
424                        AstNodeError::Custom {
425                            message: afmt!(self, "Expected a property"),
426                            span: (self.prev_token_end(), self.prev_token_end()),
427                        },
428                        node,
429                    );
430                };
431
432                if c.kind == TokenKind::Operator(Operator::Slice) {
433                    self.next();
434
435                    let Some(cc) = self.current() else {
436                        return self.error_with_node(
437                            AstNodeError::Custom {
438                                message: afmt!(self, "Unexpected token"),
439                                span: (self.prev_token_end(), self.prev_token_end()),
440                            },
441                            node,
442                        );
443                    };
444                    c = cc;
445
446                    if c.kind != TokenKind::Bracket(Bracket::RightSquareBracket) {
447                        to = Some(expression_parser(ParserContext::Global));
448                    }
449
450                    expect!(self, TokenKind::Bracket(Bracket::RightSquareBracket));
451                    self.node(Node::Slice { node, to, from }, |h| NodeMetadata {
452                        span: (
453                            h.metadata(node).map(|m| m.span.0).unwrap_or_default(),
454                            self.prev_token_end(),
455                        ),
456                    })
457                } else {
458                    let from_node = expression_parser(ParserContext::Global);
459                    from = Some(from_node);
460                    let Some(cc) = self.current() else {
461                        return self.error_with_node(
462                            AstNodeError::Custom {
463                                message: afmt!(self, "Unexpected token"),
464                                span: (self.prev_token_end(), self.prev_token_end()),
465                            },
466                            self.node(
467                                Node::Member {
468                                    node,
469                                    property: from_node,
470                                },
471                                |h| NodeMetadata {
472                                    span: h.span(node, from_node).unwrap_or_default(),
473                                },
474                            ),
475                        );
476                    };
477                    c = cc;
478
479                    if c.kind == TokenKind::Operator(Operator::Slice) {
480                        self.next();
481                        let Some(cc) = self.current() else {
482                            return self.error_with_node(
483                                AstNodeError::Custom {
484                                    message: afmt!(self, "Invalid slice syntax"),
485                                    span: (self.prev_token_end(), self.prev_token_end()),
486                                },
487                                self.node(Node::Slice { node, from, to }, |h| NodeMetadata {
488                                    span: h.span(node, from_node).unwrap_or_default(),
489                                }),
490                            );
491                        };
492                        c = cc;
493
494                        if c.kind != TokenKind::Bracket(Bracket::RightSquareBracket) {
495                            to = Some(expression_parser(ParserContext::Global));
496                        }
497
498                        expect!(self, TokenKind::Bracket(Bracket::RightSquareBracket));
499                        self.node(Node::Slice { node, from, to }, |h| NodeMetadata {
500                            span: (
501                                h.metadata(node).map(|m| m.span.0).unwrap_or_default(),
502                                self.prev_token_end(),
503                            ),
504                        })
505                    } else {
506                        // Slice operator [:] was not found,
507                        // it should be just an index node.
508                        expect!(self, TokenKind::Bracket(Bracket::RightSquareBracket));
509                        self.node(
510                            Node::Member {
511                                node,
512                                property: from.unwrap_or_else(|| {
513                                    return self.error_with_node(
514                                        AstNodeError::Custom {
515                                            message: afmt!(self, "Invalid index property"),
516                                            span: (self.prev_token_end(), self.prev_token_end()),
517                                        },
518                                        node,
519                                    );
520                                }),
521                            },
522                            |h| NodeMetadata {
523                                span: (
524                                    h.metadata(node).map(|m| m.span.0).unwrap_or_default(),
525                                    self.prev_token_end(),
526                                ),
527                            },
528                        )
529                    }
530                }
531            }
532        };
533
534        self.with_postfix(processed_token, expression_parser)
535    }
536
537    /// Closure
538    pub(crate) fn closure<F>(&self, expression_parser: F) -> &'arena Node<'arena>
539    where
540        F: Fn(ParserContext) -> &'arena Node<'arena>,
541    {
542        let start = self.token_start();
543
544        self.depth.set(self.depth.get() + 1);
545        let node = expression_parser(ParserContext::Closure);
546        self.depth.set(self.depth.get() - 1);
547
548        self.node(Node::Closure(node), |_| NodeMetadata {
549            span: (start, self.prev_token_end()),
550        })
551    }
552
553    /// Identifier expression
554    /// Either <Identifier> or <Identifier Expression>
555    pub(crate) fn identifier<F>(&self, expression_parser: F) -> &'arena Node<'arena>
556    where
557        F: Fn(ParserContext) -> &'arena Node<'arena>,
558    {
559        let Some(token) = self.current() else {
560            return self.error(AstNodeError::MissingToken {
561                expected: afmt!(self, "Identifier"),
562                position: self.position(),
563            });
564        };
565
566        match token.kind {
567            TokenKind::Identifier(_) | TokenKind::Literal => {
568                // ok
569            }
570            _ => {
571                return self.error(AstNodeError::Custom {
572                    message: afmt!(self, "Expected an `identifier`, received `{}`.", token.kind),
573                    span: token.span,
574                });
575            }
576        }
577
578        let Some(identifier_token) = self.current() else {
579            return self.error(AstNodeError::Custom {
580                message: afmt!(self, "Expected an `identifier`."),
581                span: (self.prev_token_end(), self.prev_token_end()),
582            });
583        };
584        self.next();
585
586        let current_token = self.current();
587        if current_token.map(|t| t.kind) != Some(TokenKind::Bracket(Bracket::LeftParenthesis)) {
588            let identifier_node = match identifier_token.kind {
589                TokenKind::Identifier(Identifier::RootReference) => {
590                    self.node(Node::Root, |_| NodeMetadata {
591                        span: identifier_token.span,
592                    })
593                }
594                _ => self.node(Node::Identifier(identifier_token.value), |_| NodeMetadata {
595                    span: identifier_token.span,
596                }),
597            };
598
599            return self.with_postfix(identifier_node, expression_parser);
600        }
601
602        // Potentially it might be a built-in expression
603        let Ok(builtin) = BuiltInFunction::try_from(identifier_token.value) else {
604            return self.error(AstNodeError::UnknownBuiltIn {
605                name: afmt!(self, "{}", identifier_token.value),
606                span: identifier_token.span,
607            });
608        };
609
610        self.next();
611        let builtin_node = match builtin.arity() {
612            Arity::Single => {
613                let arg = expression_parser(ParserContext::Global);
614                self.expect(TokenKind::Bracket(Bracket::RightParenthesis));
615
616                Node::BuiltIn {
617                    kind: builtin,
618                    arguments: self.bump.alloc_slice_copy(&[arg]),
619                }
620            }
621            Arity::Dual => {
622                let arg1 = expression_parser(ParserContext::Global);
623                self.expect(TokenKind::Operator(Operator::Comma));
624                let arg2 = expression_parser(ParserContext::Global);
625                self.expect(TokenKind::Bracket(Bracket::RightParenthesis));
626
627                Node::BuiltIn {
628                    kind: builtin,
629                    arguments: self.bump.alloc_slice_copy(&[arg1, arg2]),
630                }
631            }
632            Arity::Closure => {
633                let arg1 = expression_parser(ParserContext::Global);
634
635                self.expect(TokenKind::Operator(Operator::Comma));
636                let arg2 = self.closure(&expression_parser);
637                self.expect(TokenKind::Bracket(Bracket::RightParenthesis));
638
639                Node::BuiltIn {
640                    kind: builtin,
641                    arguments: self.bump.alloc_slice_copy(&[arg1, arg2]),
642                }
643            }
644        };
645
646        self.with_postfix(
647            self.node(builtin_node, |_| NodeMetadata {
648                span: (identifier_token.span.0, self.prev_token_end()),
649            }),
650            expression_parser,
651        )
652    }
653
654    /// Interval node
655    pub(crate) fn interval<F>(&self, expression_parser: F) -> Option<&'arena Node<'arena>>
656    where
657        F: Fn(ParserContext) -> &'arena Node<'arena>,
658    {
659        // Performance optimisation: skip if expression does not contain an interval for faster evaluation
660        if !self.has_range_operator {
661            return None;
662        }
663
664        let TokenKind::Bracket(_) = &self.current()?.kind else {
665            return None;
666        };
667
668        let initial_position = self.position();
669        let TokenKind::Bracket(left_bracket) = &self.current()?.kind else {
670            self.set_position(initial_position);
671            return None;
672        };
673
674        self.next();
675        let left = expression_parser(ParserContext::Global);
676        if left.has_error() {
677            self.set_position(initial_position);
678            return None;
679        };
680
681        if let Some(_) = self.expect(TokenKind::Operator(Operator::Range)) {
682            self.set_position(initial_position);
683            return None;
684        };
685
686        let right = expression_parser(ParserContext::Global);
687        if right.has_error() {
688            self.set_position(initial_position);
689            return None;
690        };
691
692        let TokenKind::Bracket(right_bracket) = &self.current()?.kind else {
693            self.set_position(initial_position);
694            return None;
695        };
696
697        self.next();
698
699        let interval_node = self.node(
700            Node::Interval {
701                left,
702                right,
703                left_bracket: *left_bracket,
704                right_bracket: *right_bracket,
705            },
706            |_| NodeMetadata {
707                span: (initial_position as u32, self.position() as u32),
708            },
709        );
710
711        Some(self.with_postfix(interval_node, expression_parser))
712    }
713
714    /// Array nodes
715    pub(crate) fn array<F>(&self, expression_parser: F) -> &'arena Node<'arena>
716    where
717        F: Fn(ParserContext) -> &'arena Node<'arena>,
718    {
719        let Some(current_token) = self.current() else {
720            return self.error(AstNodeError::MissingToken {
721                expected: afmt!(self, "Array"),
722                position: self.position(),
723            });
724        };
725
726        if current_token.kind != TokenKind::Bracket(Bracket::LeftSquareBracket) {
727            return self.error(AstNodeError::UnexpectedToken {
728                expected: afmt!(self, "{}", TokenKind::Bracket(Bracket::LeftSquareBracket)),
729                received: afmt!(self, "{}", current_token.kind),
730                span: current_token.span,
731            });
732        }
733
734        self.next();
735        let mut nodes = BumpVec::new_in(self.bump);
736        while !(self.current().map(|t| t.kind)
737            == Some(TokenKind::Bracket(Bracket::RightSquareBracket)))
738        {
739            if !nodes.is_empty() {
740                expect!(self, TokenKind::Operator(Operator::Comma));
741                if self.current().map(|t| t.kind)
742                    == Some(TokenKind::Bracket(Bracket::RightSquareBracket))
743                {
744                    break;
745                }
746            }
747
748            nodes.push(expression_parser(ParserContext::Global));
749        }
750
751        expect!(self, TokenKind::Bracket(Bracket::RightSquareBracket));
752
753        let node = Node::Array(nodes.into_bump_slice());
754
755        self.with_postfix(
756            self.node(node, |_| NodeMetadata {
757                span: (current_token.span.0, self.prev_token_end()),
758            }),
759            expression_parser,
760        )
761    }
762
763    pub(crate) fn object<F>(&self, expression_parser: F) -> &'arena Node<'arena>
764    where
765        F: Fn(ParserContext) -> &'arena Node<'arena>,
766    {
767        let span_start = self.token_start();
768        expect!(self, TokenKind::Bracket(Bracket::LeftCurlyBracket));
769
770        let mut key_value_pairs = BumpVec::new_in(self.bump);
771        if let Some(TokenKind::Bracket(Bracket::RightCurlyBracket)) = self.current().map(|t| t.kind)
772        {
773            self.next();
774            return self.node(Node::Object(key_value_pairs.into_bump_slice()), |_| {
775                NodeMetadata {
776                    span: (span_start, self.prev_token_end()),
777                }
778            });
779        }
780
781        loop {
782            let key = self.object_key(&expression_parser);
783            expect!(self, TokenKind::Operator(Operator::Slice));
784            let value = expression_parser(ParserContext::Global);
785
786            key_value_pairs.push((key, value));
787
788            let Some(current_token) = self.current() else {
789                break;
790            };
791
792            match current_token.kind {
793                TokenKind::Operator(Operator::Comma) => {
794                    expect!(self, TokenKind::Operator(Operator::Comma));
795                }
796                TokenKind::Bracket(Bracket::RightCurlyBracket) => break,
797                _ => {
798                    return self.error(AstNodeError::Custom {
799                        message: afmt!(self, "Invalid object syntax"),
800                        span: current_token.span,
801                    })
802                }
803            }
804        }
805
806        expect!(self, TokenKind::Bracket(Bracket::RightCurlyBracket));
807        self.node(Node::Object(key_value_pairs.into_bump_slice()), |_| {
808            NodeMetadata {
809                span: (span_start, self.prev_token_end()),
810            }
811        })
812    }
813
814    pub(crate) fn object_key<F>(&self, expression_parser: F) -> &'arena Node<'arena>
815    where
816        F: Fn(ParserContext) -> &'arena Node<'arena>,
817    {
818        let Some(key_token) = self.current() else {
819            return self.error(AstNodeError::Custom {
820                message: afmt!(self, "Expected an object key"),
821                span: (self.prev_token_end(), self.prev_token_end()),
822            });
823        };
824
825        let key = match key_token.kind {
826            TokenKind::Identifier(identifier) => {
827                self.next();
828                self.node(Node::String(identifier.into()), |_| NodeMetadata {
829                    span: key_token.span,
830                })
831            }
832            TokenKind::Boolean(boolean) => match boolean {
833                true => {
834                    self.next();
835                    self.node(Node::String("true"), |_| NodeMetadata {
836                        span: key_token.span,
837                    })
838                }
839                false => {
840                    self.next();
841                    self.node(Node::String("false"), |_| NodeMetadata {
842                        span: key_token.span,
843                    })
844                }
845            },
846            TokenKind::Number => {
847                self.next();
848                self.node(Node::String(key_token.value), |_| NodeMetadata {
849                    span: key_token.span,
850                })
851            }
852            TokenKind::Literal => {
853                self.next();
854                self.node(Node::String(key_token.value), |_| NodeMetadata {
855                    span: key_token.span,
856                })
857            }
858            TokenKind::Bracket(bracket) => match bracket {
859                Bracket::LeftSquareBracket => {
860                    expect!(self, TokenKind::Bracket(Bracket::LeftSquareBracket));
861                    let token = expression_parser(ParserContext::Global);
862                    expect!(self, TokenKind::Bracket(Bracket::RightSquareBracket));
863
864                    token
865                }
866                _ => {
867                    return self.error(AstNodeError::Custom {
868                        message: afmt!(self, "Operator is not supported as object key"),
869                        span: key_token.span,
870                    })
871                }
872            },
873            TokenKind::QuotationMark(qm) => match qm {
874                QuotationMark::SingleQuote => self.simple_string(&QuotationMark::SingleQuote),
875                QuotationMark::DoubleQuote => self.simple_string(&QuotationMark::DoubleQuote),
876                QuotationMark::Backtick => {
877                    return self.error(AstNodeError::Custom {
878                        message: afmt!(
879                            self,
880                            "TemplateString expression not supported as object key"
881                        ),
882                        span: key_token.span,
883                    })
884                }
885            },
886            TokenKind::TemplateString(_) => {
887                return self.error(AstNodeError::Custom {
888                    message: afmt!(
889                        self,
890                        "TemplateString expression not supported as object key"
891                    ),
892                    span: key_token.span,
893                })
894            }
895            TokenKind::Operator(_) => {
896                return self.error(AstNodeError::Custom {
897                    message: afmt!(self, "Operator is not supported as object key"),
898                    span: key_token.span,
899                })
900            }
901        };
902
903        key
904    }
905
906    /// Conditional
907    /// condition_node ? on_true : on_false
908    pub(crate) fn conditional<F>(
909        &self,
910        condition: &'arena Node<'arena>,
911        expression_parser: F,
912    ) -> Option<&'arena Node<'arena>>
913    where
914        F: Fn(ParserContext) -> &'arena Node<'arena>,
915    {
916        let Some(current_token) = self.current() else {
917            return None;
918        };
919        if current_token.kind != TokenKind::Operator(Operator::QuestionMark) {
920            return None;
921        }
922
923        self.next();
924
925        let on_true = expression_parser(ParserContext::Global);
926        if let Some(error_node) = self.expect(TokenKind::Operator(Operator::Slice)) {
927            return Some(error_node);
928        }
929
930        let on_false = expression_parser(ParserContext::Global);
931
932        let conditional_node = Node::Conditional {
933            condition,
934            on_true,
935            on_false,
936        };
937
938        Some(self.node(conditional_node, |_| NodeMetadata {
939            span: (current_token.span.0, self.prev_token_end()),
940        }))
941    }
942
943    /// Literal - number, string, array etc.
944    pub(crate) fn literal<F>(&self, expression_parser: F) -> &'arena Node<'arena>
945    where
946        F: Fn(ParserContext) -> &'arena Node<'arena>,
947    {
948        let Some(current_token) = self.current() else {
949            return self.error(AstNodeError::Custom {
950                message: afmt!(self, "Expected a literal"),
951                span: (self.prev_token_end(), self.prev_token_end()),
952            });
953        };
954
955        match &current_token.kind {
956            TokenKind::Identifier(identifier) => match identifier {
957                Identifier::Null => self.null(),
958                _ => self.identifier(&expression_parser),
959            },
960            TokenKind::Literal => self.identifier(&expression_parser),
961            TokenKind::Boolean(_) => self.bool(),
962            TokenKind::Number => self.number(),
963            TokenKind::QuotationMark(quote_mark) => match quote_mark {
964                QuotationMark::SingleQuote | QuotationMark::DoubleQuote => {
965                    self.simple_string(quote_mark)
966                }
967                QuotationMark::Backtick => self.template_string(&expression_parser),
968            },
969            TokenKind::Bracket(bracket) => match bracket {
970                Bracket::LeftParenthesis
971                | Bracket::RightParenthesis
972                | Bracket::RightSquareBracket => {
973                    self.interval(&expression_parser).unwrap_or_else(|| {
974                        self.error(AstNodeError::Custom {
975                            message: afmt!(self, "Invalid syntax"),
976                            span: (self.prev_token_end(), self.prev_token_end()),
977                        })
978                    })
979                }
980                Bracket::LeftSquareBracket => self
981                    .interval(&expression_parser)
982                    .unwrap_or_else(|| self.array(&expression_parser)),
983                Bracket::LeftCurlyBracket => self.object(&expression_parser),
984                Bracket::RightCurlyBracket => self.error(AstNodeError::Custom {
985                    message: afmt!(self, "Unexpected RightCurlyBracket token"),
986                    span: current_token.span,
987                }),
988            },
989            TokenKind::Operator(_) => self.error(AstNodeError::Custom {
990                message: afmt!(self, "Unexpected Operator token"),
991                span: current_token.span,
992            }),
993            TokenKind::TemplateString(_) => self.error(AstNodeError::Custom {
994                message: afmt!(self, "Unexpected TemplateString token"),
995                span: current_token.span,
996            }),
997        }
998    }
999}
1000
1001fn is_valid_property(token: &Token) -> bool {
1002    match &token.kind {
1003        TokenKind::Identifier(_) => true,
1004        TokenKind::Literal => true,
1005        TokenKind::Operator(operator) => match operator {
1006            Operator::Logical(_) => true,
1007            Operator::Comparison(comparison) => matches!(comparison, ComparisonOperator::In),
1008            _ => false,
1009        },
1010        _ => false,
1011    }
1012}
1013
1014#[derive(Debug)]
1015enum PostfixKind {
1016    MemberAccess,
1017    PropertyAccess,
1018    Other,
1019}
1020
1021impl From<&Token<'_>> for PostfixKind {
1022    fn from(token: &Token) -> Self {
1023        match &token.kind {
1024            TokenKind::Bracket(Bracket::LeftSquareBracket) => Self::PropertyAccess,
1025            TokenKind::Operator(Operator::Dot) => Self::MemberAccess,
1026            _ => Self::Other,
1027        }
1028    }
1029}
1030
1031pub(crate) struct MetadataHelper<'a, 'arena> {
1032    node_metadata: &'a HashMap<usize, NodeMetadata, BuildNoHashHasher<usize>>,
1033    arena: PhantomData<&'arena ()>,
1034}
1035
1036impl<'a, 'arena> MetadataHelper<'a, 'arena> {
1037    pub(crate) fn span(
1038        &self,
1039        left: &'arena Node<'arena>,
1040        right: &'arena Node<'arena>,
1041    ) -> Option<(u32, u32)> {
1042        Some((self.metadata(left)?.span.0, self.metadata(right)?.span.1))
1043    }
1044
1045    pub(crate) fn metadata(&self, n: &'arena Node<'arena>) -> Option<&NodeMetadata> {
1046        self.node_metadata.get(&self.address(n))
1047    }
1048
1049    fn address(&self, n: &'arena Node<'arena>) -> usize {
1050        n as *const Node as usize
1051    }
1052}
1053
1054#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1055pub(crate) enum ParserContext {
1056    Global,
1057    Closure,
1058}