mf_expression/parser/
parser.rs

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