hexput_ast_api/
parser.rs

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
8// Define a macro to extract location from an expression
9macro_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
32// Define a macro to extract start line from an expression
33macro_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
56// Define a macro to extract start column from an expression
57macro_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_equality()?;
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_equality()?;
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_comparison(&mut self) -> Result<Expression, ParseError> {
429        let start_location = self.current_location();
430        let mut expr = self.parse_additive()?;
431        
432        while let Some(token_with_span) = self.current_token {
433            expr = match token_with_span.token {
434                Token::Greater => {
435                    self.advance();
436                    let right = self.parse_additive()?;
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                    Expression::BinaryExpression {
447                        left: Box::new(expr),
448                        operator: Operator::Greater,
449                        right: Box::new(right),
450                        location,
451                    }
452                },
453                Token::Less => {
454                    self.advance();
455                    let right = self.parse_additive()?;
456                    let right_loc = get_expr_location!(right);
457                    
458                    let location = SourceLocation::new(
459                        start_location.start_line,
460                        start_location.start_column,
461                        right_loc.end_line,
462                        right_loc.end_column
463                    );
464                    
465                    Expression::BinaryExpression {
466                        left: Box::new(expr),
467                        operator: Operator::Less,
468                        right: Box::new(right),
469                        location,
470                    }
471                },
472                Token::GreaterEqual => {
473                    self.advance();
474                    let right = self.parse_additive()?;
475                    let right_loc = get_expr_location!(right);
476                    
477                    let location = SourceLocation::new(
478                        start_location.start_line,
479                        start_location.start_column,
480                        right_loc.end_line,
481                        right_loc.end_column
482                    );
483                    
484                    Expression::BinaryExpression {
485                        left: Box::new(expr),
486                        operator: Operator::GreaterEqual,
487                        right: Box::new(right),
488                        location,
489                    }
490                },
491                Token::LessEqual => {
492                    self.advance();
493                    let right = self.parse_additive()?;
494                    let right_loc = get_expr_location!(right);
495                    
496                    let location = SourceLocation::new(
497                        start_location.start_line,
498                        start_location.start_column,
499                        right_loc.end_line,
500                        right_loc.end_column
501                    );
502                    
503                    Expression::BinaryExpression {
504                        left: Box::new(expr),
505                        operator: Operator::LessEqual,
506                        right: Box::new(right),
507                        location,
508                    }
509                },
510                _ => break,
511            };
512        }
513        Ok(expr)
514    }
515
516    fn parse_equality(&mut self) -> Result<Expression, ParseError> {
517        let start_location = self.current_location();
518        let mut expr = self.parse_comparison()?;
519        
520        while let Some(token_with_span) = self.current_token {
521            match &token_with_span.token {
522                Token::EqualEqual => {
523                    self.advance();
524                    let right = self.parse_comparison()?;
525                    let right_loc = get_expr_location!(right);
526                    
527                    let location = SourceLocation::new(
528                        start_location.start_line,
529                        start_location.start_column,
530                        right_loc.end_line,
531                        right_loc.end_column
532                    );
533                    
534                    expr = Expression::BinaryExpression {
535                        left: Box::new(expr),
536                        operator: Operator::Equal,
537                        right: Box::new(right),
538                        location,
539                    };
540                }
541                _ => break,
542            }
543        }
544        
545        Ok(expr)
546    }
547
548    fn parse_additive(&mut self) -> Result<Expression, ParseError> {
549        let start_location = self.current_location();
550        let mut expr = self.parse_multiplicative()?;
551
552        while let Some(token_with_span) = self.current_token {
553            match &token_with_span.token {
554                Token::Plus => {
555                    self.advance();
556                    let right = self.parse_multiplicative()?;
557                    let right_loc = get_expr_location!(right);
558                    
559                    let location = SourceLocation::new(
560                        start_location.start_line,
561                        start_location.start_column,
562                        right_loc.end_line,
563                        right_loc.end_column
564                    );
565                    
566                    expr = Expression::BinaryExpression {
567                        left: Box::new(expr),
568                        operator: Operator::Plus,
569                        right: Box::new(right),
570                        location,
571                    };
572                }
573                _ => break,
574            }
575        }
576
577        Ok(expr)
578    }
579    
580    fn parse_multiplicative(&mut self) -> Result<Expression, ParseError> {
581        let start_location = self.current_location();
582        let mut expr = self.parse_unary()?;
583        
584        expr = self.parse_member_access(expr)?;
585
586        while let Some(token_with_span) = self.current_token {
587            match &token_with_span.token {
588                Token::Multiply => {
589                    self.advance();
590                    let right = self.parse_primary()?;
591                    let right_with_member = self.parse_member_access(right)?;
592                    let right_loc = get_expr_location!(right_with_member);
593                    
594                    let location = SourceLocation::new(
595                        start_location.start_line,
596                        start_location.start_column,
597                        right_loc.end_line,
598                        right_loc.end_column
599                    );
600                    
601                    expr = Expression::BinaryExpression {
602                        left: Box::new(expr),
603                        operator: Operator::Multiply,
604                        right: Box::new(right_with_member),
605                        location,
606                    };
607                }
608                Token::Divide => {
609                    self.advance();
610                    let right = self.parse_primary()?;
611                    let right_with_member = self.parse_member_access(right)?;
612                    let right_loc = get_expr_location!(right_with_member);
613                    
614                    let location = SourceLocation::new(
615                        start_location.start_line,
616                        start_location.start_column,
617                        right_loc.end_line,
618                        right_loc.end_column
619                    );
620                    
621                    expr = Expression::BinaryExpression {
622                        left: Box::new(expr),
623                        operator: Operator::Divide,
624                        right: Box::new(right_with_member),
625                        location,
626                    };
627                }
628                _ => break,
629            }
630        }
631
632        Ok(expr)
633    }
634
635    fn parse_unary(&mut self) -> Result<Expression, ParseError> {
636        let start_location = self.current_location();
637        
638        match &self.current_token {
639            Some(token_with_span) => match &token_with_span.token {
640                Token::Bang => {
641                    self.advance();
642                    let operand = self.parse_unary()?;
643                    let operand_loc = get_expr_location!(operand);
644                    
645                    let location = SourceLocation::new(
646                        start_location.start_line,
647                        start_location.start_column,
648                        operand_loc.end_line,
649                        operand_loc.end_column
650                    );
651                    
652                    Ok(Expression::UnaryExpression {
653                        operator: UnaryOperator::Not,
654                        operand: Box::new(operand),
655                        location,
656                    })
657                },
658                _ => self.parse_primary()
659            },
660            None => Err(ParseError::EndOfInput(start_location)),
661        }
662    }
663
664    fn parse_primary(&mut self) -> Result<Expression, ParseError> {
665        let start_location = self.current_location();
666        
667        match &self.current_token {
668            Some(token_with_span) => match &token_with_span.token {
669                Token::KeysOf => {
670                    if self.flags.allow_object_keys {
671                        self.advance();
672                        
673                        // First parse the primary expression
674                        let mut object_expr = self.parse_primary()?;
675                        
676                        // Then handle any member access operations after it
677                        object_expr = self.parse_member_access(object_expr)?;
678                        
679                        let object_loc = get_expr_location!(object_expr);
680                        
681                        let location = SourceLocation::new(
682                            start_location.start_line,
683                            start_location.start_column,
684                            object_loc.end_line,
685                            object_loc.end_column
686                        );
687                        
688                        Ok(Expression::KeysOfExpression {
689                            object: Box::new(object_expr),
690                            location,
691                        })
692                    } else {
693                        Err(ParseError::FeatureDisabled("Object keys operator (keysof)".to_string(), start_location))
694                    }
695                },
696                Token::OpenBracket => {
697                    if self.flags.allow_array_constructions {
698                        self.parse_array_literal(start_location)
699                    } else {
700                        Err(ParseError::FeatureDisabled("Array literals".to_string(), start_location))
701                    }
702                },
703                Token::OpenBrace => {
704                    match self.peek() {
705                        Some(next_token) => match &next_token.token {
706                            Token::Identifier(_) => {
707                                if self.flags.allow_object_constructions {
708                                    self.parse_object_literal(start_location)
709                                } else {
710                                    Err(ParseError::FeatureDisabled("Object literals".to_string(), start_location))
711                                }
712                            },
713                            Token::CloseBrace => {
714                                self.advance();
715                                self.advance();
716                                if self.flags.allow_object_constructions {
717                                    Ok(Expression::ObjectExpression { properties: vec![], location: start_location })
718                                } else {
719                                    Err(ParseError::FeatureDisabled("Object literals".to_string(), start_location))
720                                }
721                            },
722                            _ => {
723                                if self.flags.allow_object_constructions {
724                                    self.parse_object_literal(start_location)
725                                } else {
726                                    Err(ParseError::FeatureDisabled("Object literals".to_string(), start_location))
727                                }
728                            }
729                        },
730                        None => Err(ParseError::EndOfInput(start_location)),
731                    }
732                },
733                Token::OpenParen => {
734                    self.advance();
735                    let expr = self.parse_expression()?;
736                    self.expect(Token::CloseParen)?;
737                    Ok(expr)
738                },
739                Token::Identifier(name) => {
740                    let id_name = name.clone();
741                    self.advance();
742                    
743                    if let Some(next_token) = self.current_token {
744                        if next_token.token == Token::OpenParen {
745                            return self.parse_function_call(id_name, start_location);
746                        }
747                    }
748                    
749                    Ok(Expression::Identifier { 
750                        name: id_name,
751                        location: start_location,
752                    })
753                },
754                Token::StringLiteral(value) => {
755                    let str_value = value.clone();
756                    self.advance();
757                    Ok(Expression::StringLiteral { 
758                        value: str_value,
759                        location: start_location,
760                    })
761                },
762                Token::NumberLiteral(value) => {
763                    let num_value = *value;
764                    self.advance();
765                    Ok(Expression::NumberLiteral { 
766                        value: num_value,
767                        location: start_location,
768                    })
769                },
770                Token::True => {
771                    self.advance();
772                    Ok(Expression::BooleanLiteral { 
773                        value: true,
774                        location: start_location,
775                    })
776                },
777                
778                Token::False => {
779                    self.advance();
780                    Ok(Expression::BooleanLiteral { 
781                        value: false,
782                        location: start_location,
783                    })
784                },
785                
786                Token::Null => {
787                    self.advance();
788                    Ok(Expression::NullLiteral { 
789                        location: start_location,
790                    })
791                },
792                _ => Err(ParseError::UnexpectedToken(format!(
793                    "Unexpected token: {:?}",
794                    token_with_span.token
795                ), start_location)),
796            },
797            None => Err(ParseError::EndOfInput(start_location)),
798        }
799    }
800    
801    fn parse_function_call(&mut self, callee: String, start_location: SourceLocation) -> Result<Expression, ParseError> {
802        self.expect(Token::OpenParen)?;
803        
804        let mut arguments = Vec::new();
805        
806        if let Some(token_with_span) = self.current_token {
807            if token_with_span.token == Token::CloseParen {
808                let end_location = self.current_location();
809                self.advance();
810                
811                let location = SourceLocation::new(
812                    start_location.start_line,
813                    start_location.start_column,
814                    end_location.end_line,
815                    end_location.end_column
816                );
817                
818                return Ok(Expression::CallExpression { callee, arguments, location });
819            }
820        }
821        
822        arguments.push(self.parse_expression()?);
823        
824        while let Some(token_with_span) = self.current_token {
825            match &token_with_span.token {
826                Token::Comma => {
827                    self.advance();
828                    arguments.push(self.parse_expression()?);
829                }
830                Token::CloseParen => {
831                    let end_location = self.current_location();
832                    self.advance();
833                    
834                    let location = SourceLocation::new(
835                        start_location.start_line,
836                        start_location.start_column,
837                        end_location.end_line,
838                        end_location.end_column
839                    );
840                    
841                    return Ok(Expression::CallExpression { callee, arguments, location });
842                }
843                _ => return Err(ParseError::ExpectedToken("',' or ')'".to_string(), self.current_location())),
844            }
845        }
846        
847        Err(ParseError::ExpectedToken("')'".to_string(), self.current_location()))
848    }
849
850    fn parse_callback_declaration(&mut self, start_location: SourceLocation) -> Result<Statement, ParseError> {
851        self.advance();
852
853        let name = match &self.current_token {
854            Some(token_with_span) => match &token_with_span.token {
855                Token::Identifier(name) => name.clone(),
856                _ => return Err(ParseError::ExpectedToken("callback name".to_string(), self.current_location())),
857            },
858            None => return Err(ParseError::EndOfInput(self.current_location())),
859        };
860        self.advance();
861
862        self.expect(Token::OpenParen)?;
863        let mut params = Vec::new();
864        
865        if let Some(token_with_span) = self.current_token {
866            if token_with_span.token == Token::CloseParen {
867                self.advance();
868            } else {
869                if let Some(token_with_span) = self.current_token {
870                    match &token_with_span.token {
871                        Token::Identifier(param) => {
872                            params.push(param.clone());
873                            self.advance();
874                        },
875                        _ => return Err(ParseError::ExpectedToken("parameter name".to_string(), self.current_location())),
876                    }
877                }
878
879                while let Some(token_with_span) = self.current_token {
880                    match &token_with_span.token {
881                        Token::Comma => {
882                            self.advance();
883                            match &self.current_token {
884                                Some(token_with_span) => match &token_with_span.token {
885                                    Token::Identifier(param) => {
886                                        params.push(param.clone());
887                                        self.advance();
888                                    },
889                                    _ => return Err(ParseError::ExpectedToken("parameter name".to_string(), self.current_location())),
890                                },
891                                None => return Err(ParseError::EndOfInput(self.current_location())),
892                            }
893                        },
894                        Token::CloseParen => {
895                            self.advance();
896                            break;
897                        },
898                        _ => return Err(ParseError::ExpectedToken("',' or ')'".to_string(), self.current_location())),
899                    }
900                }
901            }
902        } else {
903            return Err(ParseError::EndOfInput(self.current_location()));
904        }
905
906        let body = self.parse_block()?;
907
908        let end_location = body.location.clone();
909        
910        let location = SourceLocation::new(
911            start_location.start_line,
912            start_location.start_column,
913            end_location.end_line,
914            end_location.end_column
915        );
916
917        Ok(Statement::CallbackDeclaration {
918            name,
919            params,
920            body,
921            location,
922        })
923    }
924
925    fn parse_return_statement(&mut self, start_location: SourceLocation) -> Result<Statement, ParseError> {
926        self.advance();
927
928        let value = self.parse_expression()?;
929        
930        let semicolon_location = self.current_location();
931        self.expect(Token::Semicolon)?;
932
933        let end_location = semicolon_location;
934        
935        let location = SourceLocation::new(
936            start_location.start_line,
937            start_location.start_column,
938            end_location.end_line,
939            end_location.end_column
940        );
941
942        Ok(Statement::ReturnStatement { value, location })
943    }
944
945    fn parse_array_literal(&mut self, start_location: SourceLocation) -> Result<Expression, ParseError> {
946        self.advance();
947        
948        let mut elements = Vec::new();
949        
950        if let Some(token_with_span) = self.current_token {
951            if token_with_span.token == Token::CloseBracket {
952                let end_location = self.current_location();
953                self.advance();
954                
955                let location = SourceLocation::new(
956                    start_location.start_line,
957                    start_location.start_column,
958                    end_location.end_line,
959                    end_location.end_column
960                );
961                
962                return Ok(Expression::ArrayExpression { elements, location });
963            }
964        }
965        
966        elements.push(self.parse_expression()?);
967        
968        while let Some(token_with_span) = self.current_token {
969            match &token_with_span.token {
970                Token::Comma => {
971                    self.advance();
972                    elements.push(self.parse_expression()?);
973                }
974                Token::CloseBracket => {
975                    let end_location = self.current_location();
976                    self.advance();
977                    
978                    let location = SourceLocation::new(
979                        start_location.start_line,
980                        start_location.start_column,
981                        end_location.end_line,
982                        end_location.end_column
983                    );
984                    
985                    return Ok(Expression::ArrayExpression { elements, location });
986                }
987                _ => return Err(ParseError::ExpectedToken("',' or ']'".to_string(), self.current_location())),
988            }
989        }
990        
991        Err(ParseError::ExpectedToken("']'".to_string(), self.current_location()))
992    }
993    
994    fn parse_object_literal(&mut self, start_location: SourceLocation) -> Result<Expression, ParseError> {
995        self.advance();
996        
997        let mut properties = Vec::new();
998        
999        if let Some(token_with_span) = self.current_token {
1000            if token_with_span.token == Token::CloseBrace {
1001                let end_location = self.current_location();
1002                self.advance();
1003                
1004                let location = SourceLocation::new(
1005                    start_location.start_line,
1006                    start_location.start_column,
1007                    end_location.end_line,
1008                    end_location.end_column
1009                );
1010                
1011                return Ok(Expression::ObjectExpression { properties, location });
1012            }
1013        }
1014        
1015        let property = self.parse_object_property()?;
1016        properties.push(property);
1017        
1018        while let Some(token_with_span) = self.current_token {
1019            match &token_with_span.token {
1020                Token::Comma => {
1021                    self.advance();
1022                    let property = self.parse_object_property()?;
1023                    properties.push(property);
1024                }
1025                Token::CloseBrace => {
1026                    let end_location = self.current_location();
1027                    self.advance();
1028                    
1029                    let location = SourceLocation::new(
1030                        start_location.start_line,
1031                        start_location.start_column,
1032                        end_location.end_line,
1033                        end_location.end_column
1034                    );
1035                    
1036                    return Ok(Expression::ObjectExpression { properties, location });
1037                }
1038                _ => return Err(ParseError::ExpectedToken("',' or '}'".to_string(), self.current_location())),
1039            }
1040        }
1041        
1042        Err(ParseError::ExpectedToken("'}'".to_string(), self.current_location()))
1043    }
1044    
1045    fn parse_object_property(&mut self) -> Result<Property, ParseError> {
1046        let start_location = self.current_location();
1047        
1048        let key = match &self.current_token {
1049            Some(token_with_span) => match &token_with_span.token {
1050                Token::Identifier(name) => name.clone(),
1051                Token::StringLiteral(value) => value.clone(),
1052                _ => return Err(ParseError::ExpectedToken("property key".to_string(), self.current_location())),
1053            },
1054            None => return Err(ParseError::EndOfInput(self.current_location())),
1055        };
1056        self.advance();
1057        
1058        self.expect(Token::Colon)?;
1059        
1060        let value = self.parse_expression()?;
1061        
1062        let end_location = get_expr_location!(value);
1063        
1064        let location = SourceLocation::new(
1065            start_location.start_line,
1066            start_location.start_column,
1067            end_location.end_line,
1068            end_location.end_column
1069        );
1070        
1071        Ok(Property::new(key, value, location))
1072    }
1073
1074    fn parse_member_access(&mut self, mut object: Expression) -> Result<Expression, ParseError> {
1075        loop {
1076            match &self.current_token {
1077                Some(token_with_span) => match &token_with_span.token {
1078                    Token::Dot => {
1079                        if !self.flags.allow_object_navigation {
1080                            return Err(ParseError::FeatureDisabled("Object navigation (dot notation)".to_string(), self.current_location()));
1081                        }
1082                        
1083                        self.advance();
1084                        
1085                        match &self.current_token {
1086                            Some(token_with_span) => match &token_with_span.token {
1087                                Token::Identifier(prop_name) => {
1088                                    let property = prop_name.clone();
1089                                    let property_location = self.current_location();
1090                                    self.advance();
1091                                    
1092                                    
1093                                    let obj_start_line = get_expr_start_line!(object);
1094                                    
1095                                    let obj_start_column = get_expr_start_column!(object);
1096                                    
1097                                    
1098                                    if let Some(token_with_span) = self.current_token {
1099                                        if token_with_span.token == Token::OpenParen {
1100                                            self.advance(); 
1101                                            
1102                                            
1103                                            let mut arguments = Vec::new();
1104                                            
1105                                            
1106                                            if let Some(token_with_span) = self.current_token {
1107                                                if token_with_span.token == Token::CloseParen {
1108                                                    
1109                                                    let end_call_location = self.current_location();
1110                                                    self.advance(); 
1111                                                    
1112                                                    
1113                                                    let call_location = SourceLocation::new(
1114                                                        obj_start_line,
1115                                                        obj_start_column,
1116                                                        end_call_location.end_line,
1117                                                        end_call_location.end_column
1118                                                    );
1119                                                    
1120                                                    
1121                                                    object = Expression::MemberCallExpression {
1122                                                        object: Box::new(object),
1123                                                        property: Some(property),
1124                                                        property_expr: None,
1125                                                        computed: false,
1126                                                        arguments,
1127                                                        location: call_location,
1128                                                    };
1129                                                    continue;
1130                                                }
1131                                            }
1132                                            
1133                                            
1134                                            arguments.push(self.parse_expression()?);
1135                                            
1136                                            
1137                                            while let Some(token_with_span) = self.current_token {
1138                                                match &token_with_span.token {
1139                                                    Token::Comma => {
1140                                                        self.advance(); 
1141                                                        arguments.push(self.parse_expression()?);
1142                                                    }
1143                                                    Token::CloseParen => {
1144                                                        let end_call_location = self.current_location();
1145                                                        self.advance(); 
1146                                                        
1147                                                        
1148                                                        let call_location = SourceLocation::new(
1149                                                            obj_start_line,
1150                                                            obj_start_column,
1151                                                            end_call_location.end_line,
1152                                                            end_call_location.end_column
1153                                                        );
1154                                                        
1155                                                        
1156                                                        object = Expression::MemberCallExpression {
1157                                                            object: Box::new(object),
1158                                                            property: Some(property),
1159                                                            property_expr: None,
1160                                                            computed: false,
1161                                                            arguments,
1162                                                            location: call_location,
1163                                                        };
1164                                                        break;
1165                                                    }
1166                                                    _ => return Err(ParseError::ExpectedToken("',' or ')'".to_string(), self.current_location())),
1167                                                }
1168                                            }
1169                                        } else {
1170                                            
1171                                            let member_expr_location = SourceLocation::new(
1172                                                obj_start_line,
1173                                                obj_start_column,
1174                                                property_location.end_line,
1175                                                property_location.end_column
1176                                            );
1177                                            
1178                                            object = Expression::MemberExpression {
1179                                                object: Box::new(object),
1180                                                property: Some(property),
1181                                                property_expr: None,
1182                                                computed: false,
1183                                                location: member_expr_location,
1184                                            };
1185                                        }
1186                                    } else {
1187                                        
1188                                        let member_expr_location = SourceLocation::new(
1189                                            obj_start_line,
1190                                            obj_start_column,
1191                                            property_location.end_line,
1192                                            property_location.end_column
1193                                        );
1194                                        
1195                                        object = Expression::MemberExpression {
1196                                            object: Box::new(object),
1197                                            property: Some(property),
1198                                            property_expr: None,
1199                                            computed: false,
1200                                            location: member_expr_location,
1201                                        };
1202                                    }
1203                                }
1204                                _ => return Err(ParseError::ExpectedToken("property name".to_string(), self.current_location())),
1205                            },
1206                            None => return Err(ParseError::EndOfInput(self.current_location())),
1207                        }
1208                    },
1209                    
1210                    Token::OpenBracket => {
1211                        if !self.flags.allow_object_navigation {
1212                            return Err(ParseError::FeatureDisabled("Object navigation (bracket notation)".to_string(), self.current_location()));
1213                        }
1214                        
1215                        self.advance();
1216                        
1217                        let property_expr = self.parse_expression()?;
1218                        
1219                        let close_bracket_location = self.current_location();
1220                        self.expect(Token::CloseBracket)?;
1221                        
1222                        let obj_start_line = get_expr_start_line!(object);
1223                        
1224                        let obj_start_column = get_expr_start_column!(object);
1225                        
1226                        let member_expr_location = SourceLocation::new(
1227                            obj_start_line,
1228                            obj_start_column,
1229                            close_bracket_location.end_line,
1230                            close_bracket_location.end_column
1231                        );
1232                        
1233                        if let Some(token_with_span) = self.current_token {
1234                            if token_with_span.token == Token::OpenParen {
1235                                
1236                                self.advance();
1237                                
1238                                let mut arguments = Vec::new();
1239                                
1240                                
1241                                if let Some(token_with_span) = self.current_token {
1242                                    if token_with_span.token == Token::CloseParen {
1243                                        let end_call_location = self.current_location();
1244                                        self.advance();
1245                                        
1246                                        let call_location = SourceLocation::new(
1247                                            obj_start_line,
1248                                            obj_start_column,
1249                                            end_call_location.end_line,
1250                                            end_call_location.end_column
1251                                        );
1252                                        
1253                                        
1254                                        object = Expression::MemberCallExpression {
1255                                            object: Box::new(object),
1256                                            property: None,
1257                                            property_expr: Some(Box::new(property_expr)),
1258                                            computed: true,
1259                                            arguments,
1260                                            location: call_location,
1261                                        };
1262                                        continue;
1263                                    }
1264                                }
1265                                
1266                                
1267                                arguments.push(self.parse_expression()?);
1268                                
1269                                while let Some(token_with_span) = self.current_token {
1270                                    match &token_with_span.token {
1271                                        Token::Comma => {
1272                                            self.advance();
1273                                            arguments.push(self.parse_expression()?);
1274                                        }
1275                                        Token::CloseParen => {
1276                                            let end_call_location = self.current_location();
1277                                            self.advance();
1278                                            
1279                                            let call_location = SourceLocation::new(
1280                                                obj_start_line,
1281                                                obj_start_column,
1282                                                end_call_location.end_line,
1283                                                end_call_location.end_column
1284                                            );
1285                                            
1286                                            
1287                                            object = Expression::MemberCallExpression {
1288                                                object: Box::new(object),
1289                                                property: None,
1290                                                property_expr: Some(Box::new(property_expr)),
1291                                                computed: true,
1292                                                arguments,
1293                                                location: call_location,
1294                                            };
1295                                            break;
1296                                        }
1297                                        _ => return Err(ParseError::ExpectedToken("',' or ')'".to_string(), self.current_location())),
1298                                    }
1299                                }
1300                            } else {
1301                                
1302                                object = Expression::MemberExpression {
1303                                    object: Box::new(object),
1304                                    property: None,
1305                                    property_expr: Some(Box::new(property_expr)),
1306                                    computed: true,
1307                                    location: member_expr_location,
1308                                };
1309                            }
1310                        } else {
1311                            
1312                            object = Expression::MemberExpression {
1313                                object: Box::new(object),
1314                                property: None,
1315                                property_expr: Some(Box::new(property_expr)),
1316                                computed: true,
1317                                location: member_expr_location,
1318                            };
1319                        }
1320                    },
1321                    _ => break,
1322                },
1323                None => break,
1324            }
1325        }
1326        Ok(object)
1327    }
1328
1329    fn parse_loop_statement(&mut self, start_location: SourceLocation) -> Result<Statement, ParseError> {
1330        self.advance();
1331        
1332        let variable = match &self.current_token {
1333            Some(token_with_span) => match &token_with_span.token {
1334                Token::Identifier(name) => name.clone(),
1335                _ => return Err(ParseError::ExpectedToken("identifier".to_string(), self.current_location())),
1336            },
1337            None => return Err(ParseError::EndOfInput(self.current_location())),
1338        };
1339        self.advance();
1340        
1341        match &self.current_token {
1342            Some(token_with_span) => {
1343                if token_with_span.token != Token::In {
1344                    return Err(ParseError::ExpectedToken("'in'".to_string(), self.current_location()));
1345                }
1346                self.advance();
1347            },
1348            None => return Err(ParseError::EndOfInput(self.current_location())),
1349        }
1350        
1351        let iterable = self.parse_expression()?;
1352        
1353        let body = self.parse_block()?;
1354        
1355        let end_location = body.location.clone();
1356        
1357        let location = SourceLocation::new(
1358            start_location.start_line,
1359            start_location.start_column,
1360            end_location.end_line,
1361            end_location.end_column
1362        );
1363
1364        Ok(Statement::LoopStatement {
1365            variable,
1366            iterable,
1367            body,
1368            location,
1369        })
1370    }
1371
1372    fn parse_end_statement(&mut self, start_location: SourceLocation) -> Result<Statement, ParseError> {
1373        self.advance();
1374        
1375        let semicolon_location = self.current_location();
1376        self.expect(Token::Semicolon)?;
1377
1378        let end_location = semicolon_location;
1379        
1380        let location = SourceLocation::new(
1381            start_location.start_line,
1382            start_location.start_column,
1383            end_location.end_line,
1384            end_location.end_column
1385        );
1386
1387        Ok(Statement::EndStatement { location })
1388    }
1389    
1390    fn parse_continue_statement(&mut self, start_location: SourceLocation) -> Result<Statement, ParseError> {
1391        self.advance();
1392        
1393        let semicolon_location = self.current_location();
1394        self.expect(Token::Semicolon)?;
1395
1396        let end_location = semicolon_location;
1397        
1398        let location = SourceLocation::new(
1399            start_location.start_line,
1400            start_location.start_column,
1401            end_location.end_line,
1402            end_location.end_column
1403        );
1404
1405        Ok(Statement::ContinueStatement { location })
1406    }
1407}