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_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                        // First parse the primary expression
776                        let mut object_expr = self.parse_primary()?;
777                        
778                        // Then handle any member access operations after it
779                        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}