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 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 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 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 },
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 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 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 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 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 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 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 ¤t_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}