zen_expression/parser/
parser.rs

1use crate::functions::{FunctionKind, MethodKind};
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) =
240            Decimal::from_str_exact(token.value).or_else(|_| Decimal::from_scientific(token.value))
241        else {
242            return self.error(AstNodeError::InvalidNumber {
243                number: afmt!(self, "{}", token.value),
244                span: token.span,
245            });
246        };
247
248        self.next();
249        self.node(Node::Number(decimal), |_| NodeMetadata { span: token.span })
250    }
251
252    pub(crate) fn bool(&self) -> &'arena Node<'arena> {
253        let Some(token) = self.current() else {
254            return self.error(AstNodeError::MissingToken {
255                expected: afmt!(self, "Boolean"),
256                position: self.position(),
257            });
258        };
259
260        let TokenKind::Boolean(boolean) = token.kind else {
261            return self.error(AstNodeError::InvalidBoolean {
262                boolean: afmt!(self, "{}", token.value),
263                span: token.span,
264            });
265        };
266
267        self.next();
268        self.node(Node::Bool(boolean), |_| NodeMetadata { span: token.span })
269    }
270
271    pub(crate) fn null(&self) -> &'arena Node<'arena> {
272        let Some(token) = self.current() else {
273            return self.error(AstNodeError::MissingToken {
274                expected: afmt!(self, "Null"),
275                position: self.position(),
276            });
277        };
278
279        if token.kind != TokenKind::Identifier(Identifier::Null) {
280            return self.error(AstNodeError::UnexpectedIdentifier {
281                expected: afmt!(self, "Null"),
282                received: afmt!(self, "{}", token.value),
283                span: token.span,
284            });
285        }
286
287        self.next();
288        self.node(Node::Null, |_| NodeMetadata { span: token.span })
289    }
290
291    pub(crate) fn simple_string(&self, quote_mark: &QuotationMark) -> &'arena Node<'arena> {
292        expect!(self, TokenKind::QuotationMark(quote_mark.clone()));
293        let string_value = self.current();
294
295        let error_literal = self.expect(TokenKind::Literal);
296        let error_mark_end = self.expect(TokenKind::QuotationMark(quote_mark.clone()));
297
298        error_literal
299            .or(error_mark_end)
300            .or(string_value.map(|t| {
301                self.node(Node::String(t.value), |_| NodeMetadata {
302                    span: (t.span.0 - 1, t.span.1 + 1),
303                })
304            }))
305            .unwrap_or_else(|| {
306                self.error(AstNodeError::Custom {
307                    message: afmt!(
308                        self,
309                        "Failed to parse string `{}`",
310                        string_value.map(|s| s.value).unwrap_or_default()
311                    ),
312                    span: string_value
313                        .map(|s| s.span)
314                        .unwrap_or((self.prev_token_end(), self.prev_token_end())),
315                })
316            })
317    }
318
319    pub(crate) fn template_string<F>(&self, expression_parser: &F) -> &'arena Node<'arena>
320    where
321        F: Fn(ParserContext) -> &'arena Node<'arena>,
322    {
323        expect!(self, TokenKind::QuotationMark(QuotationMark::Backtick));
324
325        let Some(mut current_token) = self.current() else {
326            return self.error(AstNodeError::MissingToken {
327                expected: afmt!(self, "Backtick (`)"),
328                position: self.position(),
329            });
330        };
331
332        let mut span = (current_token.span.0 - 1, 0u32);
333
334        let mut nodes = BumpVec::new_in(self.bump);
335        while TokenKind::QuotationMark(QuotationMark::Backtick) != current_token.kind {
336            match current_token.kind {
337                TokenKind::TemplateString(template) => match template {
338                    TemplateString::ExpressionStart => {
339                        self.next();
340                        nodes.push(expression_parser(ParserContext::Global));
341
342                        if let Some(error) =
343                            self.expect(TokenKind::TemplateString(TemplateString::ExpressionEnd))
344                        {
345                            nodes.push(error);
346                        }
347                    }
348                    TemplateString::ExpressionEnd => {
349                        self.next();
350                    }
351                },
352                TokenKind::Literal => {
353                    nodes.push(
354                        self.node(Node::String(current_token.value), |_| NodeMetadata {
355                            span: current_token.span,
356                        }),
357                    );
358                    self.next();
359                }
360                _ => {
361                    return self.error(AstNodeError::UnexpectedToken {
362                        expected: afmt!(self, "Valid TemplateString token"),
363                        received: afmt!(self, "{}", current_token.kind),
364                        span: current_token.span,
365                    })
366                }
367            }
368
369            if let Some(ct) = self.current() {
370                current_token = ct;
371                span.1 = ct.span.1;
372            } else {
373                break;
374            }
375        }
376
377        expect!(self, TokenKind::QuotationMark(QuotationMark::Backtick));
378        self.node(Node::TemplateString(nodes.into_bump_slice()), |_| {
379            NodeMetadata { span }
380        })
381    }
382
383    pub(crate) fn method_call<F>(
384        &self,
385        node: &'arena Node,
386        method_name: &Token,
387        expression_parser: &F,
388    ) -> &'arena Node<'arena>
389    where
390        F: Fn(ParserContext) -> &'arena Node<'arena>,
391    {
392        let Some(method_kind) = MethodKind::try_from(method_name.value).ok() else {
393            return self.error(AstNodeError::UnknownMethod {
394                name: afmt!(self, "{}", method_name.value),
395                span: method_name.span,
396            });
397        };
398
399        expect!(self, TokenKind::Bracket(Bracket::LeftParenthesis));
400
401        let mut arguments = BumpVec::new_in(&self.bump);
402        loop {
403            if self.current_kind() == Some(&TokenKind::Bracket(Bracket::RightParenthesis)) {
404                break;
405            }
406
407            arguments.push(expression_parser(ParserContext::Global));
408            if self.current_kind() != Some(&TokenKind::Operator(Operator::Comma)) {
409                break;
410            }
411
412            if let Some(error) = self.expect(TokenKind::Operator(Operator::Comma)) {
413                arguments.push(error);
414                break;
415            }
416        }
417
418        if let Some(error) = self.expect(TokenKind::Bracket(Bracket::RightParenthesis)) {
419            arguments.push(error);
420        }
421
422        let method_node = self.node(
423            Node::MethodCall {
424                this: node,
425                kind: method_kind,
426                arguments: arguments.into_bump_slice(),
427            },
428            |h| NodeMetadata {
429                span: (
430                    h.metadata(node).map(|m| m.span.0).unwrap_or_default(),
431                    self.prev_token_end(),
432                ),
433            },
434        );
435
436        let (node, _) = self.with_postfix(method_node, expression_parser);
437        node
438    }
439
440    pub(crate) fn with_member_access<F>(
441        &self,
442        node: &'arena Node<'arena>,
443        expression_parser: &F,
444    ) -> &'arena Node<'arena>
445    where
446        F: Fn(ParserContext) -> &'arena Node<'arena>,
447    {
448        self.next();
449        let property_token = self.current();
450        self.next();
451
452        let property = match property_token {
453            None => self.error_with_node(
454                AstNodeError::Custom {
455                    message: afmt!(self, "Expected a property"),
456                    span: (self.prev_token_end(), self.prev_token_end()),
457                },
458                node,
459            ),
460            Some(t) => match is_valid_property(t) {
461                true => {
462                    if self.current_kind() == Some(&TokenKind::Bracket(Bracket::LeftParenthesis)) {
463                        return self.method_call(node, t, expression_parser);
464                    }
465
466                    self.node(Node::String(t.value), |_| NodeMetadata { span: t.span })
467                }
468                false => {
469                    self.set_position(self.position() - 1);
470                    self.error_with_node(
471                        AstNodeError::InvalidProperty {
472                            property: afmt!(self, "{}", t.value),
473                            span: t.span,
474                        },
475                        node,
476                    )
477                }
478            },
479        };
480
481        self.node(Node::Member { node, property }, |h| NodeMetadata {
482            span: h.span(node, property).unwrap_or_default(),
483        })
484    }
485
486    pub(crate) fn with_property_access<F>(
487        &self,
488        node: &'arena Node<'arena>,
489        expression_parser: &F,
490    ) -> &'arena Node<'arena>
491    where
492        F: Fn(ParserContext) -> &'arena Node<'arena>,
493    {
494        self.next();
495        let mut from: Option<&'arena Node<'arena>> = None;
496        let mut to: Option<&'arena Node<'arena>> = None;
497
498        let Some(mut c) = self.current() else {
499            return self.error_with_node(
500                AstNodeError::Custom {
501                    message: afmt!(self, "Expected a property"),
502                    span: (self.prev_token_end(), self.prev_token_end()),
503                },
504                node,
505            );
506        };
507
508        if c.kind == TokenKind::Operator(Operator::Slice) {
509            self.next();
510
511            let Some(cc) = self.current() else {
512                return self.error_with_node(
513                    AstNodeError::Custom {
514                        message: afmt!(self, "Unexpected token"),
515                        span: (self.prev_token_end(), self.prev_token_end()),
516                    },
517                    node,
518                );
519            };
520            c = cc;
521
522            if c.kind != TokenKind::Bracket(Bracket::RightSquareBracket) {
523                to = Some(expression_parser(ParserContext::Global));
524            }
525
526            expect!(self, TokenKind::Bracket(Bracket::RightSquareBracket));
527            self.node(Node::Slice { node, to, from }, |h| NodeMetadata {
528                span: (
529                    h.metadata(node).map(|m| m.span.0).unwrap_or_default(),
530                    self.prev_token_end(),
531                ),
532            })
533        } else {
534            let from_node = expression_parser(ParserContext::Global);
535            from = Some(from_node);
536            let Some(cc) = self.current() else {
537                return self.error_with_node(
538                    AstNodeError::Custom {
539                        message: afmt!(self, "Unexpected token"),
540                        span: (self.prev_token_end(), self.prev_token_end()),
541                    },
542                    self.node(
543                        Node::Member {
544                            node,
545                            property: from_node,
546                        },
547                        |h| NodeMetadata {
548                            span: h.span(node, from_node).unwrap_or_default(),
549                        },
550                    ),
551                );
552            };
553            c = cc;
554
555            if c.kind == TokenKind::Operator(Operator::Slice) {
556                self.next();
557                let Some(cc) = self.current() else {
558                    return self.error_with_node(
559                        AstNodeError::Custom {
560                            message: afmt!(self, "Invalid slice syntax"),
561                            span: (self.prev_token_end(), self.prev_token_end()),
562                        },
563                        self.node(Node::Slice { node, from, to }, |h| NodeMetadata {
564                            span: h.span(node, from_node).unwrap_or_default(),
565                        }),
566                    );
567                };
568                c = cc;
569
570                if c.kind != TokenKind::Bracket(Bracket::RightSquareBracket) {
571                    to = Some(expression_parser(ParserContext::Global));
572                }
573
574                expect!(self, TokenKind::Bracket(Bracket::RightSquareBracket));
575                self.node(Node::Slice { node, from, to }, |h| NodeMetadata {
576                    span: (
577                        h.metadata(node).map(|m| m.span.0).unwrap_or_default(),
578                        self.prev_token_end(),
579                    ),
580                })
581            } else {
582                // Slice operator [:] was not found,
583                // it should be just an index node.
584                expect!(self, TokenKind::Bracket(Bracket::RightSquareBracket));
585                self.node(
586                    Node::Member {
587                        node,
588                        property: from.unwrap_or_else(|| {
589                            return self.error_with_node(
590                                AstNodeError::Custom {
591                                    message: afmt!(self, "Invalid index property"),
592                                    span: (self.prev_token_end(), self.prev_token_end()),
593                                },
594                                node,
595                            );
596                        }),
597                    },
598                    |h| NodeMetadata {
599                        span: (
600                            h.metadata(node).map(|m| m.span.0).unwrap_or_default(),
601                            self.prev_token_end(),
602                        ),
603                    },
604                )
605            }
606        }
607    }
608
609    pub(crate) fn with_postfix<F>(
610        &self,
611        node: &'arena Node<'arena>,
612        expression_parser: &F,
613    ) -> (&'arena Node<'arena>, PostfixCombination)
614    where
615        F: Fn(ParserContext) -> &'arena Node<'arena>,
616    {
617        let Some(postfix_token) = self.current() else {
618            return (node, PostfixCombination::Mixed);
619        };
620
621        let postfix_kind = PostfixKind::from(postfix_token);
622
623        let (processed_token, processed_combination) = match postfix_kind {
624            PostfixKind::Other => return (node, PostfixCombination::Inherit),
625            PostfixKind::PropertyAccess => (
626                self.with_member_access(node, expression_parser),
627                PostfixCombination::Property,
628            ),
629            PostfixKind::ComputedAccess => (
630                self.with_property_access(node, expression_parser),
631                PostfixCombination::Computed,
632            ),
633        };
634
635        let (node, combination) = self.with_postfix(processed_token, expression_parser);
636
637        (node, combination.and(processed_combination))
638    }
639
640    /// Closure
641    pub(crate) fn closure<F>(&self, expression_parser: &F) -> &'arena Node<'arena>
642    where
643        F: Fn(ParserContext) -> &'arena Node<'arena>,
644    {
645        let start = self.token_start();
646
647        self.depth.set(self.depth.get() + 1);
648        let node = expression_parser(ParserContext::Closure);
649        self.depth.set(self.depth.get() - 1);
650
651        self.node(Node::Closure(node), |_| NodeMetadata {
652            span: (start, self.prev_token_end()),
653        })
654    }
655
656    /// Identifier expression
657    /// Either <Identifier> or <Identifier Expression>
658    pub(crate) fn identifier<F>(&self, expression_parser: &F) -> &'arena Node<'arena>
659    where
660        F: Fn(ParserContext) -> &'arena Node<'arena>,
661    {
662        let Some(token) = self.current() else {
663            return self.error(AstNodeError::MissingToken {
664                expected: afmt!(self, "Identifier"),
665                position: self.position(),
666            });
667        };
668
669        match token.kind {
670            TokenKind::Identifier(_) | TokenKind::Literal => {
671                // ok
672            }
673            _ => {
674                return self.error(AstNodeError::Custom {
675                    message: afmt!(self, "Expected an `identifier`, received `{}`.", token.kind),
676                    span: token.span,
677                });
678            }
679        }
680
681        let Some(identifier_token) = self.current() else {
682            return self.error(AstNodeError::Custom {
683                message: afmt!(self, "Expected an `identifier`."),
684                span: (self.prev_token_end(), self.prev_token_end()),
685            });
686        };
687        self.next();
688
689        let current_token = self.current();
690        if current_token.map(|t| t.kind) != Some(TokenKind::Bracket(Bracket::LeftParenthesis)) {
691            let identifier_node = match identifier_token.kind {
692                TokenKind::Identifier(Identifier::RootReference) => {
693                    self.node(Node::Root, |_| NodeMetadata {
694                        span: identifier_token.span,
695                    })
696                }
697                _ => self.node(Node::Identifier(identifier_token.value), |_| NodeMetadata {
698                    span: identifier_token.span,
699                }),
700            };
701
702            let (identifier_with_postfix, combination) =
703                self.with_postfix(identifier_node, &expression_parser);
704            if let Some(&TokenKind::Operator(Operator::Assign)) = self.current_kind() {
705                if combination != PostfixCombination::Property
706                    && combination != PostfixCombination::Inherit
707                {
708                    return self.error_with_node(
709                        AstNodeError::Custom {
710                            span: identifier_with_postfix.span().unwrap_or_default(),
711                            message: "Only property access is allowed during assignment",
712                        },
713                        identifier_with_postfix,
714                    );
715                }
716
717                return self.assigned_object(identifier_with_postfix, expression_parser);
718            }
719
720            return identifier_with_postfix;
721        }
722
723        // Potentially it might be a built-in expression
724        let Ok(function) = FunctionKind::try_from(identifier_token.value) else {
725            return self.error(AstNodeError::UnknownBuiltIn {
726                name: afmt!(self, "{}", identifier_token.value),
727                span: identifier_token.span,
728            });
729        };
730
731        self.next();
732        let function_node = match function {
733            FunctionKind::Closure(_) => {
734                let mut arguments = BumpVec::new_in(&self.bump);
735
736                arguments.push(expression_parser(ParserContext::Global));
737                if let Some(error) = self.expect(TokenKind::Operator(Operator::Comma)) {
738                    arguments.push(error);
739                };
740
741                arguments.push(self.closure(&expression_parser));
742                if let Some(error) = self.expect(TokenKind::Bracket(Bracket::RightParenthesis)) {
743                    arguments.push(error);
744                }
745
746                Node::FunctionCall {
747                    kind: function,
748                    arguments: self.bump.alloc_slice_copy(arguments.into_bump_slice()),
749                }
750            }
751            _ => {
752                let mut arguments = BumpVec::new_in(&self.bump);
753                loop {
754                    if self.current_kind() == Some(&TokenKind::Bracket(Bracket::RightParenthesis)) {
755                        break;
756                    }
757
758                    arguments.push(expression_parser(ParserContext::Global));
759                    if self.current_kind() != Some(&TokenKind::Operator(Operator::Comma)) {
760                        break;
761                    }
762
763                    if let Some(error) = self.expect(TokenKind::Operator(Operator::Comma)) {
764                        arguments.push(error);
765                        break;
766                    }
767                }
768
769                if let Some(error) = self.expect(TokenKind::Bracket(Bracket::RightParenthesis)) {
770                    arguments.push(error);
771                }
772
773                Node::FunctionCall {
774                    kind: function,
775                    arguments: arguments.into_bump_slice(),
776                }
777            }
778        };
779
780        let (node, _) = self.with_postfix(
781            self.node(function_node, |_| NodeMetadata {
782                span: (identifier_token.span.0, self.prev_token_end()),
783            }),
784            expression_parser,
785        );
786        node
787    }
788
789    /// Interval node
790    pub(crate) fn interval<F>(&self, expression_parser: &F) -> Option<&'arena Node<'arena>>
791    where
792        F: Fn(ParserContext) -> &'arena Node<'arena>,
793    {
794        // Performance optimisation: skip if expression does not contain an interval for faster evaluation
795        if !self.has_range_operator {
796            return None;
797        }
798
799        let TokenKind::Bracket(_) = &self.current()?.kind else {
800            return None;
801        };
802
803        let initial_position = self.position();
804        let TokenKind::Bracket(left_bracket) = &self.current()?.kind else {
805            self.set_position(initial_position);
806            return None;
807        };
808
809        self.next();
810        let left = expression_parser(ParserContext::Global);
811        if left.has_error() {
812            self.set_position(initial_position);
813            return None;
814        };
815
816        if let Some(_) = self.expect(TokenKind::Operator(Operator::Range)) {
817            self.set_position(initial_position);
818            return None;
819        };
820
821        let right = expression_parser(ParserContext::Global);
822        if right.has_error() {
823            self.set_position(initial_position);
824            return None;
825        };
826
827        let TokenKind::Bracket(right_bracket) = &self.current()?.kind else {
828            self.set_position(initial_position);
829            return None;
830        };
831
832        self.next();
833
834        let interval_node = self.node(
835            Node::Interval {
836                left,
837                right,
838                left_bracket: *left_bracket,
839                right_bracket: *right_bracket,
840            },
841            |_| NodeMetadata {
842                span: (initial_position as u32, self.position() as u32),
843            },
844        );
845
846        let (node, _) = self.with_postfix(interval_node, &expression_parser);
847        Some(node)
848    }
849
850    /// Array nodes
851    pub(crate) fn array<F>(&self, expression_parser: &F) -> &'arena Node<'arena>
852    where
853        F: Fn(ParserContext) -> &'arena Node<'arena>,
854    {
855        let Some(current_token) = self.current() else {
856            return self.error(AstNodeError::MissingToken {
857                expected: afmt!(self, "Array"),
858                position: self.position(),
859            });
860        };
861
862        if current_token.kind != TokenKind::Bracket(Bracket::LeftSquareBracket) {
863            return self.error(AstNodeError::UnexpectedToken {
864                expected: afmt!(self, "{}", TokenKind::Bracket(Bracket::LeftSquareBracket)),
865                received: afmt!(self, "{}", current_token.kind),
866                span: current_token.span,
867            });
868        }
869
870        self.next();
871        let mut nodes = BumpVec::new_in(self.bump);
872        while !(self.current().map(|t| t.kind)
873            == Some(TokenKind::Bracket(Bracket::RightSquareBracket)))
874        {
875            if !nodes.is_empty() {
876                expect!(self, TokenKind::Operator(Operator::Comma));
877                if self.current().map(|t| t.kind)
878                    == Some(TokenKind::Bracket(Bracket::RightSquareBracket))
879                {
880                    break;
881                }
882            }
883
884            nodes.push(expression_parser(ParserContext::Global));
885        }
886
887        expect!(self, TokenKind::Bracket(Bracket::RightSquareBracket));
888
889        let node = Node::Array(nodes.into_bump_slice());
890
891        let (node, _) = self.with_postfix(
892            self.node(node, |_| NodeMetadata {
893                span: (current_token.span.0, self.prev_token_end()),
894            }),
895            &expression_parser,
896        );
897        node
898    }
899
900    pub(crate) fn assigned_object<F>(
901        &self,
902        starting_key: &'arena Node<'arena>,
903        expression_parser: &F,
904    ) -> &'arena Node<'arena>
905    where
906        F: Fn(ParserContext) -> &'arena Node<'arena>,
907    {
908        let transform_key = |n: &'arena Node<'arena>| -> &'arena Node<'arena> {
909            let mut keys = BumpVec::new_in(&self.bump);
910            if n.member_key(&mut keys).is_none() {
911                return self.error_with_node(
912                    AstNodeError::Custom {
913                        span: n.span().unwrap_or_default(),
914                        message: self.bump.alloc_str("Failed to resolve"),
915                    },
916                    n,
917                );
918            }
919
920            self.node(
921                Node::String(self.bump.alloc_str(keys.join(".").as_str())),
922                |_| NodeMetadata {
923                    span: n.span().unwrap_or_default(),
924                },
925            )
926        };
927
928        let span_start = self.token_start();
929        expect!(self, TokenKind::Operator(Operator::Assign));
930
931        let mut key_value_pairs = BumpVec::new_in(self.bump);
932        let value = expression_parser(ParserContext::Global);
933
934        key_value_pairs.push((transform_key(starting_key), value));
935        let mut checkpoint_for_return = None;
936
937        loop {
938            if let None = self.current() {
939                break;
940            }
941
942            expect!(self, TokenKind::Operator(Operator::Semi));
943            let Some(identifier_token) = self.current() else {
944                break;
945            };
946
947            let checkpoint = self.position();
948            let identifier_node =
949                self.node(Node::Identifier(identifier_token.value), |_| NodeMetadata {
950                    span: identifier_token.span,
951                });
952            self.next();
953
954            let (key_node, combination) = self.with_postfix(identifier_node, expression_parser);
955            if let Some(_) = self.expect(TokenKind::Operator(Operator::Assign)) {
956                checkpoint_for_return = Some(checkpoint);
957                break;
958            };
959
960            if combination != PostfixCombination::Property
961                && combination != PostfixCombination::Inherit
962            {
963                return self.error_with_node(
964                    AstNodeError::Custom {
965                        span: key_node.span().unwrap_or_default(),
966                        message: "Only property access is allowed during assignment",
967                    },
968                    key_node,
969                );
970            }
971
972            let value = expression_parser(ParserContext::Global);
973            key_value_pairs.push((transform_key(key_node), value));
974        }
975
976        let mut output = None;
977        if let Some(starting_position) = checkpoint_for_return {
978            self.set_position(starting_position);
979            let value = expression_parser(ParserContext::Global);
980            output.replace(value);
981        }
982
983        self.node(
984            Node::Assignments {
985                list: key_value_pairs.into_bump_slice(),
986                output,
987            },
988            |_| NodeMetadata {
989                span: (span_start, self.prev_token_end()),
990            },
991        )
992    }
993
994    pub(crate) fn object<F>(&self, expression_parser: &F) -> &'arena Node<'arena>
995    where
996        F: Fn(ParserContext) -> &'arena Node<'arena>,
997    {
998        let span_start = self.token_start();
999        expect!(self, TokenKind::Bracket(Bracket::LeftCurlyBracket));
1000
1001        let mut key_value_pairs = BumpVec::new_in(self.bump);
1002        if let Some(TokenKind::Bracket(Bracket::RightCurlyBracket)) = self.current().map(|t| t.kind)
1003        {
1004            self.next();
1005            return self.node(Node::Object(key_value_pairs.into_bump_slice()), |_| {
1006                NodeMetadata {
1007                    span: (span_start, self.prev_token_end()),
1008                }
1009            });
1010        }
1011
1012        loop {
1013            let key = self.object_key(&expression_parser);
1014            expect!(self, TokenKind::Operator(Operator::Slice));
1015            let value = expression_parser(ParserContext::Global);
1016
1017            key_value_pairs.push((key, value));
1018
1019            let Some(current_token) = self.current() else {
1020                break;
1021            };
1022
1023            match current_token.kind {
1024                TokenKind::Operator(Operator::Comma) => {
1025                    expect!(self, TokenKind::Operator(Operator::Comma));
1026                }
1027                TokenKind::Bracket(Bracket::RightCurlyBracket) => break,
1028                _ => {
1029                    return self.error(AstNodeError::Custom {
1030                        message: afmt!(self, "Invalid object syntax"),
1031                        span: current_token.span,
1032                    })
1033                }
1034            }
1035        }
1036
1037        if let Some(error) = self.expect(TokenKind::Bracket(Bracket::RightCurlyBracket)) {
1038            key_value_pairs.push((
1039                self.node(Node::Null, |_| NodeMetadata {
1040                    span: error.span().unwrap_or_default(),
1041                }),
1042                error,
1043            ));
1044        };
1045
1046        self.node(Node::Object(key_value_pairs.into_bump_slice()), |_| {
1047            NodeMetadata {
1048                span: (span_start, self.prev_token_end()),
1049            }
1050        })
1051    }
1052
1053    pub(crate) fn object_key<F>(&self, expression_parser: &F) -> &'arena Node<'arena>
1054    where
1055        F: Fn(ParserContext) -> &'arena Node<'arena>,
1056    {
1057        let Some(key_token) = self.current() else {
1058            return self.error(AstNodeError::Custom {
1059                message: afmt!(self, "Expected an object key"),
1060                span: (self.prev_token_end(), self.prev_token_end()),
1061            });
1062        };
1063
1064        let key = match key_token.kind {
1065            TokenKind::Identifier(identifier) => {
1066                self.next();
1067                self.node(Node::String(identifier.into()), |_| NodeMetadata {
1068                    span: key_token.span,
1069                })
1070            }
1071            TokenKind::Boolean(boolean) => match boolean {
1072                true => {
1073                    self.next();
1074                    self.node(Node::String("true"), |_| NodeMetadata {
1075                        span: key_token.span,
1076                    })
1077                }
1078                false => {
1079                    self.next();
1080                    self.node(Node::String("false"), |_| NodeMetadata {
1081                        span: key_token.span,
1082                    })
1083                }
1084            },
1085            TokenKind::Number => {
1086                self.next();
1087                self.node(Node::String(key_token.value), |_| NodeMetadata {
1088                    span: key_token.span,
1089                })
1090            }
1091            TokenKind::Literal => {
1092                self.next();
1093                self.node(Node::String(key_token.value), |_| NodeMetadata {
1094                    span: key_token.span,
1095                })
1096            }
1097            TokenKind::Bracket(bracket) => match bracket {
1098                Bracket::LeftSquareBracket => {
1099                    expect!(self, TokenKind::Bracket(Bracket::LeftSquareBracket));
1100                    let token = expression_parser(ParserContext::Global);
1101                    expect!(self, TokenKind::Bracket(Bracket::RightSquareBracket));
1102
1103                    token
1104                }
1105                _ => {
1106                    return self.error(AstNodeError::Custom {
1107                        message: afmt!(self, "Operator is not supported as object key"),
1108                        span: key_token.span,
1109                    })
1110                }
1111            },
1112            TokenKind::QuotationMark(qm) => match qm {
1113                QuotationMark::SingleQuote => self.simple_string(&QuotationMark::SingleQuote),
1114                QuotationMark::DoubleQuote => self.simple_string(&QuotationMark::DoubleQuote),
1115                QuotationMark::Backtick => {
1116                    return self.error(AstNodeError::Custom {
1117                        message: afmt!(
1118                            self,
1119                            "TemplateString expression not supported as object key"
1120                        ),
1121                        span: key_token.span,
1122                    })
1123                }
1124            },
1125            TokenKind::TemplateString(_) => {
1126                return self.error(AstNodeError::Custom {
1127                    message: afmt!(
1128                        self,
1129                        "TemplateString expression not supported as object key"
1130                    ),
1131                    span: key_token.span,
1132                })
1133            }
1134            TokenKind::Operator(_) => {
1135                return self.error(AstNodeError::Custom {
1136                    message: afmt!(self, "Operator is not supported as object key"),
1137                    span: key_token.span,
1138                })
1139            }
1140        };
1141
1142        key
1143    }
1144
1145    /// Conditional
1146    /// condition_node ? on_true : on_false
1147    pub(crate) fn conditional<F>(
1148        &self,
1149        condition: &'arena Node<'arena>,
1150        expression_parser: &F,
1151    ) -> Option<&'arena Node<'arena>>
1152    where
1153        F: Fn(ParserContext) -> &'arena Node<'arena>,
1154    {
1155        let Some(current_token) = self.current() else {
1156            return None;
1157        };
1158        if current_token.kind != TokenKind::Operator(Operator::QuestionMark) {
1159            return None;
1160        }
1161
1162        self.next();
1163
1164        let on_true = expression_parser(ParserContext::Global);
1165        if let Some(error_node) = self.expect(TokenKind::Operator(Operator::Slice)) {
1166            return Some(error_node);
1167        }
1168
1169        let on_false = expression_parser(ParserContext::Global);
1170
1171        let conditional_node = Node::Conditional {
1172            condition,
1173            on_true,
1174            on_false,
1175        };
1176
1177        Some(self.node(conditional_node, |_| NodeMetadata {
1178            span: (current_token.span.0, self.prev_token_end()),
1179        }))
1180    }
1181
1182    /// Literal - number, string, array etc.
1183    pub(crate) fn literal<F>(&self, expression_parser: &F) -> &'arena Node<'arena>
1184    where
1185        F: Fn(ParserContext) -> &'arena Node<'arena>,
1186    {
1187        let Some(current_token) = self.current() else {
1188            return self.error(AstNodeError::Custom {
1189                message: afmt!(self, "Expected a literal"),
1190                span: (self.prev_token_end(), self.prev_token_end()),
1191            });
1192        };
1193
1194        match &current_token.kind {
1195            TokenKind::Identifier(identifier) => match identifier {
1196                Identifier::Null => self.null(),
1197                _ => self.identifier(&expression_parser),
1198            },
1199            TokenKind::Literal => self.identifier(&expression_parser),
1200            TokenKind::Boolean(_) => self.bool(),
1201            TokenKind::Number => self.number(),
1202            TokenKind::QuotationMark(quote_mark) => match quote_mark {
1203                QuotationMark::SingleQuote | QuotationMark::DoubleQuote => {
1204                    self.simple_string(quote_mark)
1205                }
1206                QuotationMark::Backtick => self.template_string(&expression_parser),
1207            },
1208            TokenKind::Bracket(bracket) => match bracket {
1209                Bracket::LeftParenthesis
1210                | Bracket::RightParenthesis
1211                | Bracket::RightSquareBracket => {
1212                    self.interval(&expression_parser).unwrap_or_else(|| {
1213                        self.error(AstNodeError::Custom {
1214                            message: afmt!(self, "Invalid syntax"),
1215                            span: (self.prev_token_end(), self.prev_token_end()),
1216                        })
1217                    })
1218                }
1219                Bracket::LeftSquareBracket => self
1220                    .interval(&expression_parser)
1221                    .unwrap_or_else(|| self.array(&expression_parser)),
1222                Bracket::LeftCurlyBracket => self.object(&expression_parser),
1223                Bracket::RightCurlyBracket => self.error(AstNodeError::Custom {
1224                    message: afmt!(self, "Unexpected RightCurlyBracket token"),
1225                    span: current_token.span,
1226                }),
1227            },
1228            TokenKind::Operator(_) => self.error(AstNodeError::Custom {
1229                message: afmt!(self, "Unexpected Operator token"),
1230                span: current_token.span,
1231            }),
1232            TokenKind::TemplateString(_) => self.error(AstNodeError::Custom {
1233                message: afmt!(self, "Unexpected TemplateString token"),
1234                span: current_token.span,
1235            }),
1236        }
1237    }
1238}
1239
1240fn is_valid_property(token: &Token) -> bool {
1241    match &token.kind {
1242        TokenKind::Identifier(_) => true,
1243        TokenKind::Literal => true,
1244        TokenKind::Operator(operator) => match operator {
1245            Operator::Logical(_) => true,
1246            Operator::Comparison(comparison) => matches!(comparison, ComparisonOperator::In),
1247            _ => false,
1248        },
1249        _ => false,
1250    }
1251}
1252
1253#[derive(Debug)]
1254enum PostfixKind {
1255    PropertyAccess,
1256    ComputedAccess,
1257    Other,
1258}
1259
1260impl From<&Token<'_>> for PostfixKind {
1261    fn from(token: &Token) -> Self {
1262        match &token.kind {
1263            TokenKind::Bracket(Bracket::LeftSquareBracket) => Self::ComputedAccess,
1264            TokenKind::Operator(Operator::Dot) => Self::PropertyAccess,
1265            _ => Self::Other,
1266        }
1267    }
1268}
1269
1270#[derive(Debug, PartialEq)]
1271pub(crate) enum PostfixCombination {
1272    Mixed,
1273    Computed,
1274    Property,
1275    Inherit,
1276}
1277
1278impl PostfixCombination {
1279    fn and(self, other: PostfixCombination) -> Self {
1280        match (self, other) {
1281            (Self::Computed, Self::Computed) => Self::Computed,
1282            (Self::Property, Self::Property) => Self::Property,
1283            (Self::Inherit, other) => other,
1284            _ => Self::Mixed,
1285        }
1286    }
1287}
1288
1289pub(crate) struct MetadataHelper<'a, 'arena> {
1290    node_metadata: &'a HashMap<usize, NodeMetadata, BuildNoHashHasher<usize>>,
1291    arena: PhantomData<&'arena ()>,
1292}
1293
1294impl<'a, 'arena> MetadataHelper<'a, 'arena> {
1295    pub(crate) fn span(
1296        &self,
1297        left: &'arena Node<'arena>,
1298        right: &'arena Node<'arena>,
1299    ) -> Option<(u32, u32)> {
1300        Some((self.metadata(left)?.span.0, self.metadata(right)?.span.1))
1301    }
1302
1303    pub(crate) fn metadata(&self, n: &'arena Node<'arena>) -> Option<&NodeMetadata> {
1304        self.node_metadata.get(&self.address(n))
1305    }
1306
1307    fn address(&self, n: &'arena Node<'arena>) -> usize {
1308        n as *const Node as usize
1309    }
1310}
1311
1312#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1313pub(crate) enum ParserContext {
1314    Global,
1315    Closure,
1316}