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::InlineCallbackExpression { 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::InlineCallbackExpression { 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::InlineCallbackExpression { 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        // Parse first argument - check for inline callback
925        if let Some(token_with_span) = self.current_token {
926            if token_with_span.token == Token::Cb {
927                if !self.flags.allow_callbacks {
928                    return Err(ParseError::FeatureDisabled("Inline callback expressions".to_string(), self.current_location()));
929                }
930                let inline_callback = self.parse_inline_callback()?;
931                arguments.push(inline_callback);
932            } else {
933                arguments.push(self.parse_expression()?);
934            }
935        }
936        
937        // Parse remaining arguments
938        while let Some(token_with_span) = self.current_token {
939            match &token_with_span.token {
940                Token::Comma => {
941                    self.advance();
942                    
943                    // Check for inline callback syntax after comma
944                    if let Some(token_with_span) = self.current_token {
945                        if token_with_span.token == Token::Cb {
946                            if !self.flags.allow_callbacks {
947                                return Err(ParseError::FeatureDisabled("Inline callback expressions".to_string(), self.current_location()));
948                            }
949                            let inline_callback = self.parse_inline_callback()?;
950                            arguments.push(inline_callback);
951                        } else {
952                            arguments.push(self.parse_expression()?);
953                        }
954                    } else {
955                        return Err(ParseError::EndOfInput(self.current_location()));
956                    }
957                }
958                Token::CloseParen => {
959                    let end_location = self.current_location();
960                    self.advance();
961                    
962                    let location = SourceLocation::new(
963                        start_location.start_line,
964                        start_location.start_column,
965                        end_location.end_line,
966                        end_location.end_column
967                    );
968                    
969                    return Ok(Expression::CallExpression { callee, arguments, location });
970                }
971                _ => return Err(ParseError::ExpectedToken("',' or ')'".to_string(), self.current_location())),
972            }
973        }
974        
975        Err(ParseError::ExpectedToken("')'".to_string(), self.current_location()))
976    }
977
978    fn parse_inline_callback(&mut self) -> Result<Expression, ParseError> {
979        let start_location = self.current_location();
980        self.advance(); // consume 'cb'
981
982        let name = match &self.current_token {
983            Some(token_with_span) => match &token_with_span.token {
984                Token::Identifier(name) => name.clone(),
985                _ => return Err(ParseError::ExpectedToken("callback name".to_string(), self.current_location())),
986            },
987            None => return Err(ParseError::EndOfInput(self.current_location())),
988        };
989        self.advance();
990
991        self.expect(Token::OpenParen)?;
992        let mut params = Vec::new();
993        
994        if let Some(token_with_span) = self.current_token {
995            if token_with_span.token == Token::CloseParen {
996                self.advance();
997            } else {
998                if let Some(token_with_span) = self.current_token {
999                    match &token_with_span.token {
1000                        Token::Identifier(param) => {
1001                            params.push(param.clone());
1002                            self.advance();
1003                        },
1004                        _ => return Err(ParseError::ExpectedToken("parameter name".to_string(), self.current_location())),
1005                    }
1006                }
1007
1008                while let Some(token_with_span) = self.current_token {
1009                    match &token_with_span.token {
1010                        Token::Comma => {
1011                            self.advance();
1012                            match &self.current_token {
1013                                Some(token_with_span) => match &token_with_span.token {
1014                                    Token::Identifier(param) => {
1015                                        params.push(param.clone());
1016                                        self.advance();
1017                                    },
1018                                    _ => return Err(ParseError::ExpectedToken("parameter name".to_string(), self.current_location())),
1019                                },
1020                                None => return Err(ParseError::EndOfInput(self.current_location())),
1021                            }
1022                        },
1023                        Token::CloseParen => {
1024                            self.advance();
1025                            break;
1026                        },
1027                        _ => return Err(ParseError::ExpectedToken("',' or ')'".to_string(), self.current_location())),
1028                    }
1029                }
1030            }
1031        } else {
1032            return Err(ParseError::EndOfInput(self.current_location()));
1033        }
1034
1035        let body = self.parse_block()?;
1036
1037        let end_location = body.location.clone();
1038        
1039        let location = SourceLocation::new(
1040            start_location.start_line,
1041            start_location.start_column,
1042            end_location.end_line,
1043            end_location.end_column
1044        );
1045
1046        Ok(Expression::InlineCallbackExpression {
1047            name,
1048            params,
1049            body,
1050            location,
1051        })
1052    }
1053
1054    fn parse_callback_declaration(&mut self, start_location: SourceLocation) -> Result<Statement, ParseError> {
1055        self.advance();
1056
1057        let name = match &self.current_token {
1058            Some(token_with_span) => match &token_with_span.token {
1059                Token::Identifier(name) => name.clone(),
1060                _ => return Err(ParseError::ExpectedToken("callback name".to_string(), self.current_location())),
1061            },
1062            None => return Err(ParseError::EndOfInput(self.current_location())),
1063        };
1064        self.advance();
1065
1066        self.expect(Token::OpenParen)?;
1067        let mut params = Vec::new();
1068        
1069        if let Some(token_with_span) = self.current_token {
1070            if token_with_span.token == Token::CloseParen {
1071                self.advance();
1072            } else {
1073                if let Some(token_with_span) = self.current_token {
1074                    match &token_with_span.token {
1075                        Token::Identifier(param) => {
1076                            params.push(param.clone());
1077                            self.advance();
1078                        },
1079                        _ => return Err(ParseError::ExpectedToken("parameter name".to_string(), self.current_location())),
1080                    }
1081                }
1082
1083                while let Some(token_with_span) = self.current_token {
1084                    match &token_with_span.token {
1085                        Token::Comma => {
1086                            self.advance();
1087                            match &self.current_token {
1088                                Some(token_with_span) => match &token_with_span.token {
1089                                    Token::Identifier(param) => {
1090                                        params.push(param.clone());
1091                                        self.advance();
1092                                    },
1093                                    _ => return Err(ParseError::ExpectedToken("parameter name".to_string(), self.current_location())),
1094                                },
1095                                None => return Err(ParseError::EndOfInput(self.current_location())),
1096                            }
1097                        },
1098                        Token::CloseParen => {
1099                            self.advance();
1100                            break;
1101                        },
1102                        _ => return Err(ParseError::ExpectedToken("',' or ')'".to_string(), self.current_location())),
1103                    }
1104                }
1105            }
1106        } else {
1107            return Err(ParseError::EndOfInput(self.current_location()));
1108        }
1109
1110        let body = self.parse_block()?;
1111
1112        let end_location = body.location.clone();
1113        
1114        let location = SourceLocation::new(
1115            start_location.start_line,
1116            start_location.start_column,
1117            end_location.end_line,
1118            end_location.end_column
1119        );
1120
1121        Ok(Statement::CallbackDeclaration {
1122            name,
1123            params,
1124            body,
1125            location,
1126        })
1127    }
1128
1129    fn parse_return_statement(&mut self, start_location: SourceLocation) -> Result<Statement, ParseError> {
1130        self.advance();
1131
1132        let value = self.parse_expression()?;
1133        
1134        let semicolon_location = self.current_location();
1135        self.expect(Token::Semicolon)?;
1136
1137        let end_location = semicolon_location;
1138        
1139        let location = SourceLocation::new(
1140            start_location.start_line,
1141            start_location.start_column,
1142            end_location.end_line,
1143            end_location.end_column
1144        );
1145
1146        Ok(Statement::ReturnStatement { value, location })
1147    }
1148
1149    fn parse_array_literal(&mut self, start_location: SourceLocation) -> Result<Expression, ParseError> {
1150        self.advance();
1151        
1152        let mut elements = Vec::new();
1153        
1154        if let Some(token_with_span) = self.current_token {
1155            if token_with_span.token == Token::CloseBracket {
1156                let end_location = self.current_location();
1157                self.advance();
1158                
1159                let location = SourceLocation::new(
1160                    start_location.start_line,
1161                    start_location.start_column,
1162                    end_location.end_line,
1163                    end_location.end_column
1164                );
1165                
1166                return Ok(Expression::ArrayExpression { elements, location });
1167            }
1168        }
1169        
1170        elements.push(self.parse_expression()?);
1171        
1172        while let Some(token_with_span) = self.current_token {
1173            match &token_with_span.token {
1174                Token::Comma => {
1175                    self.advance();
1176                    elements.push(self.parse_expression()?);
1177                }
1178                Token::CloseBracket => {
1179                    let end_location = self.current_location();
1180                    self.advance();
1181                    
1182                    let location = SourceLocation::new(
1183                        start_location.start_line,
1184                        start_location.start_column,
1185                        end_location.end_line,
1186                        end_location.end_column
1187                    );
1188                    
1189                    return Ok(Expression::ArrayExpression { elements, location });
1190                }
1191                _ => return Err(ParseError::ExpectedToken("',' or ']'".to_string(), self.current_location())),
1192            }
1193        }
1194        
1195        Err(ParseError::ExpectedToken("']'".to_string(), self.current_location()))
1196    }
1197    
1198    fn parse_object_literal(&mut self, start_location: SourceLocation) -> Result<Expression, ParseError> {
1199        self.advance();
1200        
1201        let mut properties = Vec::new();
1202        
1203        if let Some(token_with_span) = self.current_token {
1204            if token_with_span.token == Token::CloseBrace {
1205                let end_location = self.current_location();
1206                self.advance();
1207                
1208                let location = SourceLocation::new(
1209                    start_location.start_line,
1210                    start_location.start_column,
1211                    end_location.end_line,
1212                    end_location.end_column
1213                );
1214                
1215                return Ok(Expression::ObjectExpression { properties, location });
1216            }
1217        }
1218        
1219        let property = self.parse_object_property()?;
1220        properties.push(property);
1221        
1222        while let Some(token_with_span) = self.current_token {
1223            match &token_with_span.token {
1224                Token::Comma => {
1225                    self.advance();
1226                    let property = self.parse_object_property()?;
1227                    properties.push(property);
1228                }
1229                Token::CloseBrace => {
1230                    let end_location = self.current_location();
1231                    self.advance();
1232                    
1233                    let location = SourceLocation::new(
1234                        start_location.start_line,
1235                        start_location.start_column,
1236                        end_location.end_line,
1237                        end_location.end_column
1238                    );
1239                    
1240                    return Ok(Expression::ObjectExpression { properties, location });
1241                }
1242                _ => return Err(ParseError::ExpectedToken("',' or '}'".to_string(), self.current_location())),
1243            }
1244        }
1245        
1246        Err(ParseError::ExpectedToken("'}'".to_string(), self.current_location()))
1247    }
1248    
1249    fn parse_object_property(&mut self) -> Result<Property, ParseError> {
1250        let start_location = self.current_location();
1251        
1252        let key = match &self.current_token {
1253            Some(token_with_span) => match &token_with_span.token {
1254                Token::Identifier(name) => name.clone(),
1255                Token::StringLiteral(value) => value.clone(),
1256                _ => return Err(ParseError::ExpectedToken("property key".to_string(), self.current_location())),
1257            },
1258            None => return Err(ParseError::EndOfInput(self.current_location())),
1259        };
1260        self.advance();
1261        
1262        self.expect(Token::Colon)?;
1263        
1264        let value = self.parse_expression()?;
1265        
1266        let end_location = get_expr_location!(value);
1267        
1268        let location = SourceLocation::new(
1269            start_location.start_line,
1270            start_location.start_column,
1271            end_location.end_line,
1272            end_location.end_column
1273        );
1274        
1275        Ok(Property::new(key, value, location))
1276    }
1277
1278    fn parse_member_access(&mut self, mut object: Expression) -> Result<Expression, ParseError> {
1279        loop {
1280            match &self.current_token {
1281                Some(token_with_span) => match &token_with_span.token {
1282                    Token::Dot => {
1283                        if !self.flags.allow_object_navigation {
1284                            return Err(ParseError::FeatureDisabled("Object navigation (dot notation)".to_string(), self.current_location()));
1285                        }
1286                        
1287                        self.advance();
1288                        
1289                        match &self.current_token {
1290                            Some(token_with_span) => match &token_with_span.token {
1291                                Token::Identifier(prop_name) => {
1292                                    let property = prop_name.clone();
1293                                    let property_location = self.current_location();
1294                                    self.advance();
1295                                    
1296                                    let obj_start_line = get_expr_start_line!(object);
1297                                    let obj_start_column = get_expr_start_column!(object);
1298                                    
1299                                    if let Some(token_with_span) = self.current_token {
1300                                        if token_with_span.token == Token::OpenParen {
1301                                            self.advance(); 
1302                                            
1303                                            let mut arguments = Vec::new();
1304                                            
1305                                            // Handle empty argument list
1306                                            if let Some(token_with_span) = self.current_token {
1307                                                if token_with_span.token == Token::CloseParen {
1308                                                    let end_call_location = self.current_location();
1309                                                    self.advance(); 
1310                                                    
1311                                                    let call_location = SourceLocation::new(
1312                                                        obj_start_line,
1313                                                        obj_start_column,
1314                                                        end_call_location.end_line,
1315                                                        end_call_location.end_column
1316                                                    );
1317                                                    
1318                                                    object = Expression::MemberCallExpression {
1319                                                        object: Box::new(object),
1320                                                        property: Some(property),
1321                                                        property_expr: None,
1322                                                        computed: false,
1323                                                        arguments,
1324                                                        location: call_location,
1325                                                    };
1326                                                    continue;
1327                                                }
1328                                            }
1329                                            
1330                                            // Parse first argument - check for inline callback
1331                                            if let Some(token_with_span) = self.current_token {
1332                                                if token_with_span.token == Token::Cb {
1333                                                    if !self.flags.allow_callbacks {
1334                                                        return Err(ParseError::FeatureDisabled("Inline callback expressions".to_string(), self.current_location()));
1335                                                    }
1336                                                    let inline_callback = self.parse_inline_callback()?;
1337                                                    arguments.push(inline_callback);
1338                                                } else {
1339                                                    arguments.push(self.parse_expression()?);
1340                                                }
1341                                            } else {
1342                                                return Err(ParseError::EndOfInput(self.current_location()));
1343                                            }
1344                                            
1345                                            // Parse remaining arguments
1346                                            while let Some(token_with_span) = self.current_token {
1347                                                match &token_with_span.token {
1348                                                    Token::Comma => {
1349                                                        self.advance(); 
1350                                                        
1351                                                        // Check for inline callback syntax after comma
1352                                                        if let Some(token_with_span) = self.current_token {
1353                                                            if token_with_span.token == Token::Cb {
1354                                                                if !self.flags.allow_callbacks {
1355                                                                    return Err(ParseError::FeatureDisabled("Inline callback expressions".to_string(), self.current_location()));
1356                                                                }
1357                                                                let inline_callback = self.parse_inline_callback()?;
1358                                                                arguments.push(inline_callback);
1359                                                            } else {
1360                                                                arguments.push(self.parse_expression()?);
1361                                                            }
1362                                                        } else {
1363                                                            return Err(ParseError::EndOfInput(self.current_location()));
1364                                                        }
1365                                                    }
1366                                                    Token::CloseParen => {
1367                                                        let end_call_location = self.current_location();
1368                                                        self.advance(); 
1369                                                        
1370                                                        let call_location = SourceLocation::new(
1371                                                            obj_start_line,
1372                                                            obj_start_column,
1373                                                            end_call_location.end_line,
1374                                                            end_call_location.end_column
1375                                                        );
1376                                                        
1377                                                        object = Expression::MemberCallExpression {
1378                                                            object: Box::new(object),
1379                                                            property: Some(property),
1380                                                            property_expr: None,
1381                                                            computed: false,
1382                                                            arguments,
1383                                                            location: call_location,
1384                                                        };
1385                                                        break;
1386                                                    }
1387                                                    _ => return Err(ParseError::ExpectedToken("',' or ')'".to_string(), self.current_location())),
1388                                                }
1389                                            }
1390                                        } else {
1391                                            // Regular member expression (not a call)
1392                                            let member_expr_location = SourceLocation::new(
1393                                                obj_start_line,
1394                                                obj_start_column,
1395                                                property_location.end_line,
1396                                                property_location.end_column
1397                                            );
1398                                            
1399                                            object = Expression::MemberExpression {
1400                                                object: Box::new(object),
1401                                                property: Some(property),
1402                                                property_expr: None,
1403                                                computed: false,
1404                                                location: member_expr_location,
1405                                            };
1406                                        }
1407                                    } else {
1408                                        // Regular member expression (not a call)
1409                                        let member_expr_location = SourceLocation::new(
1410                                            obj_start_line,
1411                                            obj_start_column,
1412                                            property_location.end_line,
1413                                            property_location.end_column
1414                                        );
1415                                        
1416                                        object = Expression::MemberExpression {
1417                                            object: Box::new(object),
1418                                            property: Some(property),
1419                                            property_expr: None,
1420                                            computed: false,
1421                                            location: member_expr_location,
1422                                        };
1423                                    }
1424                                }
1425                                _ => return Err(ParseError::ExpectedToken("property name".to_string(), self.current_location())),
1426                            },
1427                            None => return Err(ParseError::EndOfInput(self.current_location())),
1428                        }
1429                    },
1430                    
1431                    Token::OpenBracket => {
1432                        if !self.flags.allow_object_navigation {
1433                            return Err(ParseError::FeatureDisabled("Object navigation (bracket notation)".to_string(), self.current_location()));
1434                        }
1435                        
1436                        self.advance();
1437                        
1438                        let property_expr = self.parse_expression()?;
1439                        
1440                        let close_bracket_location = self.current_location();
1441                        self.expect(Token::CloseBracket)?;
1442                        
1443                        let obj_start_line = get_expr_start_line!(object);
1444                        let obj_start_column = get_expr_start_column!(object);
1445                        
1446                        let member_expr_location = SourceLocation::new(
1447                            obj_start_line,
1448                            obj_start_column,
1449                            close_bracket_location.end_line,
1450                            close_bracket_location.end_column
1451                        );
1452                        
1453                        if let Some(token_with_span) = self.current_token {
1454                            if token_with_span.token == Token::OpenParen {
1455                                self.advance();
1456                                
1457                                let mut arguments = Vec::new();
1458                                
1459                                // Handle empty argument list
1460                                if let Some(token_with_span) = self.current_token {
1461                                    if token_with_span.token == Token::CloseParen {
1462                                        let end_call_location = self.current_location();
1463                                        self.advance();
1464                                        
1465                                        let call_location = SourceLocation::new(
1466                                            obj_start_line,
1467                                            obj_start_column,
1468                                            end_call_location.end_line,
1469                                            end_call_location.end_column
1470                                        );
1471                                        
1472                                        object = Expression::MemberCallExpression {
1473                                            object: Box::new(object),
1474                                            property: None,
1475                                            property_expr: Some(Box::new(property_expr)),
1476                                            computed: true,
1477                                            arguments,
1478                                            location: call_location,
1479                                        };
1480                                        continue;
1481                                    }
1482                                }
1483                                
1484                                // Parse first argument - check for inline callback
1485                                if let Some(token_with_span) = self.current_token {
1486                                    if token_with_span.token == Token::Cb {
1487                                        if !self.flags.allow_callbacks {
1488                                            return Err(ParseError::FeatureDisabled("Inline callback expressions".to_string(), self.current_location()));
1489                                        }
1490                                        let inline_callback = self.parse_inline_callback()?;
1491                                        arguments.push(inline_callback);
1492                                    } else {
1493                                        arguments.push(self.parse_expression()?);
1494                                    }
1495                                } else {
1496                                    return Err(ParseError::EndOfInput(self.current_location()));
1497                                }
1498                                
1499                                // Parse remaining arguments
1500                                while let Some(token_with_span) = self.current_token {
1501                                    match &token_with_span.token {
1502                                        Token::Comma => {
1503                                            self.advance();
1504                                            
1505                                            // Check for inline callback syntax after comma
1506                                            if let Some(token_with_span) = self.current_token {
1507                                                if token_with_span.token == Token::Cb {
1508                                                    if !self.flags.allow_callbacks {
1509                                                        return Err(ParseError::FeatureDisabled("Inline callback expressions".to_string(), self.current_location()));
1510                                                    }
1511                                                    let inline_callback = self.parse_inline_callback()?;
1512                                                    arguments.push(inline_callback);
1513                                                } else {
1514                                                    arguments.push(self.parse_expression()?);
1515                                                }
1516                                            } else {
1517                                                return Err(ParseError::EndOfInput(self.current_location()));
1518                                            }
1519                                        }
1520                                        Token::CloseParen => {
1521                                            let end_call_location = self.current_location();
1522                                            self.advance();
1523                                            
1524                                            let call_location = SourceLocation::new(
1525                                                obj_start_line,
1526                                                obj_start_column,
1527                                                end_call_location.end_line,
1528                                                end_call_location.end_column
1529                                            );
1530                                            
1531                                            object = Expression::MemberCallExpression {
1532                                                object: Box::new(object),
1533                                                property: None,
1534                                                property_expr: Some(Box::new(property_expr)),
1535                                                computed: true,
1536                                                arguments,
1537                                                location: call_location,
1538                                            };
1539                                            break;
1540                                        }
1541                                        _ => return Err(ParseError::ExpectedToken("',' or ')'".to_string(), self.current_location())),
1542                                    }
1543                                }
1544                            } else {
1545                                // Regular member expression (not a call)
1546                                object = Expression::MemberExpression {
1547                                    object: Box::new(object),
1548                                    property: None,
1549                                    property_expr: Some(Box::new(property_expr)),
1550                                    computed: true,
1551                                    location: member_expr_location,
1552                                };
1553                            }
1554                        } else {
1555                            // Regular member expression (not a call)
1556                            object = Expression::MemberExpression {
1557                                object: Box::new(object),
1558                                property: None,
1559                                property_expr: Some(Box::new(property_expr)),
1560                                computed: true,
1561                                location: member_expr_location,
1562                            };
1563                        }
1564                    },
1565                    _ => break,
1566                },
1567                None => break,
1568            }
1569        }
1570        Ok(object)
1571    }
1572
1573    fn parse_loop_statement(&mut self, start_location: SourceLocation) -> Result<Statement, ParseError> {
1574        self.advance();
1575        
1576        let variable = match &self.current_token {
1577            Some(token_with_span) => match &token_with_span.token {
1578                Token::Identifier(name) => name.clone(),
1579                _ => return Err(ParseError::ExpectedToken("identifier".to_string(), self.current_location())),
1580            },
1581            None => return Err(ParseError::EndOfInput(self.current_location())),
1582        };
1583        self.advance();
1584        
1585        match &self.current_token {
1586            Some(token_with_span) => {
1587                if token_with_span.token != Token::In {
1588                    return Err(ParseError::ExpectedToken("'in'".to_string(), self.current_location()));
1589                }
1590                self.advance();
1591            },
1592            None => return Err(ParseError::EndOfInput(self.current_location())),
1593        }
1594        
1595        let iterable = self.parse_expression()?;
1596        
1597        let body = self.parse_block()?;
1598        
1599        let end_location = body.location.clone();
1600        
1601        let location = SourceLocation::new(
1602            start_location.start_line,
1603            start_location.start_column,
1604            end_location.end_line,
1605            end_location.end_column
1606        );
1607
1608        Ok(Statement::LoopStatement {
1609            variable,
1610            iterable,
1611            body,
1612            location,
1613        })
1614    }
1615
1616    fn parse_end_statement(&mut self, start_location: SourceLocation) -> Result<Statement, ParseError> {
1617        self.advance();
1618        
1619        let semicolon_location = self.current_location();
1620        self.expect(Token::Semicolon)?;
1621
1622        let end_location = semicolon_location;
1623        
1624        let location = SourceLocation::new(
1625            start_location.start_line,
1626            start_location.start_column,
1627            end_location.end_line,
1628            end_location.end_column
1629        );
1630
1631        Ok(Statement::EndStatement { location })
1632    }
1633    
1634    fn parse_continue_statement(&mut self, start_location: SourceLocation) -> Result<Statement, ParseError> {
1635        self.advance();
1636        
1637        let semicolon_location = self.current_location();
1638        self.expect(Token::Semicolon)?;
1639
1640        let end_location = semicolon_location;
1641        
1642        let location = SourceLocation::new(
1643            start_location.start_line,
1644            start_location.start_column,
1645            end_location.end_line,
1646            end_location.end_column
1647        );
1648
1649        Ok(Statement::ContinueStatement { location })
1650    }
1651}