1use crate::ast_structs::{Block, Expression, Operator, Program, Property, Statement, SourceLocation, UnaryOperator};
2use crate::feature_flags::FeatureFlags;
3use crate::lexer::{Token, TokenWithSpan};
4use std::fmt;
5use std::iter::Peekable;
6use std::slice::Iter;
7
8macro_rules! get_expr_location {
10 ($expr:expr) => {
11 match &$expr {
12 Expression::StringLiteral { location, .. } |
13 Expression::NumberLiteral { location, .. } |
14 Expression::Identifier { location, .. } |
15 Expression::BinaryExpression { location, .. } |
16 Expression::AssignmentExpression { location, .. } |
17 Expression::MemberAssignmentExpression { location, .. } |
18 Expression::CallExpression { location, .. } |
19 Expression::MemberCallExpression { location, .. } |
20 Expression::CallbackReference { location, .. } |
21 Expression::ArrayExpression { location, .. } |
22 Expression::ObjectExpression { location, .. } |
23 Expression::MemberExpression { location, .. } |
24 Expression::KeysOfExpression { location, .. } |
25 Expression::BooleanLiteral { location, .. } |
26 Expression::UnaryExpression { location, .. } |
27 Expression::NullLiteral { location, .. } => location.clone(),
28 }
29 };
30}
31
32macro_rules! get_expr_start_line {
34 ($expr:expr) => {
35 match &$expr {
36 Expression::StringLiteral { location, .. } |
37 Expression::NumberLiteral { location, .. } |
38 Expression::Identifier { location, .. } |
39 Expression::BinaryExpression { location, .. } |
40 Expression::AssignmentExpression { location, .. } |
41 Expression::MemberAssignmentExpression { location, .. } |
42 Expression::CallExpression { location, .. } |
43 Expression::MemberCallExpression { location, .. } |
44 Expression::CallbackReference { location, .. } |
45 Expression::ArrayExpression { location, .. } |
46 Expression::ObjectExpression { location, .. } |
47 Expression::MemberExpression { location, .. } |
48 Expression::KeysOfExpression { location, .. } |
49 Expression::BooleanLiteral { location, .. } |
50 Expression::UnaryExpression { location, .. } |
51 Expression::NullLiteral { location, .. } => location.start_line,
52 }
53 };
54}
55
56macro_rules! get_expr_start_column {
58 ($expr:expr) => {
59 match &$expr {
60 Expression::StringLiteral { location, .. } |
61 Expression::NumberLiteral { location, .. } |
62 Expression::Identifier { location, .. } |
63 Expression::BinaryExpression { location, .. } |
64 Expression::AssignmentExpression { location, .. } |
65 Expression::MemberAssignmentExpression { location, .. } |
66 Expression::CallExpression { location, .. } |
67 Expression::MemberCallExpression { location, .. } |
68 Expression::CallbackReference { location, .. } |
69 Expression::ArrayExpression { location, .. } |
70 Expression::ObjectExpression { location, .. } |
71 Expression::MemberExpression { location, .. } |
72 Expression::KeysOfExpression { location, .. } |
73 Expression::BooleanLiteral { location, .. } |
74 Expression::UnaryExpression { location, .. } |
75 Expression::NullLiteral { location, .. } => location.start_column,
76 }
77 };
78}
79
80pub struct Parser<'a> {
81 tokens: Peekable<Iter<'a, TokenWithSpan>>,
82 current_token: Option<&'a TokenWithSpan>,
83 flags: FeatureFlags,
84 source_code: &'a str,
85}
86
87#[derive(Debug)]
88pub enum ParseError {
89 UnexpectedToken(String, SourceLocation),
90 ExpectedToken(String, SourceLocation),
91 EndOfInput(SourceLocation),
92 FeatureDisabled(String, SourceLocation),
93}
94
95impl fmt::Display for ParseError {
96 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
97 match self {
98 ParseError::UnexpectedToken(msg, loc) =>
99 write!(f, "Unexpected token: {} at line {}, column {}",
100 msg, loc.start_line, loc.start_column),
101 ParseError::ExpectedToken(msg, loc) =>
102 write!(f, "Expected token: {} at line {}, column {}",
103 msg, loc.start_line, loc.start_column),
104 ParseError::EndOfInput(loc) =>
105 write!(f, "Unexpected end of input at line {}, column {}",
106 loc.start_line, loc.start_column),
107 ParseError::FeatureDisabled(feature, loc) =>
108 write!(f, "Feature disabled: {} is not allowed with current settings at line {}, column {}",
109 feature, loc.start_line, loc.start_column),
110 }
111 }
112}
113
114impl<'a> Parser<'a> {
115 pub fn new(tokens: &'a [TokenWithSpan], flags: FeatureFlags, source_code: &'a str) -> Self {
116 let mut parser = Parser {
117 tokens: tokens.iter().peekable(),
118 current_token: None,
119 flags,
120 source_code,
121 };
122 parser.advance();
123 parser
124 }
125
126 fn current_location(&self) -> SourceLocation {
127 match self.current_token {
128 Some(token) => token.get_location(self.source_code),
129 None => {
130 let end_pos = self.source_code.len();
131 SourceLocation::from_spans(self.source_code, end_pos, end_pos)
132 }
133 }
134 }
135
136 fn advance(&mut self) {
137 self.current_token = self.tokens.next();
138 }
139
140 fn peek(&mut self) -> Option<&&TokenWithSpan> {
141 self.tokens.peek()
142 }
143
144 fn expect(&mut self, expected: Token) -> Result<(), ParseError> {
145 let location = self.current_location();
146 match self.current_token {
147 Some(token_with_span) if token_with_span.token == expected => {
148 self.advance();
149 Ok(())
150 }
151 Some(token_with_span) => Err(ParseError::UnexpectedToken(format!(
152 "Expected {:?}, got {:?}",
153 expected, token_with_span.token
154 ), location)),
155 None => Err(ParseError::EndOfInput(location)),
156 }
157 }
158
159 pub fn parse_program(&mut self) -> Result<Program, ParseError> {
160 let start_location = self.current_location();
161
162 let mut statements = Vec::new();
163
164 while self.current_token.is_some() {
165 let stmt = self.parse_statement()?;
166 statements.push(stmt);
167 }
168
169 let end_location = if let Some(last_token) = self.tokens.clone().last() {
170 last_token.get_location(self.source_code)
171 } else {
172 let end_pos = self.source_code.len();
173 SourceLocation::from_spans(self.source_code, end_pos, end_pos)
174 };
175
176 let program_location = SourceLocation::new(
177 start_location.start_line,
178 start_location.start_column,
179 end_location.end_line,
180 end_location.end_column
181 );
182
183 Ok(Program::new(statements, program_location))
184 }
185
186 fn parse_statement(&mut self) -> Result<Statement, ParseError> {
187 let start_location = self.current_location();
188
189 let stmt = match &self.current_token {
190 Some(token_with_span) => match &token_with_span.token {
191 Token::Vl => {
192 if self.flags.allow_variable_declaration {
193 self.parse_variable_declaration(start_location)
194 } else {
195 Err(ParseError::FeatureDisabled("Variable declarations".to_string(), start_location))
196 }
197 },
198 Token::If => {
199 if self.flags.allow_conditionals {
200 self.parse_if_statement(start_location)
201 } else {
202 Err(ParseError::FeatureDisabled("Conditional statements".to_string(), start_location))
203 }
204 },
205 Token::Loop => {
206 if self.flags.allow_loops {
207 self.parse_loop_statement(start_location)
208 } else {
209 Err(ParseError::FeatureDisabled("Loop statements".to_string(), start_location))
210 }
211 },
212 Token::OpenBrace => self.parse_block_statement(start_location),
213 Token::Cb => {
214 if self.flags.allow_callbacks {
215 self.parse_callback_declaration(start_location)
216 } else {
217 Err(ParseError::FeatureDisabled("Callback declarations".to_string(), start_location))
218 }
219 },
220 Token::Res => {
221 if self.flags.allow_return_statements {
222 self.parse_return_statement(start_location)
223 } else {
224 Err(ParseError::FeatureDisabled("Return statements".to_string(), start_location))
225 }
226 },
227 Token::End => {
228 if self.flags.allow_loop_control {
229 self.parse_end_statement(start_location)
230 } else {
231 Err(ParseError::FeatureDisabled("Loop control statements (end)".to_string(), start_location))
232 }
233 },
234 Token::Continue => {
235 if self.flags.allow_loop_control {
236 self.parse_continue_statement(start_location)
237 } else {
238 Err(ParseError::FeatureDisabled("Loop control statements (continue)".to_string(), start_location))
239 }
240 },
241 _ => {
242 let expr = self.parse_expression()?;
243 let end_location = self.current_location();
244 self.expect(Token::Semicolon)?;
245
246 let location = SourceLocation::new(
247 start_location.start_line,
248 start_location.start_column,
249 end_location.end_line,
250 end_location.end_column
251 );
252
253 Ok(Statement::ExpressionStatement {
254 expression: expr,
255 location
256 })
257 }
258 },
259 None => Err(ParseError::EndOfInput(start_location)),
260 }?;
261
262 Ok(stmt)
263 }
264
265 fn parse_variable_declaration(&mut self, start_location: SourceLocation) -> Result<Statement, ParseError> {
266 self.advance();
267
268 let name = match &self.current_token {
269 Some(token_with_span) => match &token_with_span.token {
270 Token::Identifier(name) => name.clone(),
271 _ => return Err(ParseError::ExpectedToken("identifier".to_string(), self.current_location())),
272 },
273 None => return Err(ParseError::EndOfInput(self.current_location())),
274 };
275 self.advance();
276
277 self.expect(Token::Equal)?;
278
279 let value = self.parse_expression()?;
280
281 let semicolon_location = self.current_location();
282 self.expect(Token::Semicolon)?;
283
284 let end_location = semicolon_location;
285
286 let location = SourceLocation::new(
287 start_location.start_line,
288 start_location.start_column,
289 end_location.end_line,
290 end_location.end_column
291 );
292
293 Ok(Statement::VariableDeclaration { name, value, location })
294 }
295
296 fn parse_if_statement(&mut self, start_location: SourceLocation) -> Result<Statement, ParseError> {
297 self.advance();
298
299 let condition = self.parse_expression()?;
300 let body = self.parse_block()?;
301
302 let else_body = if let Some(token_with_span) = self.current_token {
303 if token_with_span.token == Token::Else {
304 self.advance();
305 Some(self.parse_block()?)
306 } else {
307 None
308 }
309 } else {
310 None
311 };
312
313 let end_location = else_body.as_ref().map_or_else(
314 || body.location.clone(),
315 |else_block| else_block.location.clone()
316 );
317
318 let location = SourceLocation::new(
319 start_location.start_line,
320 start_location.start_column,
321 end_location.end_line,
322 end_location.end_column
323 );
324
325 Ok(Statement::IfStatement {
326 condition,
327 body,
328 else_body,
329 location,
330 })
331 }
332
333 fn parse_block_statement(&mut self, start_location: SourceLocation) -> Result<Statement, ParseError> {
334 let block = self.parse_block()?;
335
336 let end_location = block.location.clone();
337
338 let location = SourceLocation::new(
339 start_location.start_line,
340 start_location.start_column,
341 end_location.end_line,
342 end_location.end_column
343 );
344
345 Ok(Statement::Block { block, location })
346 }
347
348 fn parse_block(&mut self) -> Result<Block, ParseError> {
349 let start_location = self.current_location();
350
351 self.expect(Token::OpenBrace)?;
352
353 let mut statements = Vec::new();
354 while let Some(token_with_span) = self.current_token {
355 if token_with_span.token == Token::CloseBrace {
356 break;
357 }
358 statements.push(self.parse_statement()?);
359 }
360
361 let end_location = self.current_location();
362 self.expect(Token::CloseBrace)?;
363
364 let location = SourceLocation::new(
365 start_location.start_line,
366 start_location.start_column,
367 end_location.end_line,
368 end_location.end_column
369 );
370
371 Ok(Block::new(statements, location))
372 }
373
374 fn parse_expression(&mut self) -> Result<Expression, ParseError> {
375 let expr = self.parse_assignment()?;
376 Ok(expr)
377 }
378
379 fn parse_assignment(&mut self) -> Result<Expression, ParseError> {
380 let start_location = self.current_location();
381 let expr = self.parse_logical_or()?;
382
383 if let Some(token_with_span) = self.current_token {
384 if token_with_span.token == Token::Equal {
385 if !self.flags.allow_assignments {
386 return Err(ParseError::FeatureDisabled("Assignments".to_string(), start_location));
387 }
388
389 self.advance();
390 let value = self.parse_logical_or()?;
391 let end_location = get_expr_location!(value);
392
393 let location = SourceLocation::new(
394 start_location.start_line,
395 start_location.start_column,
396 end_location.end_line,
397 end_location.end_column
398 );
399
400 let new_expr = match expr {
401 Expression::Identifier { name, .. } => Expression::AssignmentExpression {
402 target: name,
403 value: Box::new(value),
404 location,
405 },
406 Expression::MemberExpression { object, property, property_expr, computed, .. } => {
407 if !self.flags.allow_object_navigation {
408 return Err(ParseError::FeatureDisabled("Object property assignment".to_string(), start_location));
409 }
410
411 Expression::MemberAssignmentExpression {
412 object,
413 property,
414 property_expr,
415 computed,
416 value: Box::new(value),
417 location,
418 }
419 },
420 _ => return Err(ParseError::UnexpectedToken("Invalid assignment target".to_string(), start_location)),
421 };
422 return Ok(new_expr);
423 }
424 }
425 Ok(expr)
426 }
427
428 fn parse_logical_or(&mut self) -> Result<Expression, ParseError> {
429 let start_location = self.current_location();
430 let mut expr = self.parse_logical_and()?;
431
432 while let Some(token_with_span) = self.current_token {
433 match &token_with_span.token {
434 Token::Or => {
435 self.advance();
436 let right = self.parse_logical_and()?;
437 let right_loc = get_expr_location!(right);
438
439 let location = SourceLocation::new(
440 start_location.start_line,
441 start_location.start_column,
442 right_loc.end_line,
443 right_loc.end_column
444 );
445
446 expr = Expression::BinaryExpression {
447 left: Box::new(expr),
448 operator: Operator::Or,
449 right: Box::new(right),
450 location,
451 };
452 }
453 _ => break,
454 }
455 }
456
457 Ok(expr)
458 }
459
460 fn parse_logical_and(&mut self) -> Result<Expression, ParseError> {
461 let start_location = self.current_location();
462 let mut expr = self.parse_equality()?;
463
464 while let Some(token_with_span) = self.current_token {
465 match &token_with_span.token {
466 Token::And => {
467 self.advance();
468 let right = self.parse_equality()?;
469 let right_loc = get_expr_location!(right);
470
471 let location = SourceLocation::new(
472 start_location.start_line,
473 start_location.start_column,
474 right_loc.end_line,
475 right_loc.end_column
476 );
477
478 expr = Expression::BinaryExpression {
479 left: Box::new(expr),
480 operator: Operator::And,
481 right: Box::new(right),
482 location,
483 };
484 }
485 _ => break,
486 }
487 }
488
489 Ok(expr)
490 }
491
492 fn parse_comparison(&mut self) -> Result<Expression, ParseError> {
493 let start_location = self.current_location();
494 let mut expr = self.parse_additive()?;
495
496 while let Some(token_with_span) = self.current_token {
497 expr = match token_with_span.token {
498 Token::Greater => {
499 self.advance();
500 let right = self.parse_additive()?;
501 let right_loc = get_expr_location!(right);
502
503 let location = SourceLocation::new(
504 start_location.start_line,
505 start_location.start_column,
506 right_loc.end_line,
507 right_loc.end_column
508 );
509
510 Expression::BinaryExpression {
511 left: Box::new(expr),
512 operator: Operator::Greater,
513 right: Box::new(right),
514 location,
515 }
516 },
517 Token::Less => {
518 self.advance();
519 let right = self.parse_additive()?;
520 let right_loc = get_expr_location!(right);
521
522 let location = SourceLocation::new(
523 start_location.start_line,
524 start_location.start_column,
525 right_loc.end_line,
526 right_loc.end_column
527 );
528
529 Expression::BinaryExpression {
530 left: Box::new(expr),
531 operator: Operator::Less,
532 right: Box::new(right),
533 location,
534 }
535 },
536 Token::GreaterEqual => {
537 self.advance();
538 let right = self.parse_additive()?;
539 let right_loc = get_expr_location!(right);
540
541 let location = SourceLocation::new(
542 start_location.start_line,
543 start_location.start_column,
544 right_loc.end_line,
545 right_loc.end_column
546 );
547
548 Expression::BinaryExpression {
549 left: Box::new(expr),
550 operator: Operator::GreaterEqual,
551 right: Box::new(right),
552 location,
553 }
554 },
555 Token::LessEqual => {
556 self.advance();
557 let right = self.parse_additive()?;
558 let right_loc = get_expr_location!(right);
559
560 let location = SourceLocation::new(
561 start_location.start_line,
562 start_location.start_column,
563 right_loc.end_line,
564 right_loc.end_column
565 );
566
567 Expression::BinaryExpression {
568 left: Box::new(expr),
569 operator: Operator::LessEqual,
570 right: Box::new(right),
571 location,
572 }
573 },
574 _ => break,
575 };
576 }
577 Ok(expr)
578 }
579
580 fn parse_equality(&mut self) -> Result<Expression, ParseError> {
581 let start_location = self.current_location();
582 let mut expr = self.parse_comparison()?;
583
584 while let Some(token_with_span) = self.current_token {
585 match &token_with_span.token {
586 Token::EqualEqual => {
587 self.advance();
588 let right = self.parse_comparison()?;
589 let right_loc = get_expr_location!(right);
590
591 let location = SourceLocation::new(
592 start_location.start_line,
593 start_location.start_column,
594 right_loc.end_line,
595 right_loc.end_column
596 );
597
598 expr = Expression::BinaryExpression {
599 left: Box::new(expr),
600 operator: Operator::Equal,
601 right: Box::new(right),
602 location,
603 };
604 },
605 Token::NotEqual => {
606 self.advance();
607 let right = self.parse_comparison()?;
608 let right_loc = get_expr_location!(right);
609
610 let location = SourceLocation::new(
611 start_location.start_line,
612 start_location.start_column,
613 right_loc.end_line,
614 right_loc.end_column
615 );
616
617 expr = Expression::BinaryExpression {
618 left: Box::new(expr),
619 operator: Operator::NotEqual,
620 right: Box::new(right),
621 location,
622 };
623 }
624 _ => break,
625 }
626 }
627
628 Ok(expr)
629 }
630
631 fn parse_additive(&mut self) -> Result<Expression, ParseError> {
632 let start_location = self.current_location();
633 let mut expr = self.parse_multiplicative()?;
634
635 while let Some(token_with_span) = self.current_token {
636 match &token_with_span.token {
637 Token::Plus => {
638 self.advance();
639 let right = self.parse_multiplicative()?;
640 let right_loc = get_expr_location!(right);
641
642 let location = SourceLocation::new(
643 start_location.start_line,
644 start_location.start_column,
645 right_loc.end_line,
646 right_loc.end_column
647 );
648
649 expr = Expression::BinaryExpression {
650 left: Box::new(expr),
651 operator: Operator::Plus,
652 right: Box::new(right),
653 location,
654 };
655 },
656 Token::Minus => {
657 self.advance();
658 let right = self.parse_multiplicative()?;
659 let right_loc = get_expr_location!(right);
660
661 let location = SourceLocation::new(
662 start_location.start_line,
663 start_location.start_column,
664 right_loc.end_line,
665 right_loc.end_column
666 );
667
668 expr = Expression::BinaryExpression {
669 left: Box::new(expr),
670 operator: Operator::Minus,
671 right: Box::new(right),
672 location,
673 };
674 }
675 _ => break,
676 }
677 }
678
679 Ok(expr)
680 }
681
682 fn parse_multiplicative(&mut self) -> Result<Expression, ParseError> {
683 let start_location = self.current_location();
684 let mut expr = self.parse_unary()?;
685
686 expr = self.parse_member_access(expr)?;
687
688 while let Some(token_with_span) = self.current_token {
689 match &token_with_span.token {
690 Token::Multiply => {
691 self.advance();
692 let right = self.parse_primary()?;
693 let right_with_member = self.parse_member_access(right)?;
694 let right_loc = get_expr_location!(right_with_member);
695
696 let location = SourceLocation::new(
697 start_location.start_line,
698 start_location.start_column,
699 right_loc.end_line,
700 right_loc.end_column
701 );
702
703 expr = Expression::BinaryExpression {
704 left: Box::new(expr),
705 operator: Operator::Multiply,
706 right: Box::new(right_with_member),
707 location,
708 };
709 }
710 Token::Divide => {
711 self.advance();
712 let right = self.parse_primary()?;
713 let right_with_member = self.parse_member_access(right)?;
714 let right_loc = get_expr_location!(right_with_member);
715
716 let location = SourceLocation::new(
717 start_location.start_line,
718 start_location.start_column,
719 right_loc.end_line,
720 right_loc.end_column
721 );
722
723 expr = Expression::BinaryExpression {
724 left: Box::new(expr),
725 operator: Operator::Divide,
726 right: Box::new(right_with_member),
727 location,
728 };
729 }
730 _ => break,
731 }
732 }
733
734 Ok(expr)
735 }
736
737 fn parse_unary(&mut self) -> Result<Expression, ParseError> {
738 let start_location = self.current_location();
739
740 match &self.current_token {
741 Some(token_with_span) => match &token_with_span.token {
742 Token::Bang => {
743 self.advance();
744 let operand = self.parse_unary()?;
745 let operand_loc = get_expr_location!(operand);
746
747 let location = SourceLocation::new(
748 start_location.start_line,
749 start_location.start_column,
750 operand_loc.end_line,
751 operand_loc.end_column
752 );
753
754 Ok(Expression::UnaryExpression {
755 operator: UnaryOperator::Not,
756 operand: Box::new(operand),
757 location,
758 })
759 },
760 _ => self.parse_primary()
761 },
762 None => Err(ParseError::EndOfInput(start_location)),
763 }
764 }
765
766 fn parse_primary(&mut self) -> Result<Expression, ParseError> {
767 let start_location = self.current_location();
768
769 match &self.current_token {
770 Some(token_with_span) => match &token_with_span.token {
771 Token::KeysOf => {
772 if self.flags.allow_object_keys {
773 self.advance();
774
775 let mut object_expr = self.parse_primary()?;
777
778 object_expr = self.parse_member_access(object_expr)?;
780
781 let object_loc = get_expr_location!(object_expr);
782
783 let location = SourceLocation::new(
784 start_location.start_line,
785 start_location.start_column,
786 object_loc.end_line,
787 object_loc.end_column
788 );
789
790 Ok(Expression::KeysOfExpression {
791 object: Box::new(object_expr),
792 location,
793 })
794 } else {
795 Err(ParseError::FeatureDisabled("Object keys operator (keysof)".to_string(), start_location))
796 }
797 },
798 Token::OpenBracket => {
799 if self.flags.allow_array_constructions {
800 self.parse_array_literal(start_location)
801 } else {
802 Err(ParseError::FeatureDisabled("Array literals".to_string(), start_location))
803 }
804 },
805 Token::OpenBrace => {
806 match self.peek() {
807 Some(next_token) => match &next_token.token {
808 Token::Identifier(_) => {
809 if self.flags.allow_object_constructions {
810 self.parse_object_literal(start_location)
811 } else {
812 Err(ParseError::FeatureDisabled("Object literals".to_string(), start_location))
813 }
814 },
815 Token::CloseBrace => {
816 self.advance();
817 self.advance();
818 if self.flags.allow_object_constructions {
819 Ok(Expression::ObjectExpression { properties: vec![], location: start_location })
820 } else {
821 Err(ParseError::FeatureDisabled("Object literals".to_string(), start_location))
822 }
823 },
824 _ => {
825 if self.flags.allow_object_constructions {
826 self.parse_object_literal(start_location)
827 } else {
828 Err(ParseError::FeatureDisabled("Object literals".to_string(), start_location))
829 }
830 }
831 },
832 None => Err(ParseError::EndOfInput(start_location)),
833 }
834 },
835 Token::OpenParen => {
836 self.advance();
837 let expr = self.parse_expression()?;
838 self.expect(Token::CloseParen)?;
839 Ok(expr)
840 },
841 Token::Identifier(name) => {
842 let id_name = name.clone();
843 self.advance();
844
845 if let Some(next_token) = self.current_token {
846 if next_token.token == Token::OpenParen {
847 return self.parse_function_call(id_name, start_location);
848 }
849 }
850
851 Ok(Expression::Identifier {
852 name: id_name,
853 location: start_location,
854 })
855 },
856 Token::StringLiteral(value) => {
857 let str_value = value.clone();
858 self.advance();
859 Ok(Expression::StringLiteral {
860 value: str_value,
861 location: start_location,
862 })
863 },
864 Token::NumberLiteral(value) => {
865 let num_value = *value;
866 self.advance();
867 Ok(Expression::NumberLiteral {
868 value: num_value,
869 location: start_location,
870 })
871 },
872 Token::True => {
873 self.advance();
874 Ok(Expression::BooleanLiteral {
875 value: true,
876 location: start_location,
877 })
878 },
879
880 Token::False => {
881 self.advance();
882 Ok(Expression::BooleanLiteral {
883 value: false,
884 location: start_location,
885 })
886 },
887
888 Token::Null => {
889 self.advance();
890 Ok(Expression::NullLiteral {
891 location: start_location,
892 })
893 },
894 _ => Err(ParseError::UnexpectedToken(format!(
895 "Unexpected token: {:?}",
896 token_with_span.token
897 ), start_location)),
898 },
899 None => Err(ParseError::EndOfInput(start_location)),
900 }
901 }
902
903 fn parse_function_call(&mut self, callee: String, start_location: SourceLocation) -> Result<Expression, ParseError> {
904 self.expect(Token::OpenParen)?;
905
906 let mut arguments = Vec::new();
907
908 if let Some(token_with_span) = self.current_token {
909 if token_with_span.token == Token::CloseParen {
910 let end_location = self.current_location();
911 self.advance();
912
913 let location = SourceLocation::new(
914 start_location.start_line,
915 start_location.start_column,
916 end_location.end_line,
917 end_location.end_column
918 );
919
920 return Ok(Expression::CallExpression { callee, arguments, location });
921 }
922 }
923
924 arguments.push(self.parse_expression()?);
925
926 while let Some(token_with_span) = self.current_token {
927 match &token_with_span.token {
928 Token::Comma => {
929 self.advance();
930 arguments.push(self.parse_expression()?);
931 }
932 Token::CloseParen => {
933 let end_location = self.current_location();
934 self.advance();
935
936 let location = SourceLocation::new(
937 start_location.start_line,
938 start_location.start_column,
939 end_location.end_line,
940 end_location.end_column
941 );
942
943 return Ok(Expression::CallExpression { callee, arguments, location });
944 }
945 _ => return Err(ParseError::ExpectedToken("',' or ')'".to_string(), self.current_location())),
946 }
947 }
948
949 Err(ParseError::ExpectedToken("')'".to_string(), self.current_location()))
950 }
951
952 fn parse_callback_declaration(&mut self, start_location: SourceLocation) -> Result<Statement, ParseError> {
953 self.advance();
954
955 let name = match &self.current_token {
956 Some(token_with_span) => match &token_with_span.token {
957 Token::Identifier(name) => name.clone(),
958 _ => return Err(ParseError::ExpectedToken("callback name".to_string(), self.current_location())),
959 },
960 None => return Err(ParseError::EndOfInput(self.current_location())),
961 };
962 self.advance();
963
964 self.expect(Token::OpenParen)?;
965 let mut params = Vec::new();
966
967 if let Some(token_with_span) = self.current_token {
968 if token_with_span.token == Token::CloseParen {
969 self.advance();
970 } else {
971 if let Some(token_with_span) = self.current_token {
972 match &token_with_span.token {
973 Token::Identifier(param) => {
974 params.push(param.clone());
975 self.advance();
976 },
977 _ => return Err(ParseError::ExpectedToken("parameter name".to_string(), self.current_location())),
978 }
979 }
980
981 while let Some(token_with_span) = self.current_token {
982 match &token_with_span.token {
983 Token::Comma => {
984 self.advance();
985 match &self.current_token {
986 Some(token_with_span) => match &token_with_span.token {
987 Token::Identifier(param) => {
988 params.push(param.clone());
989 self.advance();
990 },
991 _ => return Err(ParseError::ExpectedToken("parameter name".to_string(), self.current_location())),
992 },
993 None => return Err(ParseError::EndOfInput(self.current_location())),
994 }
995 },
996 Token::CloseParen => {
997 self.advance();
998 break;
999 },
1000 _ => return Err(ParseError::ExpectedToken("',' or ')'".to_string(), self.current_location())),
1001 }
1002 }
1003 }
1004 } else {
1005 return Err(ParseError::EndOfInput(self.current_location()));
1006 }
1007
1008 let body = self.parse_block()?;
1009
1010 let end_location = body.location.clone();
1011
1012 let location = SourceLocation::new(
1013 start_location.start_line,
1014 start_location.start_column,
1015 end_location.end_line,
1016 end_location.end_column
1017 );
1018
1019 Ok(Statement::CallbackDeclaration {
1020 name,
1021 params,
1022 body,
1023 location,
1024 })
1025 }
1026
1027 fn parse_return_statement(&mut self, start_location: SourceLocation) -> Result<Statement, ParseError> {
1028 self.advance();
1029
1030 let value = self.parse_expression()?;
1031
1032 let semicolon_location = self.current_location();
1033 self.expect(Token::Semicolon)?;
1034
1035 let end_location = semicolon_location;
1036
1037 let location = SourceLocation::new(
1038 start_location.start_line,
1039 start_location.start_column,
1040 end_location.end_line,
1041 end_location.end_column
1042 );
1043
1044 Ok(Statement::ReturnStatement { value, location })
1045 }
1046
1047 fn parse_array_literal(&mut self, start_location: SourceLocation) -> Result<Expression, ParseError> {
1048 self.advance();
1049
1050 let mut elements = Vec::new();
1051
1052 if let Some(token_with_span) = self.current_token {
1053 if token_with_span.token == Token::CloseBracket {
1054 let end_location = self.current_location();
1055 self.advance();
1056
1057 let location = SourceLocation::new(
1058 start_location.start_line,
1059 start_location.start_column,
1060 end_location.end_line,
1061 end_location.end_column
1062 );
1063
1064 return Ok(Expression::ArrayExpression { elements, location });
1065 }
1066 }
1067
1068 elements.push(self.parse_expression()?);
1069
1070 while let Some(token_with_span) = self.current_token {
1071 match &token_with_span.token {
1072 Token::Comma => {
1073 self.advance();
1074 elements.push(self.parse_expression()?);
1075 }
1076 Token::CloseBracket => {
1077 let end_location = self.current_location();
1078 self.advance();
1079
1080 let location = SourceLocation::new(
1081 start_location.start_line,
1082 start_location.start_column,
1083 end_location.end_line,
1084 end_location.end_column
1085 );
1086
1087 return Ok(Expression::ArrayExpression { elements, location });
1088 }
1089 _ => return Err(ParseError::ExpectedToken("',' or ']'".to_string(), self.current_location())),
1090 }
1091 }
1092
1093 Err(ParseError::ExpectedToken("']'".to_string(), self.current_location()))
1094 }
1095
1096 fn parse_object_literal(&mut self, start_location: SourceLocation) -> Result<Expression, ParseError> {
1097 self.advance();
1098
1099 let mut properties = Vec::new();
1100
1101 if let Some(token_with_span) = self.current_token {
1102 if token_with_span.token == Token::CloseBrace {
1103 let end_location = self.current_location();
1104 self.advance();
1105
1106 let location = SourceLocation::new(
1107 start_location.start_line,
1108 start_location.start_column,
1109 end_location.end_line,
1110 end_location.end_column
1111 );
1112
1113 return Ok(Expression::ObjectExpression { properties, location });
1114 }
1115 }
1116
1117 let property = self.parse_object_property()?;
1118 properties.push(property);
1119
1120 while let Some(token_with_span) = self.current_token {
1121 match &token_with_span.token {
1122 Token::Comma => {
1123 self.advance();
1124 let property = self.parse_object_property()?;
1125 properties.push(property);
1126 }
1127 Token::CloseBrace => {
1128 let end_location = self.current_location();
1129 self.advance();
1130
1131 let location = SourceLocation::new(
1132 start_location.start_line,
1133 start_location.start_column,
1134 end_location.end_line,
1135 end_location.end_column
1136 );
1137
1138 return Ok(Expression::ObjectExpression { properties, location });
1139 }
1140 _ => return Err(ParseError::ExpectedToken("',' or '}'".to_string(), self.current_location())),
1141 }
1142 }
1143
1144 Err(ParseError::ExpectedToken("'}'".to_string(), self.current_location()))
1145 }
1146
1147 fn parse_object_property(&mut self) -> Result<Property, ParseError> {
1148 let start_location = self.current_location();
1149
1150 let key = match &self.current_token {
1151 Some(token_with_span) => match &token_with_span.token {
1152 Token::Identifier(name) => name.clone(),
1153 Token::StringLiteral(value) => value.clone(),
1154 _ => return Err(ParseError::ExpectedToken("property key".to_string(), self.current_location())),
1155 },
1156 None => return Err(ParseError::EndOfInput(self.current_location())),
1157 };
1158 self.advance();
1159
1160 self.expect(Token::Colon)?;
1161
1162 let value = self.parse_expression()?;
1163
1164 let end_location = get_expr_location!(value);
1165
1166 let location = SourceLocation::new(
1167 start_location.start_line,
1168 start_location.start_column,
1169 end_location.end_line,
1170 end_location.end_column
1171 );
1172
1173 Ok(Property::new(key, value, location))
1174 }
1175
1176 fn parse_member_access(&mut self, mut object: Expression) -> Result<Expression, ParseError> {
1177 loop {
1178 match &self.current_token {
1179 Some(token_with_span) => match &token_with_span.token {
1180 Token::Dot => {
1181 if !self.flags.allow_object_navigation {
1182 return Err(ParseError::FeatureDisabled("Object navigation (dot notation)".to_string(), self.current_location()));
1183 }
1184
1185 self.advance();
1186
1187 match &self.current_token {
1188 Some(token_with_span) => match &token_with_span.token {
1189 Token::Identifier(prop_name) => {
1190 let property = prop_name.clone();
1191 let property_location = self.current_location();
1192 self.advance();
1193
1194
1195 let obj_start_line = get_expr_start_line!(object);
1196
1197 let obj_start_column = get_expr_start_column!(object);
1198
1199
1200 if let Some(token_with_span) = self.current_token {
1201 if token_with_span.token == Token::OpenParen {
1202 self.advance();
1203
1204
1205 let mut arguments = Vec::new();
1206
1207
1208 if let Some(token_with_span) = self.current_token {
1209 if token_with_span.token == Token::CloseParen {
1210
1211 let end_call_location = self.current_location();
1212 self.advance();
1213
1214
1215 let call_location = SourceLocation::new(
1216 obj_start_line,
1217 obj_start_column,
1218 end_call_location.end_line,
1219 end_call_location.end_column
1220 );
1221
1222
1223 object = Expression::MemberCallExpression {
1224 object: Box::new(object),
1225 property: Some(property),
1226 property_expr: None,
1227 computed: false,
1228 arguments,
1229 location: call_location,
1230 };
1231 continue;
1232 }
1233 }
1234
1235
1236 arguments.push(self.parse_expression()?);
1237
1238
1239 while let Some(token_with_span) = self.current_token {
1240 match &token_with_span.token {
1241 Token::Comma => {
1242 self.advance();
1243 arguments.push(self.parse_expression()?);
1244 }
1245 Token::CloseParen => {
1246 let end_call_location = self.current_location();
1247 self.advance();
1248
1249
1250 let call_location = SourceLocation::new(
1251 obj_start_line,
1252 obj_start_column,
1253 end_call_location.end_line,
1254 end_call_location.end_column
1255 );
1256
1257
1258 object = Expression::MemberCallExpression {
1259 object: Box::new(object),
1260 property: Some(property),
1261 property_expr: None,
1262 computed: false,
1263 arguments,
1264 location: call_location,
1265 };
1266 break;
1267 }
1268 _ => return Err(ParseError::ExpectedToken("',' or ')'".to_string(), self.current_location())),
1269 }
1270 }
1271 } else {
1272
1273 let member_expr_location = SourceLocation::new(
1274 obj_start_line,
1275 obj_start_column,
1276 property_location.end_line,
1277 property_location.end_column
1278 );
1279
1280 object = Expression::MemberExpression {
1281 object: Box::new(object),
1282 property: Some(property),
1283 property_expr: None,
1284 computed: false,
1285 location: member_expr_location,
1286 };
1287 }
1288 } else {
1289
1290 let member_expr_location = SourceLocation::new(
1291 obj_start_line,
1292 obj_start_column,
1293 property_location.end_line,
1294 property_location.end_column
1295 );
1296
1297 object = Expression::MemberExpression {
1298 object: Box::new(object),
1299 property: Some(property),
1300 property_expr: None,
1301 computed: false,
1302 location: member_expr_location,
1303 };
1304 }
1305 }
1306 _ => return Err(ParseError::ExpectedToken("property name".to_string(), self.current_location())),
1307 },
1308 None => return Err(ParseError::EndOfInput(self.current_location())),
1309 }
1310 },
1311
1312 Token::OpenBracket => {
1313 if !self.flags.allow_object_navigation {
1314 return Err(ParseError::FeatureDisabled("Object navigation (bracket notation)".to_string(), self.current_location()));
1315 }
1316
1317 self.advance();
1318
1319 let property_expr = self.parse_expression()?;
1320
1321 let close_bracket_location = self.current_location();
1322 self.expect(Token::CloseBracket)?;
1323
1324 let obj_start_line = get_expr_start_line!(object);
1325
1326 let obj_start_column = get_expr_start_column!(object);
1327
1328 let member_expr_location = SourceLocation::new(
1329 obj_start_line,
1330 obj_start_column,
1331 close_bracket_location.end_line,
1332 close_bracket_location.end_column
1333 );
1334
1335 if let Some(token_with_span) = self.current_token {
1336 if token_with_span.token == Token::OpenParen {
1337
1338 self.advance();
1339
1340 let mut arguments = Vec::new();
1341
1342
1343 if let Some(token_with_span) = self.current_token {
1344 if token_with_span.token == Token::CloseParen {
1345 let end_call_location = self.current_location();
1346 self.advance();
1347
1348 let call_location = SourceLocation::new(
1349 obj_start_line,
1350 obj_start_column,
1351 end_call_location.end_line,
1352 end_call_location.end_column
1353 );
1354
1355
1356 object = Expression::MemberCallExpression {
1357 object: Box::new(object),
1358 property: None,
1359 property_expr: Some(Box::new(property_expr)),
1360 computed: true,
1361 arguments,
1362 location: call_location,
1363 };
1364 continue;
1365 }
1366 }
1367
1368
1369 arguments.push(self.parse_expression()?);
1370
1371 while let Some(token_with_span) = self.current_token {
1372 match &token_with_span.token {
1373 Token::Comma => {
1374 self.advance();
1375 arguments.push(self.parse_expression()?);
1376 }
1377 Token::CloseParen => {
1378 let end_call_location = self.current_location();
1379 self.advance();
1380
1381 let call_location = SourceLocation::new(
1382 obj_start_line,
1383 obj_start_column,
1384 end_call_location.end_line,
1385 end_call_location.end_column
1386 );
1387
1388
1389 object = Expression::MemberCallExpression {
1390 object: Box::new(object),
1391 property: None,
1392 property_expr: Some(Box::new(property_expr)),
1393 computed: true,
1394 arguments,
1395 location: call_location,
1396 };
1397 break;
1398 }
1399 _ => return Err(ParseError::ExpectedToken("',' or ')'".to_string(), self.current_location())),
1400 }
1401 }
1402 } else {
1403
1404 object = Expression::MemberExpression {
1405 object: Box::new(object),
1406 property: None,
1407 property_expr: Some(Box::new(property_expr)),
1408 computed: true,
1409 location: member_expr_location,
1410 };
1411 }
1412 } else {
1413
1414 object = Expression::MemberExpression {
1415 object: Box::new(object),
1416 property: None,
1417 property_expr: Some(Box::new(property_expr)),
1418 computed: true,
1419 location: member_expr_location,
1420 };
1421 }
1422 },
1423 _ => break,
1424 },
1425 None => break,
1426 }
1427 }
1428 Ok(object)
1429 }
1430
1431 fn parse_loop_statement(&mut self, start_location: SourceLocation) -> Result<Statement, ParseError> {
1432 self.advance();
1433
1434 let variable = match &self.current_token {
1435 Some(token_with_span) => match &token_with_span.token {
1436 Token::Identifier(name) => name.clone(),
1437 _ => return Err(ParseError::ExpectedToken("identifier".to_string(), self.current_location())),
1438 },
1439 None => return Err(ParseError::EndOfInput(self.current_location())),
1440 };
1441 self.advance();
1442
1443 match &self.current_token {
1444 Some(token_with_span) => {
1445 if token_with_span.token != Token::In {
1446 return Err(ParseError::ExpectedToken("'in'".to_string(), self.current_location()));
1447 }
1448 self.advance();
1449 },
1450 None => return Err(ParseError::EndOfInput(self.current_location())),
1451 }
1452
1453 let iterable = self.parse_expression()?;
1454
1455 let body = self.parse_block()?;
1456
1457 let end_location = body.location.clone();
1458
1459 let location = SourceLocation::new(
1460 start_location.start_line,
1461 start_location.start_column,
1462 end_location.end_line,
1463 end_location.end_column
1464 );
1465
1466 Ok(Statement::LoopStatement {
1467 variable,
1468 iterable,
1469 body,
1470 location,
1471 })
1472 }
1473
1474 fn parse_end_statement(&mut self, start_location: SourceLocation) -> Result<Statement, ParseError> {
1475 self.advance();
1476
1477 let semicolon_location = self.current_location();
1478 self.expect(Token::Semicolon)?;
1479
1480 let end_location = semicolon_location;
1481
1482 let location = SourceLocation::new(
1483 start_location.start_line,
1484 start_location.start_column,
1485 end_location.end_line,
1486 end_location.end_column
1487 );
1488
1489 Ok(Statement::EndStatement { location })
1490 }
1491
1492 fn parse_continue_statement(&mut self, start_location: SourceLocation) -> Result<Statement, ParseError> {
1493 self.advance();
1494
1495 let semicolon_location = self.current_location();
1496 self.expect(Token::Semicolon)?;
1497
1498 let end_location = semicolon_location;
1499
1500 let location = SourceLocation::new(
1501 start_location.start_line,
1502 start_location.start_column,
1503 end_location.end_line,
1504 end_location.end_column
1505 );
1506
1507 Ok(Statement::ContinueStatement { location })
1508 }
1509}