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>(
642        &self,
643        expression_parser: &F,
644        alias: Option<&'arena str>,
645    ) -> &'arena Node<'arena>
646    where
647        F: Fn(ParserContext) -> &'arena Node<'arena>,
648    {
649        let start = self.token_start();
650
651        self.depth.set(self.depth.get() + 1);
652        let node = expression_parser(ParserContext::Closure);
653        self.depth.set(self.depth.get() - 1);
654
655        self.node(Node::Closure { body: node, alias }, |_| NodeMetadata {
656            span: (start, self.prev_token_end()),
657        })
658    }
659
660    /// Identifier expression
661    /// Either <Identifier> or <Identifier Expression>
662    pub(crate) fn identifier<F>(&self, expression_parser: &F) -> &'arena Node<'arena>
663    where
664        F: Fn(ParserContext) -> &'arena Node<'arena>,
665    {
666        let Some(token) = self.current() else {
667            return self.error(AstNodeError::MissingToken {
668                expected: afmt!(self, "Identifier"),
669                position: self.position(),
670            });
671        };
672
673        match token.kind {
674            TokenKind::Identifier(_) | TokenKind::Literal => {
675                // ok
676            }
677            _ => {
678                return self.error(AstNodeError::Custom {
679                    message: afmt!(self, "Expected an `identifier`, received `{}`.", token.kind),
680                    span: token.span,
681                });
682            }
683        }
684
685        let Some(identifier_token) = self.current() else {
686            return self.error(AstNodeError::Custom {
687                message: afmt!(self, "Expected an `identifier`."),
688                span: (self.prev_token_end(), self.prev_token_end()),
689            });
690        };
691        self.next();
692
693        let current_token = self.current();
694        if current_token.map(|t| t.kind) != Some(TokenKind::Bracket(Bracket::LeftParenthesis)) {
695            let identifier_node = match identifier_token.kind {
696                TokenKind::Identifier(Identifier::RootReference) => {
697                    self.node(Node::Root, |_| NodeMetadata {
698                        span: identifier_token.span,
699                    })
700                }
701                _ => self.node(Node::Identifier(identifier_token.value), |_| NodeMetadata {
702                    span: identifier_token.span,
703                }),
704            };
705
706            let (identifier_with_postfix, combination) =
707                self.with_postfix(identifier_node, &expression_parser);
708            if let Some(&TokenKind::Operator(Operator::Assign)) = self.current_kind() {
709                if combination != PostfixCombination::Property
710                    && combination != PostfixCombination::Inherit
711                {
712                    return self.error_with_node(
713                        AstNodeError::Custom {
714                            span: identifier_with_postfix.span().unwrap_or_default(),
715                            message: "Only property access is allowed during assignment",
716                        },
717                        identifier_with_postfix,
718                    );
719                }
720
721                return self.assigned_object(identifier_with_postfix, expression_parser);
722            }
723
724            return identifier_with_postfix;
725        }
726
727        // Potentially it might be a built-in expression
728        let Ok(function) = FunctionKind::try_from(identifier_token.value) else {
729            return self.error(AstNodeError::UnknownBuiltIn {
730                name: afmt!(self, "{}", identifier_token.value),
731                span: identifier_token.span,
732            });
733        };
734
735        self.next();
736        let function_node = match function {
737            FunctionKind::Closure(_) => {
738                let mut arguments = BumpVec::new_in(&self.bump);
739
740                arguments.push(expression_parser(ParserContext::Global));
741
742                let alias: Option<&'arena str> =
743                    if self
744                        .current()
745                        .is_some_and(|t| t.kind == TokenKind::Literal && t.value == "as")
746                    {
747                        self.next();
748
749                        let alias_token = self.current();
750                        match alias_token {
751                            Some(t) if t.kind == TokenKind::Literal => {
752                                let alias_str = self.bump.alloc_str(t.value);
753                                self.next();
754                                Some(alias_str)
755                            }
756                            _ => {
757                                arguments.push(self.error(AstNodeError::Custom {
758                                    message: afmt!(self, "Expected identifier after 'as'"),
759                                    span:
760                                        alias_token.map(|t| t.span).unwrap_or((
761                                            self.prev_token_end(),
762                                            self.prev_token_end(),
763                                        )),
764                                }));
765                                None
766                            }
767                        }
768                    } else {
769                        None
770                    };
771
772                if let Some(error) = self.expect(TokenKind::Operator(Operator::Comma)) {
773                    arguments.push(error);
774                };
775
776                arguments.push(self.closure(&expression_parser, alias));
777                if let Some(error) = self.expect(TokenKind::Bracket(Bracket::RightParenthesis)) {
778                    arguments.push(error);
779                }
780
781                Node::FunctionCall {
782                    kind: function,
783                    arguments: self.bump.alloc_slice_copy(arguments.into_bump_slice()),
784                }
785            }
786            _ => {
787                let mut arguments = BumpVec::new_in(&self.bump);
788                loop {
789                    if self.current_kind() == Some(&TokenKind::Bracket(Bracket::RightParenthesis)) {
790                        break;
791                    }
792
793                    arguments.push(expression_parser(ParserContext::Global));
794                    if self.current_kind() != Some(&TokenKind::Operator(Operator::Comma)) {
795                        break;
796                    }
797
798                    if let Some(error) = self.expect(TokenKind::Operator(Operator::Comma)) {
799                        arguments.push(error);
800                        break;
801                    }
802                }
803
804                if let Some(error) = self.expect(TokenKind::Bracket(Bracket::RightParenthesis)) {
805                    arguments.push(error);
806                }
807
808                Node::FunctionCall {
809                    kind: function,
810                    arguments: arguments.into_bump_slice(),
811                }
812            }
813        };
814
815        let (node, _) = self.with_postfix(
816            self.node(function_node, |_| NodeMetadata {
817                span: (identifier_token.span.0, self.prev_token_end()),
818            }),
819            expression_parser,
820        );
821        node
822    }
823
824    /// Interval node
825    pub(crate) fn interval<F>(&self, expression_parser: &F) -> Option<&'arena Node<'arena>>
826    where
827        F: Fn(ParserContext) -> &'arena Node<'arena>,
828    {
829        // Performance optimisation: skip if expression does not contain an interval for faster evaluation
830        if !self.has_range_operator {
831            return None;
832        }
833
834        let TokenKind::Bracket(_) = &self.current()?.kind else {
835            return None;
836        };
837
838        let initial_position = self.position();
839        let TokenKind::Bracket(left_bracket) = &self.current()?.kind else {
840            self.set_position(initial_position);
841            return None;
842        };
843
844        self.next();
845        let left = expression_parser(ParserContext::Global);
846        if left.has_error() {
847            self.set_position(initial_position);
848            return None;
849        };
850
851        if let Some(_) = self.expect(TokenKind::Operator(Operator::Range)) {
852            self.set_position(initial_position);
853            return None;
854        };
855
856        let right = expression_parser(ParserContext::Global);
857        if right.has_error() {
858            self.set_position(initial_position);
859            return None;
860        };
861
862        let TokenKind::Bracket(right_bracket) = &self.current()?.kind else {
863            self.set_position(initial_position);
864            return None;
865        };
866
867        self.next();
868
869        let interval_node = self.node(
870            Node::Interval {
871                left,
872                right,
873                left_bracket: *left_bracket,
874                right_bracket: *right_bracket,
875            },
876            |_| NodeMetadata {
877                span: (initial_position as u32, self.position() as u32),
878            },
879        );
880
881        let (node, _) = self.with_postfix(interval_node, &expression_parser);
882        Some(node)
883    }
884
885    /// Array nodes
886    pub(crate) fn array<F>(&self, expression_parser: &F) -> &'arena Node<'arena>
887    where
888        F: Fn(ParserContext) -> &'arena Node<'arena>,
889    {
890        let Some(current_token) = self.current() else {
891            return self.error(AstNodeError::MissingToken {
892                expected: afmt!(self, "Array"),
893                position: self.position(),
894            });
895        };
896
897        if current_token.kind != TokenKind::Bracket(Bracket::LeftSquareBracket) {
898            return self.error(AstNodeError::UnexpectedToken {
899                expected: afmt!(self, "{}", TokenKind::Bracket(Bracket::LeftSquareBracket)),
900                received: afmt!(self, "{}", current_token.kind),
901                span: current_token.span,
902            });
903        }
904
905        self.next();
906        let mut nodes = BumpVec::new_in(self.bump);
907        while !(self.current().map(|t| t.kind)
908            == Some(TokenKind::Bracket(Bracket::RightSquareBracket)))
909        {
910            if !nodes.is_empty() {
911                expect!(self, TokenKind::Operator(Operator::Comma));
912                if self.current().map(|t| t.kind)
913                    == Some(TokenKind::Bracket(Bracket::RightSquareBracket))
914                {
915                    break;
916                }
917            }
918
919            nodes.push(expression_parser(ParserContext::Global));
920        }
921
922        expect!(self, TokenKind::Bracket(Bracket::RightSquareBracket));
923
924        let node = Node::Array(nodes.into_bump_slice());
925
926        let (node, _) = self.with_postfix(
927            self.node(node, |_| NodeMetadata {
928                span: (current_token.span.0, self.prev_token_end()),
929            }),
930            &expression_parser,
931        );
932        node
933    }
934
935    pub(crate) fn assigned_object<F>(
936        &self,
937        starting_key: &'arena Node<'arena>,
938        expression_parser: &F,
939    ) -> &'arena Node<'arena>
940    where
941        F: Fn(ParserContext) -> &'arena Node<'arena>,
942    {
943        let transform_key = |n: &'arena Node<'arena>| -> &'arena Node<'arena> {
944            let mut keys = BumpVec::new_in(&self.bump);
945            if n.member_key(&mut keys).is_none() {
946                return self.error_with_node(
947                    AstNodeError::Custom {
948                        span: n.span().unwrap_or_default(),
949                        message: self.bump.alloc_str("Failed to resolve"),
950                    },
951                    n,
952                );
953            }
954
955            self.node(
956                Node::String(self.bump.alloc_str(keys.join(".").as_str())),
957                |_| NodeMetadata {
958                    span: n.span().unwrap_or_default(),
959                },
960            )
961        };
962
963        let span_start = self.token_start();
964        expect!(self, TokenKind::Operator(Operator::Assign));
965
966        let mut key_value_pairs = BumpVec::new_in(self.bump);
967        let value = expression_parser(ParserContext::Global);
968
969        key_value_pairs.push((transform_key(starting_key), value));
970        let mut checkpoint_for_return = None;
971
972        loop {
973            if let None = self.current() {
974                break;
975            }
976
977            expect!(self, TokenKind::Operator(Operator::Semi));
978            let Some(identifier_token) = self.current() else {
979                break;
980            };
981
982            let checkpoint = self.position();
983            let identifier_node =
984                self.node(Node::Identifier(identifier_token.value), |_| NodeMetadata {
985                    span: identifier_token.span,
986                });
987            self.next();
988
989            let (key_node, combination) = self.with_postfix(identifier_node, expression_parser);
990            if let Some(_) = self.expect(TokenKind::Operator(Operator::Assign)) {
991                checkpoint_for_return = Some(checkpoint);
992                break;
993            };
994
995            if combination != PostfixCombination::Property
996                && combination != PostfixCombination::Inherit
997            {
998                return self.error_with_node(
999                    AstNodeError::Custom {
1000                        span: key_node.span().unwrap_or_default(),
1001                        message: "Only property access is allowed during assignment",
1002                    },
1003                    key_node,
1004                );
1005            }
1006
1007            let value = expression_parser(ParserContext::Global);
1008            key_value_pairs.push((transform_key(key_node), value));
1009        }
1010
1011        let mut output = None;
1012        if let Some(starting_position) = checkpoint_for_return {
1013            self.set_position(starting_position);
1014            let value = expression_parser(ParserContext::Global);
1015            output.replace(value);
1016        }
1017
1018        self.node(
1019            Node::Assignments {
1020                list: key_value_pairs.into_bump_slice(),
1021                output,
1022            },
1023            |_| NodeMetadata {
1024                span: (span_start, self.prev_token_end()),
1025            },
1026        )
1027    }
1028
1029    pub(crate) fn object<F>(&self, expression_parser: &F) -> &'arena Node<'arena>
1030    where
1031        F: Fn(ParserContext) -> &'arena Node<'arena>,
1032    {
1033        let span_start = self.token_start();
1034        expect!(self, TokenKind::Bracket(Bracket::LeftCurlyBracket));
1035
1036        let mut key_value_pairs = BumpVec::new_in(self.bump);
1037        if let Some(TokenKind::Bracket(Bracket::RightCurlyBracket)) = self.current().map(|t| t.kind)
1038        {
1039            self.next();
1040            return self.node(Node::Object(key_value_pairs.into_bump_slice()), |_| {
1041                NodeMetadata {
1042                    span: (span_start, self.prev_token_end()),
1043                }
1044            });
1045        }
1046
1047        loop {
1048            let key = self.object_key(&expression_parser);
1049            expect!(self, TokenKind::Operator(Operator::Slice));
1050            let value = expression_parser(ParserContext::Global);
1051
1052            key_value_pairs.push((key, value));
1053
1054            let Some(current_token) = self.current() else {
1055                break;
1056            };
1057
1058            match current_token.kind {
1059                TokenKind::Operator(Operator::Comma) => {
1060                    expect!(self, TokenKind::Operator(Operator::Comma));
1061                }
1062                TokenKind::Bracket(Bracket::RightCurlyBracket) => break,
1063                _ => {
1064                    return self.error(AstNodeError::Custom {
1065                        message: afmt!(self, "Invalid object syntax"),
1066                        span: current_token.span,
1067                    })
1068                }
1069            }
1070        }
1071
1072        if let Some(error) = self.expect(TokenKind::Bracket(Bracket::RightCurlyBracket)) {
1073            key_value_pairs.push((
1074                self.node(Node::Null, |_| NodeMetadata {
1075                    span: error.span().unwrap_or_default(),
1076                }),
1077                error,
1078            ));
1079        };
1080
1081        self.node(Node::Object(key_value_pairs.into_bump_slice()), |_| {
1082            NodeMetadata {
1083                span: (span_start, self.prev_token_end()),
1084            }
1085        })
1086    }
1087
1088    pub(crate) fn object_key<F>(&self, expression_parser: &F) -> &'arena Node<'arena>
1089    where
1090        F: Fn(ParserContext) -> &'arena Node<'arena>,
1091    {
1092        let Some(key_token) = self.current() else {
1093            return self.error(AstNodeError::Custom {
1094                message: afmt!(self, "Expected an object key"),
1095                span: (self.prev_token_end(), self.prev_token_end()),
1096            });
1097        };
1098
1099        let key = match key_token.kind {
1100            TokenKind::Identifier(identifier) => {
1101                self.next();
1102                self.node(Node::String(identifier.into()), |_| NodeMetadata {
1103                    span: key_token.span,
1104                })
1105            }
1106            TokenKind::Boolean(boolean) => match boolean {
1107                true => {
1108                    self.next();
1109                    self.node(Node::String("true"), |_| NodeMetadata {
1110                        span: key_token.span,
1111                    })
1112                }
1113                false => {
1114                    self.next();
1115                    self.node(Node::String("false"), |_| NodeMetadata {
1116                        span: key_token.span,
1117                    })
1118                }
1119            },
1120            TokenKind::Number => {
1121                self.next();
1122                self.node(Node::String(key_token.value), |_| NodeMetadata {
1123                    span: key_token.span,
1124                })
1125            }
1126            TokenKind::Literal => {
1127                self.next();
1128                self.node(Node::String(key_token.value), |_| NodeMetadata {
1129                    span: key_token.span,
1130                })
1131            }
1132            TokenKind::Bracket(bracket) => match bracket {
1133                Bracket::LeftSquareBracket => {
1134                    expect!(self, TokenKind::Bracket(Bracket::LeftSquareBracket));
1135                    let token = expression_parser(ParserContext::Global);
1136                    expect!(self, TokenKind::Bracket(Bracket::RightSquareBracket));
1137
1138                    token
1139                }
1140                _ => {
1141                    return self.error(AstNodeError::Custom {
1142                        message: afmt!(self, "Operator is not supported as object key"),
1143                        span: key_token.span,
1144                    })
1145                }
1146            },
1147            TokenKind::QuotationMark(qm) => match qm {
1148                QuotationMark::SingleQuote => self.simple_string(&QuotationMark::SingleQuote),
1149                QuotationMark::DoubleQuote => self.simple_string(&QuotationMark::DoubleQuote),
1150                QuotationMark::Backtick => {
1151                    return self.error(AstNodeError::Custom {
1152                        message: afmt!(
1153                            self,
1154                            "TemplateString expression not supported as object key"
1155                        ),
1156                        span: key_token.span,
1157                    })
1158                }
1159            },
1160            TokenKind::TemplateString(_) => {
1161                return self.error(AstNodeError::Custom {
1162                    message: afmt!(
1163                        self,
1164                        "TemplateString expression not supported as object key"
1165                    ),
1166                    span: key_token.span,
1167                })
1168            }
1169            TokenKind::Operator(_) => {
1170                return self.error(AstNodeError::Custom {
1171                    message: afmt!(self, "Operator is not supported as object key"),
1172                    span: key_token.span,
1173                })
1174            }
1175        };
1176
1177        key
1178    }
1179
1180    /// Conditional
1181    /// condition_node ? on_true : on_false
1182    pub(crate) fn conditional<F>(
1183        &self,
1184        condition: &'arena Node<'arena>,
1185        expression_parser: &F,
1186    ) -> Option<&'arena Node<'arena>>
1187    where
1188        F: Fn(ParserContext) -> &'arena Node<'arena>,
1189    {
1190        let Some(current_token) = self.current() else {
1191            return None;
1192        };
1193        if current_token.kind != TokenKind::Operator(Operator::QuestionMark) {
1194            return None;
1195        }
1196
1197        self.next();
1198
1199        let on_true = expression_parser(ParserContext::Global);
1200        if let Some(error_node) = self.expect(TokenKind::Operator(Operator::Slice)) {
1201            return Some(error_node);
1202        }
1203
1204        let on_false = expression_parser(ParserContext::Global);
1205
1206        let conditional_node = Node::Conditional {
1207            condition,
1208            on_true,
1209            on_false,
1210        };
1211
1212        Some(self.node(conditional_node, |_| NodeMetadata {
1213            span: (current_token.span.0, self.prev_token_end()),
1214        }))
1215    }
1216
1217    /// Literal - number, string, array etc.
1218    pub(crate) fn literal<F>(&self, expression_parser: &F) -> &'arena Node<'arena>
1219    where
1220        F: Fn(ParserContext) -> &'arena Node<'arena>,
1221    {
1222        let Some(current_token) = self.current() else {
1223            return self.error(AstNodeError::Custom {
1224                message: afmt!(self, "Expected a literal"),
1225                span: (self.prev_token_end(), self.prev_token_end()),
1226            });
1227        };
1228
1229        match &current_token.kind {
1230            TokenKind::Identifier(identifier) => match identifier {
1231                Identifier::Null => self.null(),
1232                _ => self.identifier(&expression_parser),
1233            },
1234            TokenKind::Literal => self.identifier(&expression_parser),
1235            TokenKind::Boolean(_) => self.bool(),
1236            TokenKind::Number => self.number(),
1237            TokenKind::QuotationMark(quote_mark) => match quote_mark {
1238                QuotationMark::SingleQuote | QuotationMark::DoubleQuote => {
1239                    self.simple_string(quote_mark)
1240                }
1241                QuotationMark::Backtick => self.template_string(&expression_parser),
1242            },
1243            TokenKind::Bracket(bracket) => match bracket {
1244                Bracket::LeftParenthesis
1245                | Bracket::RightParenthesis
1246                | Bracket::RightSquareBracket => {
1247                    self.interval(&expression_parser).unwrap_or_else(|| {
1248                        self.error(AstNodeError::Custom {
1249                            message: afmt!(self, "Invalid syntax"),
1250                            span: (self.prev_token_end(), self.prev_token_end()),
1251                        })
1252                    })
1253                }
1254                Bracket::LeftSquareBracket => self
1255                    .interval(&expression_parser)
1256                    .unwrap_or_else(|| self.array(&expression_parser)),
1257                Bracket::LeftCurlyBracket => self.object(&expression_parser),
1258                Bracket::RightCurlyBracket => self.error(AstNodeError::Custom {
1259                    message: afmt!(self, "Unexpected RightCurlyBracket token"),
1260                    span: current_token.span,
1261                }),
1262            },
1263            TokenKind::Operator(_) => self.error(AstNodeError::Custom {
1264                message: afmt!(self, "Unexpected Operator token"),
1265                span: current_token.span,
1266            }),
1267            TokenKind::TemplateString(_) => self.error(AstNodeError::Custom {
1268                message: afmt!(self, "Unexpected TemplateString token"),
1269                span: current_token.span,
1270            }),
1271        }
1272    }
1273}
1274
1275fn is_valid_property(token: &Token) -> bool {
1276    match &token.kind {
1277        TokenKind::Identifier(_) => true,
1278        TokenKind::Literal => true,
1279        TokenKind::Operator(operator) => match operator {
1280            Operator::Logical(_) => true,
1281            Operator::Comparison(comparison) => matches!(comparison, ComparisonOperator::In),
1282            _ => false,
1283        },
1284        _ => false,
1285    }
1286}
1287
1288#[derive(Debug)]
1289enum PostfixKind {
1290    PropertyAccess,
1291    ComputedAccess,
1292    Other,
1293}
1294
1295impl From<&Token<'_>> for PostfixKind {
1296    fn from(token: &Token) -> Self {
1297        match &token.kind {
1298            TokenKind::Bracket(Bracket::LeftSquareBracket) => Self::ComputedAccess,
1299            TokenKind::Operator(Operator::Dot) => Self::PropertyAccess,
1300            _ => Self::Other,
1301        }
1302    }
1303}
1304
1305#[derive(Debug, PartialEq)]
1306pub(crate) enum PostfixCombination {
1307    Mixed,
1308    Computed,
1309    Property,
1310    Inherit,
1311}
1312
1313impl PostfixCombination {
1314    fn and(self, other: PostfixCombination) -> Self {
1315        match (self, other) {
1316            (Self::Computed, Self::Computed) => Self::Computed,
1317            (Self::Property, Self::Property) => Self::Property,
1318            (Self::Inherit, other) => other,
1319            _ => Self::Mixed,
1320        }
1321    }
1322}
1323
1324pub(crate) struct MetadataHelper<'a, 'arena> {
1325    node_metadata: &'a HashMap<usize, NodeMetadata, BuildNoHashHasher<usize>>,
1326    arena: PhantomData<&'arena ()>,
1327}
1328
1329impl<'a, 'arena> MetadataHelper<'a, 'arena> {
1330    pub(crate) fn span(
1331        &self,
1332        left: &'arena Node<'arena>,
1333        right: &'arena Node<'arena>,
1334    ) -> Option<(u32, u32)> {
1335        Some((self.metadata(left)?.span.0, self.metadata(right)?.span.1))
1336    }
1337
1338    pub(crate) fn metadata(&self, n: &'arena Node<'arena>) -> Option<&NodeMetadata> {
1339        self.node_metadata.get(&self.address(n))
1340    }
1341
1342    fn address(&self, n: &'arena Node<'arena>) -> usize {
1343        n as *const Node as usize
1344    }
1345}
1346
1347#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1348pub(crate) enum ParserContext {
1349    Global,
1350    Closure,
1351}