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 let check_token = if let Some(current) = &self.current_token {
234 current.token_type
235 } else {
236 return false;
237 };
238
239 if check_token == TokenType::LeftParen {
242 if let Some(next_token) = self.tokens.peek()
244 && next_token.token_type == TokenType::RightParen
245 {
246 return self
248 .tokens
249 .peek_ahead(1)
250 .map(|t| t.token_type == TokenType::Arrow)
251 .unwrap_or(false);
252 }
253 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 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 self.tokens
279 .peek()
280 .map(|t| t.token_type == TokenType::Arrow)
281 .unwrap_or(false)
282 } else {
283 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 if let Some(first_token) = self.tokens.peek() {
301 if first_token.token_type != TokenType::LeftParen {
302 return false;
303 }
304 if let Some(second_token) = self.tokens.peek_ahead(1) {
306 if second_token.token_type == TokenType::RightParen {
307 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 false
315 } else {
316 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 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]; 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(); 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.")?; 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, Ternary, Pipe, Or, And, Equality, Comparison, Term, Factor, Unary, Call, }
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 let is_lambda = parser.is_lambda_start_after_paren();
1136
1137 if is_lambda {
1138 let is_grouped_lambda = parser.check(TokenType::LeftParen);
1140
1141 let lambda_expr = lambda(parser)?;
1142
1143 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 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 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 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 let first_expr = parser.expression()?;
1381 parser.nodes.array.push(array_node_id, first_expr);
1382
1383 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 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 loop {
1570 if parser.check(TokenType::RightBrace) || parser.is_at_end() {
1572 break;
1573 }
1574
1575 if parser.check(TokenType::Else) {
1577 parser.advance(); parser.consume(TokenType::FatArrow, "Expected '=>' after 'else'.")?;
1579 else_branch = Some(parse(parser, Precedence::Ternary)?);
1580 let _ = parser.match_token(TokenType::Comma);
1582 break;
1583 }
1584
1585 let condition_start_span = parser.get_current_span();
1587
1588 let (condition, is_type_check) = if parser.check(TokenType::Is) {
1590 parser.advance(); parser.consume(TokenType::Identifier, "Expected type name after 'is'.")?;
1593 let type_name = parser.get_identifier()?;
1594 (type_name, true)
1595 } else {
1596 let cond = parse(parser, Precedence::Ternary)?;
1598
1599 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 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), };
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 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 .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 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 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); 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}