Skip to main content

qanglang_core/frontend/
parser.rs

1use std::{
2    collections::VecDeque,
3    path::{Path, PathBuf},
4    sync::Arc,
5};
6
7use crate::{
8    ErrorReporter, QangCompilerError, SourceMap,
9    frontend::{
10        ast_node_arena::{AstNodeArena, NodeId},
11        module_map::ModuleMap,
12        node_array_arena::NodeArrayId,
13        nodes::*,
14        tokenizer::{Token, TokenType, Tokenizer},
15    },
16    memory::StringInterner,
17};
18
19type ParseResult<T> = Result<T, QangCompilerError>;
20
21#[derive(Clone, Default)]
22pub struct ParserConfig {
23    pub skip_modules: bool,
24}
25
26pub struct Parser<'a> {
27    source_map: Arc<SourceMap>,
28    tokens: Tokenizer,
29    previous_token: Option<Token>,
30    current_token: Option<Token>,
31    errors: ErrorReporter,
32    strings: &'a mut StringInterner,
33    nodes: &'a mut AstNodeArena,
34    module_queue: VecDeque<PathBuf>,
35    config: ParserConfig,
36}
37
38impl<'a> Parser<'a> {
39    pub fn new(
40        source_map: Arc<SourceMap>,
41        nodes: &'a mut AstNodeArena,
42        strings: &'a mut StringInterner,
43    ) -> Self {
44        let errors = ErrorReporter::new();
45        let mut parser = Self {
46            tokens: Tokenizer::new(source_map.clone()),
47            source_map,
48            previous_token: None,
49            current_token: None,
50            errors,
51            nodes,
52            strings,
53            module_queue: VecDeque::new(),
54            config: ParserConfig::default(),
55        };
56
57        parser.advance();
58        parser
59    }
60
61    pub fn with_config(mut self, config: ParserConfig) -> Self {
62        self.config = config;
63        self
64    }
65
66    pub fn into_errors(self) -> ErrorReporter {
67        self.errors
68    }
69
70    fn into_parts(self) -> (ErrorReporter, VecDeque<PathBuf>) {
71        (self.errors, self.module_queue)
72    }
73
74    fn advance(&mut self) {
75        self.previous_token = self.current_token.take();
76
77        while let Some(token) = self.tokens.next() {
78            if token.token_type == TokenType::Error {
79                self.handle_tokenizer_error(&token);
80                continue;
81            }
82
83            self.current_token = Some(token);
84            break;
85        }
86    }
87
88    fn consume(&mut self, token_type: TokenType, message: &str) -> ParseResult<()> {
89        if let Some(current_token_type) = self.current_token.as_ref().map(|t| &t.token_type)
90            && token_type == *current_token_type
91        {
92            self.advance();
93            return Ok(());
94        }
95
96        let span = self
97            .current_token
98            .as_ref()
99            .map(SourceSpan::from_token)
100            .unwrap_or_default();
101
102        if !self.is_at_end() {
103            self.advance();
104        }
105
106        Err(QangCompilerError::new_syntax_error(
107            message.to_string(),
108            span,
109            self.source_map.clone(),
110        ))
111    }
112
113    fn match_token(&mut self, token_type: TokenType) -> bool {
114        if !self.check(token_type) {
115            return false;
116        }
117
118        self.advance();
119
120        true
121    }
122
123    fn check(&self, token_type: TokenType) -> bool {
124        self.current_token
125            .as_ref()
126            .map(|t| t.token_type == token_type)
127            .unwrap_or(false)
128    }
129
130    fn handle_tokenizer_error(&mut self, token: &Token) {
131        let message = token
132            .error_message
133            .as_deref()
134            .unwrap_or("Tokenization error")
135            .to_string();
136
137        self.errors
138            .report_error(QangCompilerError::new_syntax_error(
139                message,
140                SourceSpan::from_token(token),
141                self.source_map.clone(),
142            ));
143    }
144
145    fn get_current_span(&self) -> SourceSpan {
146        self.current_token
147            .as_ref()
148            .map(SourceSpan::from_token)
149            .unwrap_or_default()
150    }
151
152    fn get_previous_span(&self) -> SourceSpan {
153        self.previous_token
154            .as_ref()
155            .map(SourceSpan::from_token)
156            .unwrap_or_default()
157    }
158
159    fn get_identifier(&mut self) -> ParseResult<NodeId> {
160        let token = self.previous_token.as_ref();
161        let span = token
162            .map(SourceSpan::from_token)
163            .unwrap_or(SourceSpan { start: 0, end: 0 });
164
165        if let Some(token) = token {
166            let name = token.lexeme(&self.source_map);
167            let name = self.strings.intern(&name.iter().collect::<String>());
168            let node_id = self
169                .nodes
170                .create_node(AstNode::Identifier(IdentifierNode { name, span }));
171            Ok(node_id)
172        } else {
173            Err(QangCompilerError::new_syntax_error(
174                "Expected identifier.".to_string(),
175                span,
176                self.source_map.clone(),
177            ))
178        }
179    }
180
181    fn synchronize(&mut self) {
182        loop {
183            let current_token_type = match self.current_token.as_ref() {
184                Some(token) => &token.token_type,
185                None => {
186                    return;
187                }
188            };
189
190            if current_token_type == &TokenType::Eof {
191                break;
192            }
193
194            if let Some(prev_token) = &self.previous_token
195                && prev_token.token_type == TokenType::Semicolon
196            {
197                return;
198            }
199
200            match current_token_type {
201                TokenType::Class
202                | TokenType::Fn
203                | TokenType::Var
204                | TokenType::For
205                | TokenType::If
206                | TokenType::While
207                | TokenType::Return
208                | TokenType::Break
209                | TokenType::Continue => {
210                    return;
211                }
212                _ => {}
213            }
214
215            self.advance();
216        }
217    }
218
219    fn is_at_end(&self) -> bool {
220        match &self.current_token {
221            Some(token) => token.token_type == TokenType::Eof,
222            None => true,
223        }
224    }
225
226    fn is_lambda_start_after_paren(&mut self) -> bool {
227        self.check_lambda_pattern(true)
228    }
229
230    fn check_lambda_pattern(&mut self, after_paren: bool) -> bool {
231        if after_paren {
232            // After paren case - check current token and look ahead
233            let check_token = if let Some(current) = &self.current_token {
234                current.token_type
235            } else {
236                return false;
237            };
238
239            // Special case: if we see another '(' after the first '(', we need to check if it's a lambda
240            // pattern like "(() -> nil)" where the inner () is the lambda parameter list
241            if check_token == TokenType::LeftParen {
242                // Look for () -> pattern starting from current position
243                if let Some(next_token) = self.tokens.peek()
244                    && next_token.token_type == TokenType::RightParen
245                {
246                    // Found "(()" pattern, check for -> after the )
247                    return self
248                        .tokens
249                        .peek_ahead(1)
250                        .map(|t| t.token_type == TokenType::Arrow)
251                        .unwrap_or(false);
252                }
253                // For non-empty parameter lists like "(x) ->" or "(x, y) ->"
254                // we need to find the matching ) and then check for ->
255                let mut paren_depth = 1;
256                let mut offset = 0;
257                while let Some(token) = self.tokens.peek_ahead(offset) {
258                    match token.token_type {
259                        TokenType::LeftParen => paren_depth += 1,
260                        TokenType::RightParen => {
261                            paren_depth -= 1;
262                            if paren_depth == 0 {
263                                // Found matching ), check for -> after it
264                                return self
265                                    .tokens
266                                    .peek_ahead(offset + 1)
267                                    .map(|t| t.token_type == TokenType::Arrow)
268                                    .unwrap_or(false);
269                            }
270                        }
271                        _ => {}
272                    }
273                    offset += 1;
274                }
275                false
276            } else if check_token == TokenType::RightParen {
277                // Empty parameter list: () ->
278                self.tokens
279                    .peek()
280                    .map(|t| t.token_type == TokenType::Arrow)
281                    .unwrap_or(false)
282            } else {
283                // Non-empty parameter list: look for ) ->
284                let mut offset = 0;
285                while self
286                    .tokens
287                    .peek_ahead(offset)
288                    .map(|t| t.token_type != TokenType::RightParen)
289                    .unwrap_or(false)
290                {
291                    offset += 1;
292                }
293                self.tokens
294                    .peek_ahead(offset + 1)
295                    .map(|t| t.token_type == TokenType::Arrow)
296                    .unwrap_or(false)
297            }
298        } else {
299            // Before paren case - must start with '(' immediately
300            if let Some(first_token) = self.tokens.peek() {
301                if first_token.token_type != TokenType::LeftParen {
302                    return false;
303                }
304                // Check if it's followed by ) -> or parameters ) ->
305                if let Some(second_token) = self.tokens.peek_ahead(1) {
306                    if second_token.token_type == TokenType::RightParen {
307                        // Empty parameter list: () ->
308                        self.tokens
309                            .peek_ahead(2)
310                            .map(|t| t.token_type == TokenType::Arrow)
311                            .unwrap_or(false)
312                    } else if second_token.token_type == TokenType::LeftParen {
313                        // If we see "((", this is a grouped expression, not a direct lambda
314                        false
315                    } else {
316                        // Non-empty parameter list: look for ) ->
317                        let mut offset = 2;
318                        while self
319                            .tokens
320                            .peek_ahead(offset)
321                            .map(|t| t.token_type != TokenType::RightParen)
322                            .unwrap_or(false)
323                        {
324                            offset += 1;
325                        }
326                        self.tokens
327                            .peek_ahead(offset + 1)
328                            .map(|t| t.token_type == TokenType::Arrow)
329                            .unwrap_or(false)
330                    }
331                } else {
332                    false
333                }
334            } else {
335                false
336            }
337        }
338    }
339
340    pub fn parse(&mut self) -> ModuleMap {
341        let main_id = self.parse_file();
342        let mut modules = ModuleMap::new();
343
344        // Insert the main module
345        let main_path = self.source_map.get_path().to_path_buf();
346        modules.insert(&main_path, main_id, self.source_map.clone());
347        modules.set_main_module(main_path);
348
349        if self.config.skip_modules {
350            return modules;
351        }
352
353        while let Some(module_path) = self.module_queue.pop_front() {
354            if modules.has(&module_path) {
355                continue;
356            }
357
358            let path_str = module_path.to_string_lossy();
359            let source_map = if path_str.starts_with("<builtin:") && path_str.ends_with('>') {
360                let builtin_import_path = &path_str[9..path_str.len() - 1]; // Remove "<builtin:" and ">"
361
362                match crate::backend::builtin_modules::resolve_builtin_import(builtin_import_path) {
363                    Some(builtin_source) => {
364                        SourceMap::new(builtin_source.to_string(), module_path.clone())
365                    }
366                    None => {
367                        self.errors
368                            .report_error(QangCompilerError::new_analysis_error(
369                                format!("Built-in module '{}' not found", builtin_import_path),
370                                SourceSpan::default(),
371                                Arc::new(SourceMap::default()),
372                            ));
373                        continue;
374                    }
375                }
376            } else {
377                match SourceMap::from_path(&module_path) {
378                    Ok(source_map) => source_map,
379                    Err(err) => {
380                        self.errors
381                            .report_error(QangCompilerError::new_analysis_error(
382                                format!(
383                                    "Error loading module '{}': {}",
384                                    module_path.display(),
385                                    err
386                                ),
387                                SourceSpan::default(),
388                                Arc::new(SourceMap::default()),
389                            ));
390                        continue;
391                    }
392                }
393            };
394
395            let source_map = Arc::new(source_map);
396
397            let mut module_parser = Parser::new(source_map.clone(), self.nodes, self.strings);
398
399            let module_id = module_parser.parse_file();
400
401            let (errors, queue) = module_parser.into_parts();
402            self.errors.merge(errors);
403
404            modules.insert(module_path.as_path(), module_id, source_map);
405
406            self.module_queue.extend(queue);
407        }
408
409        modules
410    }
411
412    pub fn parse_file(&mut self) -> NodeId {
413        let start_span = self.get_current_span();
414        let decls = self.nodes.array.create();
415
416        while !self.is_at_end() {
417            if let Some(decl) = self.declaration() {
418                self.nodes.array.push(decls, decl);
419            }
420        }
421
422        let end_span = self.get_current_span();
423
424        self.nodes.create_node(AstNode::Module(Module {
425            decls,
426            span: SourceSpan::combine(start_span, end_span),
427        }))
428    }
429
430    fn declaration(&mut self) -> Option<NodeId> {
431        let current_token_type = self.current_token.as_ref()?.token_type;
432
433        let result = match current_token_type {
434            TokenType::Var => {
435                self.advance();
436                self.variable_declaration()
437            }
438            TokenType::Fn => {
439                self.advance();
440                self.function_declaration()
441            }
442            TokenType::Class => {
443                self.advance();
444                self.class_declaration()
445            }
446            TokenType::Mod => {
447                self.advance();
448                self.import_module_declaration()
449            }
450            _ => self.declaration_statement(),
451        };
452
453        match result {
454            Ok(decl) => Some(decl),
455            Err(error) => {
456                let formatted_error = QangCompilerError::new_syntax_error(
457                    error.message,
458                    error.span,
459                    self.source_map.clone(),
460                );
461                self.errors.report_error(formatted_error);
462                self.synchronize();
463                None
464            }
465        }
466    }
467
468    fn import_module_declaration(&mut self) -> ParseResult<NodeId> {
469        let span_start = self.get_previous_span();
470        self.consume(TokenType::Identifier, "Expected module identifier.")?;
471        let name = self.get_identifier()?;
472
473        self.consume(TokenType::Equals, "Expected equals.")?;
474        self.consume(TokenType::Import, "Expected import declaration.")?;
475        self.consume(TokenType::LeftParen, "Expected open parentheses.")?;
476        self.consume(TokenType::String, "Expected import path as string.")?;
477
478        let token = self.previous_token.as_ref().unwrap();
479
480        let path_span = self.get_previous_span();
481
482        let value = token.lexeme(&self.source_map);
483        let path_as_string = value[1..value.len() - 1].iter().collect::<String>();
484
485        let (path, combined_path) =
486            if crate::backend::builtin_modules::is_builtin_import(&path_as_string) {
487                if crate::backend::builtin_modules::resolve_builtin_import(&path_as_string)
488                    .is_none()
489                {
490                    return Err(QangCompilerError::new_syntax_error(
491                        format!("Built-in module '{}' does not exist.", path_as_string),
492                        path_span,
493                        self.source_map.clone(),
494                    ));
495                }
496
497                let path = self.strings.intern(&path_as_string);
498                let virtual_path = PathBuf::from(format!("<builtin:{}>", path_as_string));
499                (path, virtual_path)
500            } else {
501                let current_dir = self
502                    .source_map
503                    .get_path()
504                    .parent()
505                    .expect("Expected path to be file and to be within a dir");
506                let combined_path =
507                    match current_dir.join(Path::new(&path_as_string)).canonicalize() {
508                        Ok(combined_path) => combined_path,
509                        Err(_) => {
510                            return Err(QangCompilerError::new_syntax_error(
511                                "Unable to get module path.".to_string(),
512                                path_span,
513                                self.source_map.clone(),
514                            ));
515                        }
516                    };
517
518                match std::fs::exists(combined_path.as_path()) {
519                    Ok(exists) => {
520                        if !exists {
521                            self.errors
522                                .report_error(QangCompilerError::new_syntax_error(
523                                    format!(
524                                        "module at path '{}' does not exist.",
525                                        combined_path.as_path().display(),
526                                    ),
527                                    path_span,
528                                    self.source_map.clone(),
529                                ));
530                        }
531                    }
532                    Err(_) => {
533                        self.errors
534                            .report_error(QangCompilerError::new_syntax_error(
535                                format!(
536                                    "Unable to load module from path '{}'",
537                                    combined_path.as_path().display(),
538                                ),
539                                path_span,
540                                self.source_map.clone(),
541                            ));
542                    }
543                }
544
545                let combined_path_str = combined_path.to_string_lossy();
546                let path = self.strings.intern(&combined_path_str);
547                (path, combined_path)
548            };
549
550        self.module_queue.push_back(combined_path);
551
552        self.consume(TokenType::RightParen, "Expected closing parentheses.")?;
553        self.consume(TokenType::Semicolon, "Expected semicolon.")?;
554        let span_end = self.get_previous_span();
555
556        Ok(self
557            .nodes
558            .create_node(AstNode::ImportModuleDecl(ImportModuleDeclNode {
559                path,
560                name,
561                path_literal_span: path_span,
562                span: SourceSpan::combine(span_start, span_end),
563            })))
564    }
565
566    fn variable_declaration(&mut self) -> ParseResult<NodeId> {
567        let var_span = self.get_previous_span();
568        self.consume(TokenType::Identifier, "Expect variable name.")?;
569
570        let identifier = self.get_identifier()?;
571
572        let initializer = if self.match_token(TokenType::Equals) {
573            Some(self.expression()?)
574        } else {
575            None
576        };
577
578        self.consume(
579            TokenType::Semicolon,
580            "Expect ';' after variable declaration",
581        )?;
582
583        let semicolon_span = self.get_previous_span();
584        let span = SourceSpan::combine(var_span, semicolon_span);
585
586        let node_id = self
587            .nodes
588            .create_node(AstNode::VariableDecl(VariableDeclNode {
589                target: identifier,
590                initializer,
591                span,
592            }));
593
594        Ok(node_id)
595    }
596
597    fn class_declaration(&mut self) -> ParseResult<NodeId> {
598        let start_span = self.get_previous_span();
599
600        self.consume(TokenType::Identifier, "Expect class name.")?;
601        let name = self.get_identifier()?;
602
603        let superclass = if self.match_token(TokenType::Colon) {
604            self.consume(TokenType::Identifier, "Expect superclass name.")?;
605            Some(self.get_identifier()?)
606        } else {
607            None
608        };
609
610        self.consume(TokenType::LeftBrace, "Expect '{' before class body.")?;
611
612        let members = self.nodes.array.create();
613        while !self.check(TokenType::RightBrace) && !self.is_at_end() {
614            let class_member = self.class_member()?;
615            self.nodes.array.push(members, class_member);
616        }
617
618        self.consume(TokenType::RightBrace, "Expect '}' after class body.")?;
619        let end_span = self.get_previous_span();
620        let span = SourceSpan::combine(start_span, end_span);
621
622        let node_id = self.nodes.create_node(AstNode::Class(ClassDeclNode {
623            name,
624            superclass,
625            members,
626            span,
627        }));
628
629        Ok(node_id)
630    }
631
632    fn class_member(&mut self) -> ParseResult<NodeId> {
633        if self.check(TokenType::Identifier) {
634            if self
635                .tokens
636                .peek()
637                .map(|t| t.token_type == TokenType::LeftParen)
638                .unwrap_or(false)
639            {
640                Ok(self.function_expression()?)
641            } else {
642                Ok(self.field_declaration()?)
643            }
644        } else {
645            Err(QangCompilerError::new_syntax_error(
646                "Expected field or method declaration.".to_string(),
647                self.get_current_span(),
648                self.source_map.clone(),
649            ))
650        }
651    }
652
653    fn field_declaration(&mut self) -> ParseResult<NodeId> {
654        let start_span = self.get_current_span();
655        self.consume(TokenType::Identifier, "Expect field name.")?;
656        let name = self.get_identifier()?;
657
658        let initializer = if self.match_token(TokenType::Equals) {
659            Some(self.expression()?)
660        } else {
661            None
662        };
663
664        self.consume(TokenType::Semicolon, "Expect ';' after field declaration.")?;
665        let end_span = self.get_previous_span();
666        let span = SourceSpan::combine(start_span, end_span);
667
668        let node_id = self.nodes.create_node(AstNode::FieldDecl(FieldDeclNode {
669            name,
670            initializer,
671            span,
672        }));
673
674        Ok(node_id)
675    }
676
677    fn function_declaration(&mut self) -> ParseResult<NodeId> {
678        let function_expr = self.function_expression()?;
679        let function_expr_span = self.nodes.get_func_expr_node(function_expr).node.span;
680        let span = SourceSpan::combine(self.get_previous_span(), function_expr_span);
681
682        let node_id = self
683            .nodes
684            .create_node(AstNode::FunctionDecl(FunctionDeclNode {
685                function: function_expr,
686                span,
687            }));
688
689        Ok(node_id)
690    }
691
692    fn declaration_statement(&mut self) -> ParseResult<NodeId> {
693        let current_token_type = self
694            .current_token
695            .as_ref()
696            .ok_or(QangCompilerError::new_syntax_error(
697                "Expected statement.".to_string(),
698                self.previous_token
699                    .as_ref()
700                    .map(SourceSpan::from_token)
701                    .unwrap_or_default(),
702                self.source_map.clone(),
703            ))?
704            .token_type;
705
706        match current_token_type {
707            TokenType::While => Ok(self.while_statement()?),
708            TokenType::If => Ok(self.if_statement()?),
709            TokenType::LeftBrace => Ok(self.block_statement()?),
710            TokenType::For => Ok(self.for_statement()?),
711            TokenType::Break => Ok(self.break_statement()?),
712            TokenType::Continue => Ok(self.continue_statement()?),
713            TokenType::Return => Ok(self.return_statement()?),
714            _ => Ok(self.statement()?),
715        }
716    }
717
718    fn block_statement(&mut self) -> ParseResult<NodeId> {
719        let start_span = self.get_current_span();
720        self.advance();
721        let decls = self.nodes.array.create();
722
723        while !self.check(TokenType::RightBrace) && !self.is_at_end() {
724            if let Some(decl) = self.declaration() {
725                self.nodes.array.push(decls, decl);
726            }
727        }
728        self.consume(TokenType::RightBrace, "Expected '}'.")?;
729        let end_span = self.get_previous_span(); // Use previous_span to get the '}' token we just consumed
730
731        let node_id = self.nodes.create_node(AstNode::BlockStmt(BlockStmtNode {
732            decls,
733            span: SourceSpan::combine(start_span, end_span),
734        }));
735
736        Ok(node_id)
737    }
738
739    fn if_statement(&mut self) -> ParseResult<NodeId> {
740        let start_span = self.get_current_span();
741        self.advance();
742        self.consume(TokenType::LeftParen, "Expected '('.")?;
743        let condition = self.expression()?;
744        self.consume(TokenType::RightParen, "Expected ')'.")?;
745
746        let then_branch = self.statement()?;
747
748        let (else_branch, span) = if self.match_token(TokenType::Else) {
749            let else_stmt = self.statement()?;
750            let else_stmt_span = self.nodes.get_node(else_stmt).span();
751            let span = SourceSpan::combine(start_span, else_stmt_span);
752            (Some(else_stmt), span)
753        } else {
754            let then_branch_span = self.nodes.get_node(then_branch).span();
755            (None, SourceSpan::combine(start_span, then_branch_span))
756        };
757
758        let node_id = self.nodes.create_node(AstNode::IfStmt(IfStmtNode {
759            condition,
760            then_branch,
761            else_branch,
762            span,
763        }));
764
765        Ok(node_id)
766    }
767
768    fn statement(&mut self) -> ParseResult<NodeId> {
769        let current_token_type = self
770            .current_token
771            .as_ref()
772            .ok_or(QangCompilerError::new_syntax_error(
773                "Expected statement.".to_string(),
774                self.previous_token
775                    .as_ref()
776                    .map(SourceSpan::from_token)
777                    .unwrap_or_default(),
778                self.source_map.clone(),
779            ))?
780            .token_type;
781
782        match current_token_type {
783            TokenType::While => Ok(self.while_statement()?),
784            TokenType::If => Ok(self.if_statement()?),
785            TokenType::LeftBrace => Ok(self.block_statement()?),
786            TokenType::For => Ok(self.for_statement()?),
787            TokenType::Break => Ok(self.break_statement()?),
788            TokenType::Continue => Ok(self.continue_statement()?),
789            TokenType::Return => Ok(self.return_statement()?),
790            _ => Ok(self.expression_statement()?),
791        }
792    }
793
794    fn while_statement(&mut self) -> ParseResult<NodeId> {
795        let start_span = self.get_current_span();
796        self.advance();
797        self.consume(TokenType::LeftParen, "Expected '('.")?;
798        let condition = self.expression()?;
799        self.consume(TokenType::RightParen, "Expected ')'.")?;
800
801        let stmt = self.statement()?;
802        let stmt_span = self.nodes.get_node(stmt).span();
803        let span = SourceSpan::combine(start_span, stmt_span);
804
805        let node_id = self.nodes.create_node(AstNode::WhileStmt(WhileStmtNode {
806            condition,
807            body: stmt,
808            span,
809        }));
810
811        Ok(node_id)
812    }
813
814    fn for_statement(&mut self) -> ParseResult<NodeId> {
815        let start_span = self.get_current_span();
816        self.advance();
817        self.consume(TokenType::LeftParen, "Expect '(' after 'for'.")?;
818
819        let initializer = if self.match_token(TokenType::Semicolon) {
820            None
821        } else if self.match_token(TokenType::Var) {
822            let var_decl = self.variable_declaration()?;
823            Some(var_decl)
824        } else {
825            let expr = self.expression()?;
826            self.consume(
827                TokenType::Semicolon,
828                "Expect ';' after for loop initializer.",
829            )?;
830            Some(expr)
831        };
832
833        let condition = if self.check(TokenType::Semicolon) {
834            None
835        } else {
836            Some(self.expression()?)
837        };
838        self.consume(TokenType::Semicolon, "Expect ';' after for loop condition.")?;
839
840        let afterthought = if self.check(TokenType::RightParen) {
841            None
842        } else {
843            Some(self.expression()?)
844        };
845        self.consume(TokenType::RightParen, "Expect ')' after for clauses.")?;
846
847        let body = self.statement()?;
848        let body_span = self.nodes.get_node(body).span();
849        let span = SourceSpan::combine(start_span, body_span);
850        let node_id = self.nodes.create_node(AstNode::ForStmt(ForStmtNode {
851            initializer,
852            condition,
853            afterthought,
854            body,
855            span,
856        }));
857
858        Ok(node_id)
859    }
860
861    fn break_statement(&mut self) -> ParseResult<NodeId> {
862        let start_span = self.get_current_span();
863        self.advance();
864        self.consume(TokenType::Semicolon, "Expected ';'.")?;
865        let span = SourceSpan::combine(start_span, self.get_previous_span());
866
867        let node_id = self
868            .nodes
869            .create_node(AstNode::BreakStmt(BreakStmtNode { span }));
870
871        Ok(node_id)
872    }
873
874    fn continue_statement(&mut self) -> ParseResult<NodeId> {
875        let start_span = self.get_current_span();
876        self.advance();
877        self.consume(TokenType::Semicolon, "Expected ';'.")?;
878        let span = SourceSpan::combine(start_span, self.get_previous_span());
879
880        let node_id = self
881            .nodes
882            .create_node(AstNode::ContinueStmt(ContinueStmtNode { span }));
883
884        Ok(node_id)
885    }
886
887    fn return_statement(&mut self) -> ParseResult<NodeId> {
888        let start_span = self.get_current_span();
889        self.advance();
890
891        let value = if self.check(TokenType::Semicolon) {
892            None
893        } else {
894            Some(self.expression()?)
895        };
896
897        self.consume(TokenType::Semicolon, "Expect ';' after return value.")?;
898        let end_span = self.get_previous_span();
899        let span = SourceSpan::combine(start_span, end_span);
900
901        let node_id = self
902            .nodes
903            .create_node(AstNode::ReturnStmt(ReturnStmtNode { value, span }));
904
905        Ok(node_id)
906    }
907
908    fn expression_statement(&mut self) -> ParseResult<NodeId> {
909        let expr = self.expression()?;
910
911        self.consume(TokenType::Semicolon, "Expect ';' after expression.")?; // TODO move this error to the previous line.
912
913        let semicolon_span = self.get_previous_span();
914
915        let expr_span = self.nodes.get_node(expr).span();
916
917        let node_id = self.nodes.create_node(AstNode::ExprStmt(ExprStmtNode {
918            expr,
919            span: SourceSpan::combine(expr_span, semicolon_span),
920        }));
921
922        Ok(node_id)
923    }
924
925    fn expression(&mut self) -> ParseResult<NodeId> {
926        self.assignment()
927    }
928
929    fn function_expression(&mut self) -> ParseResult<NodeId> {
930        let start_span = self.get_current_span();
931        self.consume(TokenType::Identifier, "Expect function name.")?;
932        let name = self.get_identifier()?;
933
934        let parameters = self.argument_parameters()?;
935        let body = self.block_statement()?;
936        let body_span = self.nodes.get_node(body).span();
937        let span = SourceSpan::combine(start_span, body_span);
938
939        let node_id = self
940            .nodes
941            .create_node(AstNode::FunctionExpr(FunctionExprNode {
942                name,
943                parameters,
944                body,
945                span,
946            }));
947
948        Ok(node_id)
949    }
950
951    fn assignment(&mut self) -> ParseResult<NodeId> {
952        let expr = expression_parser::parse(self, expression_parser::Precedence::Ternary)?;
953
954        let assignment_operator = if self.match_token(TokenType::Equals) {
955            Some(AssignmentOperator::Assign)
956        } else if self.match_token(TokenType::PlusAssign) {
957            Some(AssignmentOperator::AddAssign)
958        } else if self.match_token(TokenType::MinusAssign) {
959            Some(AssignmentOperator::SubtractAssign)
960        } else if self.match_token(TokenType::StarAssign) {
961            Some(AssignmentOperator::MultiplyAssign)
962        } else if self.match_token(TokenType::SlashAssign) {
963            Some(AssignmentOperator::DivideAssign)
964        } else if self.match_token(TokenType::ModuloAssign) {
965            Some(AssignmentOperator::ModuloAssign)
966        } else {
967            None
968        };
969
970        if let Some(operator) = assignment_operator {
971            let value = self.expression()?;
972            let span = self.nodes.get_node(value).span();
973
974            let expr = self.nodes.get_expr_node(expr);
975            let target = match expr.node {
976                ExprNode::Primary(PrimaryNode::Identifier(_)) => expr.id,
977                ExprNode::Call(call_expr) => {
978                    let call_operation = *self.nodes.get_node(call_expr.operation);
979
980                    match call_operation {
981                        AstNode::PropertyAccess(property) => self.nodes.create_node(
982                            AstNode::PropertyAssignment(PropertyAssignmentNode {
983                                property: property.identifier,
984                                object: call_expr.callee,
985                                span,
986                            }),
987                        ),
988                        AstNode::IndexAccess(index) => {
989                            self.nodes
990                                .create_node(AstNode::IndexAssignment(IndexAssignmentNode {
991                                    object: call_expr.callee,
992                                    index: index.index,
993                                    span,
994                                }))
995                        }
996                        _ => {
997                            return Err(QangCompilerError::new_syntax_error(
998                                "Invalid assignment target".to_string(),
999                                span,
1000                                self.source_map.clone(),
1001                            ));
1002                        }
1003                    }
1004                }
1005                _ => {
1006                    return Err(QangCompilerError::new_syntax_error(
1007                        "Invalid assignment target".to_string(),
1008                        span,
1009                        self.source_map.clone(),
1010                    ));
1011                }
1012            };
1013
1014            let node_id = self
1015                .nodes
1016                .create_node(AstNode::AssignmentExpr(AssignmentExprNode {
1017                    target,
1018                    operator,
1019                    value,
1020                    span,
1021                }));
1022
1023            Ok(node_id)
1024        } else {
1025            Ok(expr)
1026        }
1027    }
1028
1029    fn argument_parameters(&mut self) -> ParseResult<NodeArrayId> {
1030        self.consume(TokenType::LeftParen, "Expect '(' before parameters.")?;
1031
1032        let parameters = self.nodes.array.create();
1033
1034        if self.match_token(TokenType::RightParen) {
1035            return Ok(parameters);
1036        }
1037
1038        self.advance();
1039        let parameter = self.get_identifier()?;
1040        self.nodes.array.push(parameters, parameter);
1041
1042        while self.match_token(TokenType::Comma) {
1043            if self.check(TokenType::RightParen) {
1044                break;
1045            }
1046            self.advance();
1047            let parameter = self.get_identifier()?;
1048            self.nodes.array.push(parameters, parameter);
1049        }
1050
1051        self.consume(TokenType::RightParen, "Expect ')' after parameters.")?;
1052
1053        Ok(parameters)
1054    }
1055}
1056
1057mod expression_parser {
1058    use super::*;
1059    use crate::{frontend::node_array_arena::NodeArrayId, frontend::tokenizer};
1060
1061    #[derive(Debug, PartialEq, PartialOrd)]
1062    #[repr(u8)]
1063    pub enum Precedence {
1064        None = 0,
1065        Assignment, // =
1066        Ternary,    // ? :
1067        Pipe,       // |>
1068        Or,         // or
1069        And,        // and
1070        Equality,   // == !=
1071        Comparison, // > >= < <=
1072        Term,       // + -
1073        Factor,     // * / %
1074        Unary,      // ! -
1075        Call,       // . () []
1076    }
1077
1078    impl From<u8> for Precedence {
1079        fn from(byte: u8) -> Self {
1080            match byte {
1081                0 => Precedence::None,
1082                1 => Precedence::Assignment,
1083                2 => Precedence::Pipe,
1084                3 => Precedence::Ternary,
1085                4 => Precedence::Or,
1086                5 => Precedence::And,
1087                6 => Precedence::Equality,
1088                7 => Precedence::Comparison,
1089                8 => Precedence::Term,
1090                9 => Precedence::Factor,
1091                10 => Precedence::Unary,
1092                11 => Precedence::Call,
1093                _ => panic!("Unknown precedence: {}", byte),
1094            }
1095        }
1096    }
1097
1098    impl From<Precedence> for u8 {
1099        fn from(precedence: Precedence) -> Self {
1100            precedence as u8
1101        }
1102    }
1103
1104    type PrefixParseFn = fn(&mut Parser) -> ParseResult<NodeId>;
1105    type InfixParseFn = fn(&mut Parser, NodeId) -> ParseResult<NodeId>;
1106
1107    fn number(parser: &mut Parser) -> ParseResult<NodeId> {
1108        let token = get_previous_token(parser);
1109
1110        let span = SourceSpan::from_token(token);
1111
1112        let value = token
1113            .lexeme(&parser.source_map)
1114            .iter()
1115            .collect::<String>()
1116            .parse::<f64>()
1117            .map_err(|_| {
1118                crate::QangCompilerError::new_syntax_error(
1119                    "Expected number.".to_string(),
1120                    span,
1121                    parser.source_map.clone(),
1122                )
1123            })?;
1124
1125        let node_id = parser
1126            .nodes
1127            .create_node(AstNode::NumberLiteral(NumberLiteralNode { value, span }));
1128
1129        Ok(node_id)
1130    }
1131
1132    fn grouping_or_lambda(parser: &mut Parser) -> ParseResult<NodeId> {
1133        // Check if this is a lambda by looking at the current parser state
1134        // At this point, '(' has been consumed, so we use is_lambda_start_after_paren
1135        let is_lambda = parser.is_lambda_start_after_paren();
1136
1137        if is_lambda {
1138            // Check if we're parsing a grouped lambda (like "(() -> nil)") vs direct lambda
1139            let is_grouped_lambda = parser.check(TokenType::LeftParen);
1140
1141            let lambda_expr = lambda(parser)?;
1142
1143            // Only consume closing ')' if this is a grouped lambda
1144            if is_grouped_lambda {
1145                parser.consume(TokenType::RightParen, "Expect ')' after lambda expression.")?;
1146            }
1147
1148            Ok(lambda_expr)
1149        } else {
1150            grouping(parser)
1151        }
1152    }
1153
1154    fn grouping(parser: &mut Parser) -> ParseResult<NodeId> {
1155        let expr = parser.expression()?;
1156        parser.consume(
1157            tokenizer::TokenType::RightParen,
1158            "Expect ')' after expression.",
1159        )?;
1160
1161        Ok(expr)
1162    }
1163
1164    fn lambda(parser: &mut Parser) -> ParseResult<NodeId> {
1165        let start_span = parser.get_previous_span();
1166
1167        // If we encounter a '(' at the start, consume it (start of parameter list)
1168        if parser.check(TokenType::LeftParen) {
1169            parser.advance();
1170        }
1171
1172        let parameters = parser.nodes.array.create();
1173
1174        if !parser.match_token(TokenType::RightParen) {
1175            parser.consume(TokenType::Identifier, "Expect parameter name.")?;
1176            let parameter = parser.get_identifier()?;
1177            parser.nodes.array.push(parameters, parameter);
1178
1179            while parser.match_token(TokenType::Comma) {
1180                if parser.check(TokenType::RightParen) {
1181                    break;
1182                }
1183                parser.consume(TokenType::Identifier, "Expect parameter name.")?;
1184                let parameter = parser.get_identifier()?;
1185                parser.nodes.array.push(parameters, parameter);
1186            }
1187
1188            parser.consume(TokenType::RightParen, "Expect ')' after parameters.")?;
1189        }
1190
1191        parser.consume(TokenType::Arrow, "Expect '->' after lambda parameters.")?;
1192
1193        let body = if parser.check(TokenType::LeftBrace) {
1194            parser.block_statement()?
1195        } else {
1196            parser.expression()?
1197        };
1198        let body_span = parser.nodes.get_node(body).span();
1199        let span = SourceSpan::combine(start_span, body_span);
1200
1201        let node_id = parser
1202            .nodes
1203            .create_node(AstNode::LambdaExpr(LambdaExprNode {
1204                parameters,
1205                body,
1206                span,
1207            }));
1208
1209        Ok(node_id)
1210    }
1211
1212    fn unary(parser: &mut Parser) -> ParseResult<NodeId> {
1213        let token = get_previous_token(parser);
1214        let operator_type = token.token_type;
1215        let operator_span = SourceSpan::from_token(token);
1216        let operand = parse(parser, Precedence::Unary)?;
1217        let operand_span = parser.nodes.get_node(operand).span();
1218
1219        let span = SourceSpan::combine(operator_span, operand_span);
1220        match operator_type {
1221            tokenizer::TokenType::Minus => {
1222                Ok(parser.nodes.create_node(AstNode::UnaryExpr(UnaryExprNode {
1223                    operator: UnaryOperator::Minus,
1224                    operand,
1225                    span,
1226                })))
1227            }
1228            tokenizer::TokenType::Bang => {
1229                Ok(parser.nodes.create_node(AstNode::UnaryExpr(UnaryExprNode {
1230                    operator: UnaryOperator::Not,
1231                    operand,
1232                    span,
1233                })))
1234            }
1235            _ => Err(crate::QangCompilerError::new_syntax_error(
1236                "Unknown operator.".to_string(),
1237                span,
1238                parser.source_map.clone(),
1239            )),
1240        }
1241    }
1242
1243    fn literal(parser: &mut Parser) -> ParseResult<NodeId> {
1244        let token = get_previous_token(parser);
1245
1246        let span = SourceSpan::from_token(token);
1247
1248        match token.token_type {
1249            tokenizer::TokenType::False => {
1250                Ok(parser
1251                    .nodes
1252                    .create_node(AstNode::BooleanLiteral(BooleanLiteralNode {
1253                        value: false,
1254                        span,
1255                    })))
1256            }
1257            tokenizer::TokenType::True => {
1258                Ok(parser
1259                    .nodes
1260                    .create_node(AstNode::BooleanLiteral(BooleanLiteralNode {
1261                        value: true,
1262                        span,
1263                    })))
1264            }
1265            tokenizer::TokenType::Nil => Ok(parser
1266                .nodes
1267                .create_node(AstNode::NilLiteral(NilLiteralNode { span }))),
1268            tokenizer::TokenType::This => Ok(parser
1269                .nodes
1270                .create_node(AstNode::ThisExpr(ThisExprNode { span }))),
1271            tokenizer::TokenType::Super => {
1272                if !parser.match_token(tokenizer::TokenType::Dot) {
1273                    return Err(crate::QangCompilerError::new_syntax_error(
1274                        "Expect '.' after 'super'.".to_string(),
1275                        span,
1276                        parser.source_map.clone(),
1277                    ));
1278                }
1279
1280                parser.consume(
1281                    tokenizer::TokenType::Identifier,
1282                    "Expect method name after 'super.'.",
1283                )?;
1284
1285                let method_name = parser.get_identifier()?;
1286                let method_name_span = parser.nodes.get_node(method_name).span();
1287                let method_span = SourceSpan::combine(span, method_name_span);
1288                let node_id = parser.nodes.create_node(AstNode::SuperExpr(SuperExprNode {
1289                    method: method_name,
1290                    span: method_span,
1291                }));
1292                Ok(node_id)
1293            }
1294            _ => Err(crate::QangCompilerError::new_syntax_error(
1295                "Unknown literal.".to_string(),
1296                span,
1297                parser.source_map.clone(),
1298            )),
1299        }
1300    }
1301
1302    fn process_escape_sequences(raw_string: &str) -> String {
1303        let mut result = String::new();
1304        let mut chars = raw_string.chars();
1305
1306        while let Some(c) = chars.next() {
1307            if c == '\\' {
1308                if let Some(escaped) = chars.next() {
1309                    match escaped {
1310                        'n' => result.push('\n'),
1311                        't' => result.push('\t'),
1312                        'r' => result.push('\r'),
1313                        '\\' => result.push('\\'),
1314                        '"' => result.push('"'),
1315                        '\'' => result.push('\''),
1316                        '0' => result.push('\0'),
1317                        _ => {
1318                            // This should not happen as tokenizer validates escapes
1319                            result.push('\\');
1320                            result.push(escaped);
1321                        }
1322                    }
1323                } else {
1324                    result.push('\\');
1325                }
1326            } else {
1327                result.push(c);
1328            }
1329        }
1330
1331        result
1332    }
1333
1334    fn string(parser: &mut Parser) -> ParseResult<NodeId> {
1335        let token = get_previous_token(parser);
1336
1337        let value = token.lexeme(&parser.source_map);
1338
1339        let span = SourceSpan::from_token(token);
1340
1341        let raw_content = value[1..value.len() - 1].iter().collect::<String>();
1342
1343        let processed_content = process_escape_sequences(&raw_content);
1344
1345        let string_handle = parser.strings.intern(&processed_content);
1346        let node_id = parser
1347            .nodes
1348            .create_node(AstNode::StringLiteral(StringLiteralNode {
1349                value: string_handle,
1350                span,
1351            }));
1352
1353        Ok(node_id)
1354    }
1355
1356    fn identifier(parser: &mut Parser) -> ParseResult<NodeId> {
1357        parser.get_identifier()
1358    }
1359
1360    fn array(parser: &mut Parser) -> ParseResult<NodeId> {
1361        let start_span = parser.get_previous_span();
1362        let array_node_id = parser.nodes.array.create();
1363
1364        // Handle empty array case
1365        if parser.check(tokenizer::TokenType::RightSquareBracket) {
1366            parser.advance();
1367            let end_span = parser.get_previous_span();
1368            let span = SourceSpan::combine(start_span, end_span);
1369            let node_id =
1370                parser
1371                    .nodes
1372                    .create_node(AstNode::ArrayLiteralExpr(ArrayLiteralExprNode {
1373                        elements: array_node_id,
1374                        span,
1375                    }));
1376            return Ok(node_id);
1377        }
1378
1379        // Parse the first expression
1380        let first_expr = parser.expression()?;
1381        parser.nodes.array.push(array_node_id, first_expr);
1382
1383        // Continue parsing comma-separated elements
1384        while parser.match_token(tokenizer::TokenType::Comma)
1385            && parser
1386                .current_token
1387                .as_ref()
1388                .map(|t| t.token_type != TokenType::RightSquareBracket)
1389                .unwrap_or(false)
1390        {
1391            let expr = parser.expression()?;
1392            parser.nodes.array.push(array_node_id, expr);
1393        }
1394
1395        let _ = parser.match_token(TokenType::Comma);
1396
1397        parser.consume(
1398            tokenizer::TokenType::RightSquareBracket,
1399            "Expect ']' after array elements.",
1400        )?;
1401
1402        let end_span = parser.get_previous_span();
1403        let span = SourceSpan::combine(start_span, end_span);
1404        let node_id = parser
1405            .nodes
1406            .create_node(AstNode::ArrayLiteralExpr(ArrayLiteralExprNode {
1407                elements: array_node_id,
1408                span,
1409            }));
1410
1411        Ok(node_id)
1412    }
1413
1414    fn map_expression(parser: &mut Parser, left: NodeId) -> ParseResult<NodeId> {
1415        let start_span: SourceSpan = parser.nodes.get_node(left).span();
1416
1417        let parameter = if parser.match_token(TokenType::Identifier) {
1418            parser.get_identifier()?
1419        } else {
1420            return Err(crate::QangCompilerError::new_syntax_error(
1421                "Expect parameter name before '->' in map expression.".to_string(),
1422                parser.get_current_span(),
1423                parser.source_map.clone(),
1424            ));
1425        };
1426
1427        parser.consume(TokenType::Arrow, "Expect '->' after parameters.")?;
1428        let body = expression_parser::parse(parser, Precedence::Ternary)?;
1429        parser.consume(TokenType::Bar, "Expect '|' after map body.")?;
1430
1431        let span = SourceSpan::combine(start_span, parser.get_previous_span());
1432
1433        let operation = parser.nodes.create_node(AstNode::MapExpr(MapExprNode {
1434            parameter,
1435            body,
1436            span,
1437        }));
1438        let node_id = parser.nodes.create_node(AstNode::CallExpr(CallExprNode {
1439            callee: left,
1440            operation,
1441            span,
1442        }));
1443
1444        Ok(node_id)
1445    }
1446
1447    fn optional_map_expression(parser: &mut Parser, left: NodeId) -> ParseResult<NodeId> {
1448        let start_span = parser.nodes.get_node(left).span();
1449
1450        let parameter = if parser.check(TokenType::Identifier) {
1451            parser.advance();
1452            parser.get_identifier()?
1453        } else {
1454            return Err(crate::QangCompilerError::new_syntax_error(
1455                "Expect parameter name before '->' in optional map expression.".to_string(),
1456                parser.get_current_span(),
1457                parser.source_map.clone(),
1458            ));
1459        };
1460
1461        parser.consume(TokenType::Arrow, "Expect '->' after parameters.")?;
1462
1463        let body = expression_parser::parse(parser, Precedence::Ternary)?;
1464
1465        parser.consume(TokenType::Bar, "Expect '|' after map body.")?;
1466
1467        let span = SourceSpan::combine(start_span, parser.get_previous_span());
1468
1469        let operation = parser
1470            .nodes
1471            .create_node(AstNode::OptionalMapExpr(OptionalMapExprNode {
1472                parameter,
1473                body,
1474                span,
1475            }));
1476        let node_id = parser.nodes.create_node(AstNode::CallExpr(CallExprNode {
1477            callee: left,
1478            operation,
1479            span,
1480        }));
1481
1482        Ok(node_id)
1483    }
1484
1485    fn object(parser: &mut Parser) -> ParseResult<NodeId> {
1486        let start_span = parser.get_previous_span();
1487        let entries = parser.nodes.array.create();
1488
1489        if parser.check(tokenizer::TokenType::DoubleRightBrace) {
1490            parser.advance();
1491            let end_span = parser.get_previous_span();
1492            let span = SourceSpan::combine(start_span, end_span);
1493            let node_id =
1494                parser
1495                    .nodes
1496                    .create_node(AstNode::ObjectLiteralExpr(ObjectLiteralExprNode {
1497                        entries,
1498                        span,
1499                    }));
1500            return Ok(node_id);
1501        }
1502
1503        while !parser.check(tokenizer::TokenType::DoubleRightBrace) && !parser.is_at_end() {
1504            parser.advance();
1505            let key = parser.get_identifier()?;
1506            let key_span = parser.nodes.get_node(key).span();
1507
1508            if parser.match_token(tokenizer::TokenType::Equals) {
1509                let value = parser.expression()?;
1510                let value_span = parser.nodes.get_node(value).span();
1511                let entry = parser
1512                    .nodes
1513                    .create_node(AstNode::ObjectEntry(ObjectEntryNode {
1514                        key,
1515                        value,
1516                        span: SourceSpan::combine(key_span, value_span),
1517                    }));
1518                parser.nodes.array.push(entries, entry);
1519
1520                if !parser.match_token(tokenizer::TokenType::Comma) {
1521                    break;
1522                }
1523            } else if parser.match_token(tokenizer::TokenType::Comma)
1524                || parser.check(tokenizer::TokenType::DoubleRightBrace)
1525            {
1526                let entry = parser
1527                    .nodes
1528                    .create_node(AstNode::ObjectEntry(ObjectEntryNode {
1529                        key,
1530                        value: key,
1531                        span: key_span,
1532                    }));
1533                parser.nodes.array.push(entries, entry);
1534            } else {
1535                break;
1536            }
1537        }
1538
1539        parser.consume(tokenizer::TokenType::DoubleRightBrace, "Expected '}}'.")?;
1540        let end_span = parser.get_previous_span();
1541
1542        let node_id = parser
1543            .nodes
1544            .create_node(AstNode::ObjectLiteralExpr(ObjectLiteralExprNode {
1545                entries,
1546                span: SourceSpan::combine(start_span, end_span),
1547            }));
1548        Ok(node_id)
1549    }
1550
1551    fn when_expression(parser: &mut Parser) -> ParseResult<NodeId> {
1552        let start_span = parser.get_previous_span();
1553
1554        // Check for optional value in parentheses: when (value)
1555        let value = if parser.match_token(TokenType::LeftParen) {
1556            let val = parser.expression()?;
1557            parser.consume(TokenType::RightParen, "Expected ')' after when value.")?;
1558            Some(val)
1559        } else {
1560            None
1561        };
1562
1563        parser.consume(TokenType::LeftBrace, "Expected '{' after 'when'.")?;
1564
1565        let branches = parser.nodes.array.create();
1566        let mut else_branch = None;
1567
1568        // Parse branches until we hit '}'
1569        loop {
1570            // Check for end of branches
1571            if parser.check(TokenType::RightBrace) || parser.is_at_end() {
1572                break;
1573            }
1574
1575            // Check for else branch
1576            if parser.check(TokenType::Else) {
1577                parser.advance(); // Consume 'else'
1578                parser.consume(TokenType::FatArrow, "Expected '=>' after 'else'.")?;
1579                else_branch = Some(parse(parser, Precedence::Ternary)?);
1580                // Optional trailing comma after else
1581                let _ = parser.match_token(TokenType::Comma);
1582                break;
1583            }
1584
1585            // Parse condition expression
1586            let condition_start_span = parser.get_current_span();
1587
1588            // Special handling for 'is Type' pattern in match form
1589            let (condition, is_type_check) = if parser.check(TokenType::Is) {
1590                parser.advance(); // Consume 'is'
1591                // This is a type check pattern: is Type
1592                parser.consume(TokenType::Identifier, "Expected type name after 'is'.")?;
1593                let type_name = parser.get_identifier()?;
1594                (type_name, true)
1595            } else {
1596                // Regular condition expression
1597                let cond = parse(parser, Precedence::Ternary)?;
1598
1599                // Check if the parsed expression itself contains 'is' operator
1600                let is_check = if let AstNode::EqualityExpr(eq_expr) = parser.nodes.get_node(cond) {
1601                    matches!(eq_expr.operator, EqualityOperator::Is)
1602                } else {
1603                    false
1604                };
1605
1606                (cond, is_check)
1607            };
1608
1609            parser.consume(TokenType::FatArrow, "Expected '=>' after when condition.")?;
1610
1611            let body = parse(parser, Precedence::Ternary)?;
1612            let body_span = parser.nodes.get_node(body).span();
1613            let branch_span = SourceSpan::combine(condition_start_span, body_span);
1614
1615            let branch = parser
1616                .nodes
1617                .create_node(AstNode::WhenBranch(WhenBranchNode {
1618                    condition,
1619                    is_type_check,
1620                    body,
1621                    span: branch_span,
1622                }));
1623
1624            parser.nodes.array.push(branches, branch);
1625
1626            // Optional comma between branches
1627            let _ = parser.match_token(TokenType::Comma);
1628        }
1629
1630        parser.consume(TokenType::RightBrace, "Expected '}' after when branches.")?;
1631        let end_span = parser.get_previous_span();
1632        let span = SourceSpan::combine(start_span, end_span);
1633
1634        let node_id = parser.nodes.create_node(AstNode::WhenExpr(WhenExprNode {
1635            value,
1636            branches,
1637            else_branch,
1638            span,
1639        }));
1640
1641        Ok(node_id)
1642    }
1643
1644    fn binary(parser: &mut Parser, left: NodeId) -> ParseResult<NodeId> {
1645        let token = get_previous_token(parser);
1646        let span_start = parser.nodes.get_node(left).span().start;
1647        let token_type = token.token_type;
1648
1649        let rule = get_rule(token_type);
1650
1651        if rule.is_empty() {
1652            return Err(QangCompilerError::new_syntax_error(
1653                "Unexpected token.".to_string(),
1654                SourceSpan::from_token(token),
1655                parser.source_map.clone(),
1656            ));
1657        }
1658
1659        let precedence: Precedence = (rule.precedence as u8 + 1).into();
1660
1661        let right = parse(parser, precedence)?;
1662        let right_span = parser.nodes.get_node(right).span();
1663        let span = SourceSpan::new(span_start, right_span.end);
1664
1665        match token_type {
1666            tokenizer::TokenType::Plus => {
1667                Ok(parser.nodes.create_node(AstNode::TermExpr(TermExprNode {
1668                    left,
1669                    operator: TermOperator::Add,
1670                    right,
1671                    span,
1672                })))
1673            }
1674            tokenizer::TokenType::Minus => {
1675                Ok(parser.nodes.create_node(AstNode::TermExpr(TermExprNode {
1676                    left,
1677                    operator: TermOperator::Subtract,
1678                    right,
1679                    span,
1680                })))
1681            }
1682            tokenizer::TokenType::Star => {
1683                Ok(parser
1684                    .nodes
1685                    .create_node(AstNode::FactorExpr(FactorExprNode {
1686                        left,
1687                        operator: FactorOperator::Multiply,
1688                        right,
1689                        span,
1690                    })))
1691            }
1692            tokenizer::TokenType::Slash => {
1693                Ok(parser
1694                    .nodes
1695                    .create_node(AstNode::FactorExpr(FactorExprNode {
1696                        left,
1697                        operator: FactorOperator::Divide,
1698                        right,
1699                        span,
1700                    })))
1701            }
1702            tokenizer::TokenType::Modulo => {
1703                Ok(parser
1704                    .nodes
1705                    .create_node(AstNode::FactorExpr(FactorExprNode {
1706                        left,
1707                        operator: FactorOperator::Modulo,
1708                        right,
1709                        span,
1710                    })))
1711            }
1712            tokenizer::TokenType::EqualsEquals => {
1713                Ok(parser
1714                    .nodes
1715                    .create_node(AstNode::EqualityExpr(EqualityExprNode {
1716                        left,
1717                        operator: EqualityOperator::Equal,
1718                        right,
1719                        span,
1720                    })))
1721            }
1722            tokenizer::TokenType::BangEquals => {
1723                Ok(parser
1724                    .nodes
1725                    .create_node(AstNode::EqualityExpr(EqualityExprNode {
1726                        left,
1727                        operator: EqualityOperator::NotEqual,
1728                        right,
1729                        span,
1730                    })))
1731            }
1732            tokenizer::TokenType::Is => {
1733                Ok(parser
1734                    .nodes
1735                    .create_node(AstNode::EqualityExpr(EqualityExprNode {
1736                        left,
1737                        operator: EqualityOperator::Is,
1738                        right,
1739                        span,
1740                    })))
1741            }
1742            tokenizer::TokenType::Less => {
1743                Ok(parser
1744                    .nodes
1745                    .create_node(AstNode::ComparisonExpr(ComparisonExprNode {
1746                        left,
1747                        operator: ComparisonOperator::Less,
1748                        right,
1749                        span,
1750                    })))
1751            }
1752            tokenizer::TokenType::LessEquals => {
1753                Ok(parser
1754                    .nodes
1755                    .create_node(AstNode::ComparisonExpr(ComparisonExprNode {
1756                        left,
1757                        operator: ComparisonOperator::LessEqual,
1758                        right,
1759                        span,
1760                    })))
1761            }
1762            tokenizer::TokenType::Greater => {
1763                Ok(parser
1764                    .nodes
1765                    .create_node(AstNode::ComparisonExpr(ComparisonExprNode {
1766                        left,
1767                        operator: ComparisonOperator::Greater,
1768                        right,
1769                        span,
1770                    })))
1771            }
1772            tokenizer::TokenType::GreaterEquals => {
1773                Ok(parser
1774                    .nodes
1775                    .create_node(AstNode::ComparisonExpr(ComparisonExprNode {
1776                        left,
1777                        operator: ComparisonOperator::GreaterEqual,
1778                        right,
1779                        span,
1780                    })))
1781            }
1782            tokenizer::TokenType::And => {
1783                Ok(parser
1784                    .nodes
1785                    .create_node(AstNode::LogicalAndExpr(LogicalAndExprNode {
1786                        left,
1787                        right,
1788                        span,
1789                    })))
1790            }
1791            tokenizer::TokenType::Or => {
1792                Ok(parser
1793                    .nodes
1794                    .create_node(AstNode::LogicalOrExpr(LogicalOrExprNode {
1795                        left,
1796                        right,
1797                        span,
1798                    })))
1799            }
1800            _ => Err(crate::QangCompilerError::new_syntax_error(
1801                "Unknown operator.".to_string(),
1802                span,
1803                parser.source_map.clone(),
1804            )),
1805        }
1806    }
1807
1808    fn ternary(parser: &mut Parser, left: NodeId) -> ParseResult<NodeId> {
1809        let then_expr = parse(parser, Precedence::Ternary)?;
1810
1811        parser.consume(
1812            tokenizer::TokenType::Colon,
1813            "Expect ':' after then expression in ternary.",
1814        )?;
1815
1816        let else_expr = parse(parser, Precedence::Ternary)?;
1817
1818        let left_span = parser.nodes.get_node(left).span();
1819        let else_expr_span = parser.nodes.get_node(else_expr).span();
1820        let span = SourceSpan::combine(left_span, else_expr_span);
1821
1822        let node_id = parser
1823            .nodes
1824            .create_node(AstNode::TernaryExpr(TernaryExprNode {
1825                condition: left,
1826                then_expr,
1827                else_expr,
1828                span,
1829            }));
1830
1831        Ok(node_id)
1832    }
1833
1834    fn pipe(parser: &mut Parser, left: NodeId) -> ParseResult<NodeId> {
1835        let right = parse(parser, (Precedence::Pipe as u8 + 1).into())?;
1836        let left_span = parser.nodes.get_node(left).span();
1837        let right_span = parser.nodes.get_node(right).span();
1838        let span = SourceSpan::combine(left_span, right_span);
1839
1840        let node_id =
1841            parser
1842                .nodes
1843                .create_node(AstNode::PipeExpr(PipeExprNode { left, right, span }));
1844
1845        Ok(node_id)
1846    }
1847
1848    fn call(parser: &mut Parser, left: NodeId) -> ParseResult<NodeId> {
1849        let operation = match parser.previous_token.as_ref().unwrap().token_type {
1850            tokenizer::TokenType::LeftParen => {
1851                let args = parse_arguments(parser)?;
1852                parser.consume(
1853                    tokenizer::TokenType::RightParen,
1854                    "Expect ')' after arguments.",
1855                )?;
1856                let start = parser.nodes.get_node(left).span().end;
1857                let end = get_previous_token(parser).end;
1858                parser.nodes.create_node(AstNode::CallOperation(CallNode {
1859                    args,
1860                    span: SourceSpan { start, end },
1861                }))
1862            }
1863            tokenizer::TokenType::Dot => {
1864                parser.consume(
1865                    tokenizer::TokenType::Identifier,
1866                    "Expect property name after '.'.",
1867                )?;
1868                let property_span = parser.get_previous_span();
1869                let property_name = parser
1870                    .previous_token
1871                    .as_ref()
1872                    .map(|t| t.lexeme(&parser.source_map))
1873                    .unwrap();
1874                let property_handle = parser
1875                    .strings
1876                    .intern(&property_name.iter().collect::<String>());
1877                let identifier = parser
1878                    .nodes
1879                    .create_node(AstNode::Identifier(IdentifierNode {
1880                        name: property_handle,
1881                        span: property_span,
1882                    }));
1883                parser
1884                    .nodes
1885                    .create_node(AstNode::PropertyAccess(PropertyNode {
1886                        identifier,
1887                        span: property_span,
1888                    }))
1889            }
1890            tokenizer::TokenType::OptionalDot => {
1891                parser.consume(
1892                    tokenizer::TokenType::Identifier,
1893                    "Expect property name after '?.'.",
1894                )?;
1895                let property_span = parser.get_previous_span();
1896                let property_name = parser
1897                    .previous_token
1898                    .as_ref()
1899                    .map(|t| t.lexeme(&parser.source_map))
1900                    .unwrap();
1901                let property_handle = parser
1902                    .strings
1903                    .intern(&property_name.iter().collect::<String>());
1904                let identifier = parser
1905                    .nodes
1906                    .create_node(AstNode::Identifier(IdentifierNode {
1907                        name: property_handle,
1908                        span: property_span,
1909                    }));
1910                parser
1911                    .nodes
1912                    .create_node(AstNode::OptionalPropertyAccess(OptionalPropertyNode {
1913                        identifier,
1914                        span: property_span,
1915                    }))
1916            }
1917            tokenizer::TokenType::LeftSquareBracket => {
1918                let index = parser.expression()?;
1919                parser.consume(
1920                    tokenizer::TokenType::RightSquareBracket,
1921                    "Expect ']' after array index.",
1922                )?;
1923                let index_span = parser.nodes.get_node(index).span();
1924                parser.nodes.create_node(AstNode::IndexAccess(IndexNode {
1925                    index,
1926                    span: index_span,
1927                }))
1928            }
1929            _ => return Ok(left), // This shouldn't happen
1930        };
1931
1932        let left_span = parser.nodes.get_node(left).span();
1933        let end_span = parser.get_previous_span();
1934        let span = SourceSpan::combine(left_span, end_span);
1935        let node_id = parser.nodes.create_node(AstNode::CallExpr(CallExprNode {
1936            callee: left,
1937            operation,
1938            span,
1939        }));
1940
1941        Ok(node_id)
1942    }
1943
1944    fn parse_arguments(parser: &mut Parser) -> ParseResult<NodeArrayId> {
1945        let arguments = parser.nodes.array.create();
1946
1947        if parser.check(tokenizer::TokenType::RightParen) {
1948            return Ok(arguments);
1949        }
1950
1951        let arg = parser.expression()?;
1952        parser.nodes.array.push(arguments, arg);
1953
1954        while parser.match_token(tokenizer::TokenType::Comma)
1955            && parser
1956                .current_token
1957                .as_ref()
1958                .map(|t| t.token_type != TokenType::RightParen)
1959                .unwrap_or(false)
1960        {
1961            let arg = parser.expression()?;
1962            parser.nodes.array.push(arguments, arg);
1963        }
1964
1965        let _ = parser.match_token(TokenType::Comma);
1966
1967        Ok(arguments)
1968    }
1969
1970    fn get_previous_token<'a>(parser: &'a Parser) -> &'a Token {
1971        // This should never panic because the expression parser will always have a previous token available to it.
1972        parser
1973            .previous_token
1974            .as_ref()
1975            .expect("Expected token but found none.")
1976    }
1977
1978    pub struct ParseRule {
1979        infix: Option<InfixParseFn>,
1980        prefix: Option<PrefixParseFn>,
1981        precedence: Precedence,
1982    }
1983
1984    impl ParseRule {
1985        fn is_empty(&self) -> bool {
1986            self.infix.is_none() && self.prefix.is_none() && self.precedence == Precedence::None
1987        }
1988
1989        fn is_not_empty(&self) -> bool {
1990            !self.is_empty()
1991        }
1992    }
1993
1994    const fn get_rule(token_type: tokenizer::TokenType) -> ParseRule {
1995        match token_type {
1996            tokenizer::TokenType::Number => ParseRule {
1997                prefix: Some(number),
1998                infix: None,
1999                precedence: Precedence::None,
2000            },
2001            tokenizer::TokenType::LeftParen => ParseRule {
2002                prefix: Some(grouping_or_lambda),
2003                infix: Some(call),
2004                precedence: Precedence::Call,
2005            },
2006            tokenizer::TokenType::Minus => ParseRule {
2007                prefix: Some(unary),
2008                infix: Some(binary),
2009                precedence: Precedence::Term,
2010            },
2011            tokenizer::TokenType::Plus => ParseRule {
2012                prefix: None,
2013                infix: Some(binary),
2014                precedence: Precedence::Term,
2015            },
2016            tokenizer::TokenType::Star => ParseRule {
2017                prefix: None,
2018                infix: Some(binary),
2019                precedence: Precedence::Factor,
2020            },
2021            tokenizer::TokenType::Slash => ParseRule {
2022                prefix: None,
2023                infix: Some(binary),
2024                precedence: Precedence::Factor,
2025            },
2026            tokenizer::TokenType::Modulo => ParseRule {
2027                prefix: None,
2028                infix: Some(binary),
2029                precedence: Precedence::Factor,
2030            },
2031            tokenizer::TokenType::Greater => ParseRule {
2032                prefix: None,
2033                infix: Some(binary),
2034                precedence: Precedence::Comparison,
2035            },
2036            tokenizer::TokenType::GreaterEquals => ParseRule {
2037                prefix: None,
2038                infix: Some(binary),
2039                precedence: Precedence::Comparison,
2040            },
2041            tokenizer::TokenType::Less => ParseRule {
2042                prefix: None,
2043                infix: Some(binary),
2044                precedence: Precedence::Comparison,
2045            },
2046            tokenizer::TokenType::LessEquals => ParseRule {
2047                prefix: None,
2048                infix: Some(binary),
2049                precedence: Precedence::Comparison,
2050            },
2051            tokenizer::TokenType::EqualsEquals => ParseRule {
2052                prefix: None,
2053                infix: Some(binary),
2054                precedence: Precedence::Equality,
2055            },
2056            tokenizer::TokenType::BangEquals => ParseRule {
2057                prefix: None,
2058                infix: Some(binary),
2059                precedence: Precedence::Equality,
2060            },
2061            tokenizer::TokenType::Is => ParseRule {
2062                prefix: None,
2063                infix: Some(binary),
2064                precedence: Precedence::Equality,
2065            },
2066            tokenizer::TokenType::And => ParseRule {
2067                prefix: None,
2068                infix: Some(binary),
2069                precedence: Precedence::And,
2070            },
2071            tokenizer::TokenType::Or => ParseRule {
2072                prefix: None,
2073                infix: Some(binary),
2074                precedence: Precedence::Or,
2075            },
2076            tokenizer::TokenType::False => ParseRule {
2077                prefix: Some(literal),
2078                infix: None,
2079                precedence: Precedence::None,
2080            },
2081            tokenizer::TokenType::True => ParseRule {
2082                prefix: Some(literal),
2083                infix: None,
2084                precedence: Precedence::None,
2085            },
2086            tokenizer::TokenType::Nil => ParseRule {
2087                prefix: Some(literal),
2088                infix: None,
2089                precedence: Precedence::None,
2090            },
2091            tokenizer::TokenType::Bang => ParseRule {
2092                prefix: Some(unary),
2093                infix: None,
2094                precedence: Precedence::None,
2095            },
2096            tokenizer::TokenType::String => ParseRule {
2097                prefix: Some(string),
2098                infix: None,
2099                precedence: Precedence::None,
2100            },
2101            tokenizer::TokenType::Identifier => ParseRule {
2102                prefix: Some(identifier),
2103                infix: None,
2104                precedence: Precedence::None,
2105            },
2106            tokenizer::TokenType::Question => ParseRule {
2107                prefix: None,
2108                infix: Some(ternary),
2109                precedence: Precedence::Ternary,
2110            },
2111            tokenizer::TokenType::Pipe => ParseRule {
2112                prefix: None,
2113                infix: Some(pipe),
2114                precedence: Precedence::Pipe,
2115            },
2116            tokenizer::TokenType::LeftSquareBracket => ParseRule {
2117                prefix: Some(array),
2118                infix: Some(call),
2119                precedence: Precedence::Call,
2120            },
2121            tokenizer::TokenType::Super => ParseRule {
2122                prefix: Some(literal),
2123                infix: None,
2124                precedence: Precedence::None,
2125            },
2126            tokenizer::TokenType::This => ParseRule {
2127                prefix: Some(literal),
2128                infix: None,
2129                precedence: Precedence::None,
2130            },
2131            tokenizer::TokenType::Dot => ParseRule {
2132                prefix: None,
2133                infix: Some(call),
2134                precedence: Precedence::Call,
2135            },
2136            tokenizer::TokenType::DoubleLeftBrace => ParseRule {
2137                prefix: Some(object),
2138                infix: None,
2139                precedence: Precedence::None,
2140            },
2141            tokenizer::TokenType::OptionalDot => ParseRule {
2142                prefix: None,
2143                infix: Some(call),
2144                precedence: Precedence::Call,
2145            },
2146            tokenizer::TokenType::DoubleBar => ParseRule {
2147                prefix: None,
2148                infix: Some(map_expression),
2149                precedence: Precedence::Call,
2150            },
2151            tokenizer::TokenType::OptionalBar => ParseRule {
2152                prefix: None,
2153                infix: Some(optional_map_expression),
2154                precedence: Precedence::Call,
2155            },
2156            tokenizer::TokenType::When => ParseRule {
2157                prefix: Some(when_expression),
2158                infix: None,
2159                precedence: Precedence::None,
2160            },
2161            _ => ParseRule {
2162                prefix: None,
2163                infix: None,
2164                precedence: Precedence::None,
2165            },
2166        }
2167    }
2168
2169    pub fn parse(parser: &mut Parser, precedence: Precedence) -> ParseResult<NodeId> {
2170        parser.advance();
2171
2172        let prefix_rule = parser
2173            .previous_token
2174            .as_ref()
2175            .map(|t| get_rule(t.token_type))
2176            // .filter(ParseRule::is_not_empty)
2177            .and_then(|r| r.prefix);
2178
2179        let mut expr = match prefix_rule {
2180            Some(rule) => rule(parser)?,
2181            None => {
2182                let span = parser
2183                    .previous_token
2184                    .as_ref()
2185                    .map(SourceSpan::from_token)
2186                    .unwrap_or_default();
2187
2188                return Err(crate::QangCompilerError::new_syntax_error(
2189                    "Expected expression.".to_string(),
2190                    span,
2191                    parser.source_map.clone(),
2192                ));
2193            }
2194        };
2195
2196        while let Some(current_token) = &parser.current_token {
2197            let rule = get_rule(current_token.token_type);
2198
2199            if precedence <= rule.precedence && rule.is_not_empty() {
2200                parser.advance();
2201
2202                if let Some(infix_rule) = rule.infix {
2203                    expr = infix_rule(parser, expr)?;
2204                } else {
2205                    break;
2206                }
2207            } else {
2208                break;
2209            }
2210        }
2211
2212        // Check for potential malformed expressions
2213        // If we have an identifier or other expression-starting token immediately following
2214        // our parsed expression, it's likely a syntax error
2215        if let Some(current_token) = &parser.current_token {
2216            match current_token.token_type {
2217                TokenType::Identifier
2218                | TokenType::Number
2219                | TokenType::String
2220                | TokenType::True
2221                | TokenType::False
2222                | TokenType::Nil
2223                | TokenType::This
2224                | TokenType::Super
2225                | TokenType::LeftParen => {
2226                    // We have an expression-like token that couldn't be parsed as part of the current expression
2227                    // This suggests a syntax error like missing operator or semicolon.
2228                    let location = parser
2229                        .previous_token
2230                        .as_ref()
2231                        .map(|t| SourceSpan::from_token(t).end)
2232                        .unwrap_or(SourceSpan::from_token(current_token).start);
2233
2234                    let span = SourceSpan::new(location, location); // TODO move the logic to get this span into a helper in the Parser.
2235
2236                    return Err(crate::QangCompilerError::new_syntax_error(
2237                        "Unexpected oprand. Missing operator or ';'.".to_string(),
2238                        span,
2239                        parser.source_map.clone(),
2240                    ));
2241                }
2242                _ => {}
2243            }
2244        }
2245
2246        Ok(expr)
2247    }
2248}