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