zen_expression/parser/
parser.rs

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