tenda_parser/
parser.rs

1use tenda_common::{
2    source::IdentifiedSource,
3    span::{SourceSpan, Span},
4};
5use tenda_scanner::{self, Token, TokenKind};
6
7use crate::{
8    ast::{self, FunctionParam},
9    closures,
10    parser_error::{unexpected_token, ParserError, Result},
11    scope_tracker::{BlockScope, ScopeTracker},
12    token_iter::TokenIterator,
13    token_slice,
14};
15
16pub struct Parser<'a> {
17    tokens: TokenIterator<'a>,
18    scope: ScopeTracker,
19    uid_counter: usize,
20    source_id: IdentifiedSource,
21}
22
23impl<'a> Parser<'a> {
24    pub fn new(stream: &'a [Token], source_id: IdentifiedSource) -> Parser<'a> {
25        Parser {
26            tokens: stream.into(),
27            scope: ScopeTracker::new(),
28            uid_counter: 0,
29            source_id,
30        }
31    }
32
33    pub fn parse(&mut self) -> Result<ast::Ast> {
34        let program = self.parse_program()?;
35
36        let mut ast = match self.tokens.peek() {
37            Some(token) if token.kind == TokenKind::Eof => program,
38            Some(token) => return Err(vec![unexpected_token!(token)]),
39            None => unreachable!(),
40        };
41
42        closures::annotate_ast_with_var_captures(&mut ast);
43
44        Ok(ast)
45    }
46
47    fn parse_program(&mut self) -> Result<ast::Ast> {
48        let mut stmt_list = vec![];
49        let mut errors: Vec<ParserError> = vec![];
50
51        let span_start = match self.tokens.peek() {
52            Some(token) => token.span.start(),
53            None => self.tokens.last_token().span.end(),
54        };
55
56        while self.tokens.is_next_valid() {
57            match self.parse_statement() {
58                Ok(stmt) => stmt_list.push(stmt),
59                Err(e) => {
60                    errors.extend(e);
61
62                    break;
63                }
64            }
65        }
66
67        if !errors.is_empty() {
68            Err(errors)
69        } else {
70            let span_end = stmt_list
71                .last()
72                .map_or(span_start, |stmt| stmt.get_span().end());
73
74            let span = SourceSpan::new(span_start, span_end, self.source_id);
75            let ast = ast::Ast::from(stmt_list, span);
76
77            Ok(ast)
78        }
79    }
80
81    fn parse_statement(&mut self) -> Result<ast::Stmt> {
82        let token = match self.tokens.peek() {
83            Some(token) if token.kind == TokenKind::Newline => {
84                self.tokens.advance_while(token_slice![Newline]);
85
86                return self.parse_statement();
87            }
88            Some(token) => token,
89            _ => unreachable!(),
90        };
91
92        let result = match token.kind {
93            TokenKind::Let => self.parse_declaration(),
94            TokenKind::If => match self.try_parse_if_expression_as_stmt()? {
95                Some(expr_stmt) => Ok(expr_stmt),
96                None => self.parse_if_statement(),
97            },
98            TokenKind::While => self.parse_while_statement(),
99            TokenKind::ForOrBreak => {
100                if self.tokens.check_sequence(token_slice![ForOrBreak, Each]) {
101                    self.parse_for_each_statement()
102                } else {
103                    self.parse_break_statement()
104                }
105            }
106            TokenKind::Do => self.parse_do_statement(),
107            TokenKind::Return => self.parse_return_statement(),
108            TokenKind::Continue => self.parse_continue_statement(),
109            _ => self.parse_expression().map(ast::Stmt::Expr),
110        }?;
111
112        match self.tokens.peek() {
113            Some(token) if token.kind == TokenKind::Newline => {
114                self.tokens.advance_while(token_slice![Newline]);
115            }
116            Some(token)
117                if matches!(
118                    token.kind,
119                    TokenKind::Eof | TokenKind::BlockEnd | TokenKind::Else
120                ) => {}
121            Some(token) => {
122                return Err(vec![unexpected_token!(token)]);
123            }
124            None => unreachable!(),
125        }
126
127        Ok(result)
128    }
129
130    fn parse_block(
131        &mut self,
132        end_token_types: &[TokenKind],
133        scope: BlockScope,
134    ) -> Result<(ast::Stmt, TokenKind)> {
135        let span_start = self.tokens.next().unwrap().span.start();
136
137        self.parse_block_contents(end_token_types, scope, Some(span_start))
138    }
139
140    fn parse_block_contents(
141        &mut self,
142        end_token_types: &[TokenKind],
143        scope: BlockScope,
144        span_start: Option<usize>,
145    ) -> Result<(ast::Stmt, TokenKind)> {
146        let _guard = self.scope.guard(scope);
147        let _newline_guard = self.tokens.halt_ignoring_newline();
148
149        self.tokens.advance_while(token_slice![Newline]);
150
151        let block_first_token_span = match self.tokens.peek() {
152            Some(token) => &token.span,
153            None => {
154                return Err(vec![ParserError::UnexpectedEoi {
155                    span: self.tokens.last_token().span.clone(),
156                }])
157            }
158        };
159
160        let span_start = span_start.unwrap_or_else(|| block_first_token_span.start());
161        let inner_span_start = block_first_token_span.start();
162        let mut current_inner_span_end = block_first_token_span.end();
163
164        let mut stmt_list = vec![];
165
166        let end_token = loop {
167            let token = match self.tokens.peek() {
168                Some(token) => token,
169                None => unreachable!(),
170            };
171
172            if end_token_types.contains(&token.kind) {
173                break Ok(self.tokens.next().unwrap());
174            }
175
176            current_inner_span_end = token.span.end();
177
178            match self.parse_statement() {
179                Ok(stmt) => stmt_list.push(stmt),
180                Err(e) => break Err(e),
181            };
182        }?;
183
184        let span_end = end_token.span.end();
185        let span = SourceSpan::new(span_start, span_end, self.source_id);
186        let inner_span = SourceSpan::new(inner_span_start, current_inner_span_end, self.source_id);
187
188        let ast = ast::Ast::from(stmt_list, inner_span);
189        let block_stmt = ast::Block::new(ast, span);
190        let block_stmt = ast::Stmt::Block(block_stmt);
191
192        Ok((block_stmt, end_token.kind))
193    }
194
195    fn try_parse_if_expression_as_stmt(&mut self) -> Result<Option<ast::Stmt>> {
196        let saved_tokens = self.tokens.clone();
197
198        match self.parse_expression() {
199            Err(_) => {
200                self.tokens = saved_tokens;
201                Ok(None)
202            }
203            Ok(expr) => {
204                let _guard = self.tokens.set_ignoring_newline();
205
206                let is_stmt_continuation = matches!(
207                    self.tokens.peek(),
208                    Some(token) if matches!(token.kind, TokenKind::BlockEnd | TokenKind::Else)
209                );
210
211                if is_stmt_continuation {
212                    self.tokens = saved_tokens;
213                    Ok(None)
214                } else {
215                    Ok(Some(ast::Stmt::Expr(expr)))
216                }
217            }
218        }
219    }
220
221    fn parse_if_statement(&mut self) -> Result<ast::Stmt> {
222        let span_start = self.tokens.next().unwrap().span.start();
223        let condition = self.parse_expression()?;
224
225        self.skip_token(TokenKind::Then)?;
226
227        let (then_branch, block_end_delimiter) =
228            self.parse_block(token_slice![BlockEnd, Else], BlockScope::If)?;
229
230        let else_branch = match block_end_delimiter {
231            TokenKind::Else => {
232                if self.tokens.is_next_token(TokenKind::If) {
233                    Some(self.parse_if_statement()?)
234                } else {
235                    let (else_branch, _) =
236                        self.parse_block(token_slice![BlockEnd], BlockScope::Else)?;
237
238                    Some(else_branch)
239                }
240            }
241            TokenKind::BlockEnd => None,
242            _ => unreachable!(),
243        };
244
245        let span_end = else_branch
246            .as_ref()
247            .map_or(then_branch.get_span().end(), |else_branch| {
248                else_branch.get_span().end()
249            });
250
251        let span = SourceSpan::new(span_start, span_end, self.source_id);
252        let stmt = ast::Cond::new(condition, then_branch, else_branch, span);
253
254        Ok(ast::Stmt::Cond(stmt))
255    }
256
257    fn parse_while_statement(&mut self) -> Result<ast::Stmt> {
258        let span_start = self.tokens.next().unwrap().span.start();
259        let condition = self.parse_expression()?;
260
261        if !self.tokens.is_next_token(TokenKind::Do) {
262            let token = self.tokens.next().unwrap();
263            return Err(vec![unexpected_token!(token)]);
264        }
265
266        let (body, _) = self.parse_block(token_slice![BlockEnd], BlockScope::Loop)?;
267
268        let span_end = body.get_span().end();
269        let span = SourceSpan::new(span_start, span_end, self.source_id);
270
271        let while_stmt = ast::While::new(condition, body, span);
272        let while_stmt = ast::Stmt::While(while_stmt);
273
274        Ok(while_stmt)
275    }
276
277    fn parse_for_each_statement(&mut self) -> Result<ast::Stmt> {
278        let span_start = self.tokens.next().unwrap().span.start();
279
280        self.skip_token(TokenKind::Each)?;
281
282        let (name, name_span) = self.consume_identifier()?;
283
284        self.skip_token(TokenKind::In)?;
285
286        let iterable = self.parse_expression()?;
287
288        if !self.tokens.is_next_token(TokenKind::Do) {
289            let token = self.tokens.next().unwrap();
290
291            return Err(vec![unexpected_token!(token)]);
292        }
293
294        let (body, _) = self.parse_block(token_slice![BlockEnd], BlockScope::Loop)?;
295
296        let span_end = body.get_span().end();
297        let span = SourceSpan::new(span_start, span_end, self.source_id);
298
299        let for_each_item = ast::ForEachItem::new(name, self.gen_uid(), name_span);
300        let for_each_stmt = ast::ForEach::new(for_each_item, iterable, body, span);
301        let for_each_stmt = ast::Stmt::ForEach(for_each_stmt);
302
303        Ok(for_each_stmt)
304    }
305
306    fn parse_declaration(&mut self) -> Result<ast::Stmt> {
307        let span_start = self.tokens.next().unwrap().span.start();
308        let (name, _) = self.consume_identifier()?;
309
310        match self.tokens.peek() {
311            Some(token) if token.kind == TokenKind::LeftParen => {
312                let parameters = self.parse_function_parameters_signature()?;
313
314                self.skip_token(TokenKind::EqualSign)?;
315                self.tokens.advance_while(token_slice![Newline]);
316
317                let stmt = if self.tokens.is_next_token(TokenKind::Do) {
318                    self.tokens.next().unwrap();
319
320                    let (body, _) = self.parse_block_contents(
321                        token_slice![BlockEnd],
322                        BlockScope::Function,
323                        None,
324                    )?;
325
326                    body
327                } else {
328                    ast::Stmt::Expr(self.parse_expression()?)
329                };
330
331                let span_end = stmt.get_span().end();
332                let span = SourceSpan::new(span_start, span_end, self.source_id);
333
334                let function_decl =
335                    ast::FunctionDecl::new(name, parameters, stmt, self.gen_uid(), span);
336                let function_decl = ast::Decl::Function(function_decl);
337                let function_decl = ast::Stmt::Decl(function_decl);
338
339                Ok(function_decl)
340            }
341            Some(token) if token.kind == TokenKind::EqualSign => {
342                self.skip_token(TokenKind::EqualSign)?;
343
344                let expr = self.parse_expression()?;
345
346                let span_end = expr.get_span().end();
347                let span = SourceSpan::new(span_start, span_end, self.source_id);
348
349                let local_decl = ast::LocalDecl::new(name, expr, self.gen_uid(), span);
350                let local_decl = ast::Decl::Local(local_decl);
351
352                Ok(ast::Stmt::Decl(local_decl))
353            }
354            Some(token) => Err(vec![unexpected_token!(token)]),
355            None => Err(vec![ParserError::UnexpectedEoi {
356                span: self.tokens.last_token().span.clone(),
357            }]),
358        }
359    }
360
361    fn parse_do_statement(&mut self) -> Result<ast::Stmt> {
362        let span_start = self.tokens.next().unwrap().span.start();
363
364        let (body, _) = self.parse_block(token_slice![BlockEnd], BlockScope::Global)?;
365
366        let span_end = body.get_span().end();
367        let span = SourceSpan::new(span_start, span_end, self.source_id);
368
369        let body = ast::Ast::from(vec![body], span.clone());
370        let do_stmt = ast::Block::new(body, span);
371        let do_stmt = ast::Stmt::Block(do_stmt);
372
373        Ok(do_stmt)
374    }
375
376    fn parse_return_statement(&mut self) -> Result<ast::Stmt> {
377        let return_token = self.tokens.next().unwrap();
378
379        if !self.scope.has_scope(BlockScope::Function) {
380            return Err(vec![ParserError::IllegalReturn {
381                span: return_token.span.clone(),
382            }]);
383        }
384
385        let expr = match self.tokens.peek() {
386            Some(token) if token.kind != TokenKind::Newline => Some(self.parse_expression()?),
387            _ => None,
388        };
389
390        let span_start = return_token.span.start();
391        let span_end = expr
392            .as_ref()
393            .map_or(return_token.span.end(), |expr| expr.get_span().end());
394        let span = SourceSpan::new(span_start, span_end, self.source_id);
395
396        let return_stmt = ast::Return::new(expr, span);
397
398        Ok(ast::Stmt::Return(return_stmt))
399    }
400
401    fn parse_break_statement(&mut self) -> Result<ast::Stmt> {
402        let break_token = self.tokens.next().unwrap();
403
404        if !self.scope.has_scope(BlockScope::Loop) {
405            return Err(vec![ParserError::IllegalBreak {
406                span: break_token.span.clone(),
407            }]);
408        }
409
410        let break_stmt = ast::Break::new(break_token.span.clone());
411        let break_stmt = ast::Stmt::Break(break_stmt);
412
413        Ok(break_stmt)
414    }
415
416    fn parse_continue_statement(&mut self) -> Result<ast::Stmt> {
417        let continue_token = self.tokens.next().unwrap();
418
419        if !self.scope.has_scope(BlockScope::Loop) {
420            return Err(vec![ParserError::IllegalContinue {
421                span: continue_token.span.clone(),
422            }]);
423        }
424
425        let continue_stmt = ast::Continue::new(continue_token.span.clone());
426        let continue_stmt = ast::Stmt::Continue(continue_stmt);
427
428        Ok(continue_stmt)
429    }
430
431    fn parse_expression(&mut self) -> Result<ast::Expr> {
432        let _guard = self.tokens.set_ignoring_newline();
433
434        self.parse_assignment()
435    }
436
437    fn parse_assignment(&mut self) -> Result<ast::Expr> {
438        let expr = self.parse_ternary()?;
439
440        if let Some(equal_sign) = self.tokens.consume_one_of(token_slice![EqualSign]) {
441            let value = self.parse_assignment()?;
442
443            return match expr {
444                ast::Expr::Variable(_) | ast::Expr::Access(_) => {
445                    let span_start = expr.get_span().start();
446                    let span_end = value.get_span().end();
447                    let span = SourceSpan::new(span_start, span_end, self.source_id);
448
449                    let assign_expr = ast::Assign::new(expr, value, span);
450                    let assign_expr = ast::Expr::Assign(assign_expr);
451
452                    Ok(assign_expr)
453                }
454                _ => Err(vec![ParserError::InvalidAssignmentTarget {
455                    span: equal_sign.span.clone(),
456                    token: equal_sign.clone_ref(),
457                }]),
458            };
459        }
460
461        Ok(expr)
462    }
463
464    fn parse_ternary(&mut self) -> Result<ast::Expr> {
465        if let Some(token) = self.tokens.consume_one_of(token_slice![If]) {
466            let span_start = token.span.start();
467            let condition = self.parse_logical_or()?;
468
469            self.skip_token(TokenKind::Then)?;
470            self.parse_ternary_branches(condition, span_start)
471        } else {
472            self.parse_logical_or()
473        }
474    }
475
476    fn parse_logical_or(&mut self) -> Result<ast::Expr> {
477        let mut expr = self.parse_logical_and()?;
478
479        while let Some(op) = self.tokens.consume_one_of(token_slice![Or]) {
480            let lhs = expr;
481            let rhs = self.parse_logical_and()?;
482
483            let span_start = lhs.get_span().start();
484            let span_end = rhs.get_span().end();
485            let span = SourceSpan::new(span_start, span_end, self.source_id);
486
487            let binary_op = ast::BinaryOp::new(lhs, op.into(), rhs, span);
488
489            expr = ast::Expr::Binary(binary_op);
490        }
491
492        Ok(expr)
493    }
494
495    fn parse_logical_and(&mut self) -> Result<ast::Expr> {
496        let mut expr = self.parse_equality()?;
497
498        while let Some(op) = self.tokens.consume_one_of(token_slice![And]) {
499            let lhs = expr;
500            let rhs = self.parse_equality()?;
501
502            let span_start = lhs.get_span().start();
503            let span_end = rhs.get_span().end();
504            let span = SourceSpan::new(span_start, span_end, self.source_id);
505
506            let binary_op = ast::BinaryOp::new(lhs, op.into(), rhs, span);
507
508            expr = ast::Expr::Binary(binary_op);
509        }
510
511        Ok(expr)
512    }
513
514    fn parse_equality(&mut self) -> Result<ast::Expr> {
515        let mut expr = self.parse_comparison()?;
516
517        loop {
518            let op: Option<ast::BinaryOperator> = {
519                if self.tokens.consume_one_of(token_slice![Equals]).is_some() {
520                    Some(ast::BinaryOperator::Equality)
521                } else if self.tokens.consume_one_of(token_slice![Has]).is_some() {
522                    Some(ast::BinaryOperator::Has)
523                } else if self
524                    .tokens
525                    .consume_sequence(token_slice![Not, Has])
526                    .is_some()
527                {
528                    Some(ast::BinaryOperator::Lacks)
529                } else if self
530                    .tokens
531                    .consume_sequence(token_slice![Not, Equals])
532                    .is_some()
533                {
534                    Some(ast::BinaryOperator::Inequality)
535                } else {
536                    None
537                }
538            };
539
540            if let Some(op) = op {
541                let lhs = expr;
542                let rhs = self.parse_comparison()?;
543
544                let span_start = lhs.get_span().start();
545                let span_end = rhs.get_span().end();
546                let span = SourceSpan::new(span_start, span_end, self.source_id);
547
548                let binary_op = ast::BinaryOp::new(lhs, op, rhs, span);
549
550                expr = ast::Expr::Binary(binary_op);
551            } else {
552                break;
553            }
554        }
555
556        Ok(expr)
557    }
558
559    fn parse_comparison(&mut self) -> Result<ast::Expr> {
560        let mut expr = self.parse_range()?;
561
562        const COMPARISON_OPS: &[TokenKind] =
563            token_slice![Greater, GreaterOrEqual, Less, LessOrEqual];
564
565        if let Some(op) = self.tokens.consume_one_of(COMPARISON_OPS) {
566            let lhs = expr;
567            let rhs = self.parse_range()?;
568
569            if let Some(op) = self.tokens.consume_one_of(COMPARISON_OPS) {
570                return Err(vec![ParserError::InvalidChaining {
571                    op: op.clone(),
572                    span: op.span.clone(),
573                    message: Some("operadores de comparação não podem ser encadeados".to_string()),
574                    help: Some("use parênteses para separar as expressões".to_string()),
575                }]);
576            }
577
578            let span_start = lhs.get_span().start();
579            let span_end = rhs.get_span().end();
580            let span = SourceSpan::new(span_start, span_end, self.source_id);
581
582            let binary_op = ast::BinaryOp::new(lhs, op.into(), rhs, span);
583
584            expr = ast::Expr::Binary(binary_op);
585        }
586
587        Ok(expr)
588    }
589
590    fn parse_range(&mut self) -> Result<ast::Expr> {
591        let lhs = self.parse_term()?;
592
593        if let Some(op) = self.tokens.consume_one_of(token_slice![Until]) {
594            let rhs = self.parse_term()?;
595
596            if let Some(op) = self.tokens.consume_one_of(token_slice![Until]) {
597                return Err(vec![ParserError::InvalidChaining {
598                    op: op.clone(),
599                    span: op.span.clone(),
600                    message: None,
601                    help: None,
602                }]);
603            }
604
605            let span_start = lhs.get_span().start();
606            let span_end = rhs.get_span().end();
607            let span = SourceSpan::new(span_start, span_end, self.source_id);
608
609            let binary_op = ast::BinaryOp::new(lhs, op.into(), rhs, span);
610
611            return Ok(ast::Expr::Binary(binary_op));
612        }
613
614        Ok(lhs)
615    }
616
617    fn parse_term(&mut self) -> Result<ast::Expr> {
618        let mut expr = self.parse_factor()?;
619
620        while let Some(op) = self.tokens.consume_one_of(token_slice![Plus, Minus]) {
621            let lhs = expr;
622            let rhs = self.parse_factor()?;
623
624            let span_start = lhs.get_span().start();
625            let span_end = rhs.get_span().end();
626            let span = SourceSpan::new(span_start, span_end, self.source_id);
627
628            let binary_op = ast::BinaryOp::new(lhs, op.into(), rhs, span);
629
630            expr = ast::Expr::Binary(binary_op);
631        }
632
633        Ok(expr)
634    }
635
636    fn parse_factor(&mut self) -> Result<ast::Expr> {
637        let mut expr = self.parse_exponent()?;
638
639        while let Some(op) = self
640            .tokens
641            .consume_one_of(token_slice![Star, Slash, Percent])
642        {
643            let lhs = expr;
644            let rhs = self.parse_exponent()?;
645
646            let span_start = lhs.get_span().start();
647            let span_end = rhs.get_span().end();
648            let span = SourceSpan::new(span_start, span_end, self.source_id);
649
650            let binary_op = ast::BinaryOp::new(lhs, op.into(), rhs, span);
651
652            expr = ast::Expr::Binary(binary_op);
653        }
654
655        Ok(expr)
656    }
657
658    fn parse_exponent(&mut self) -> Result<ast::Expr> {
659        let mut expr = self.parse_unary()?;
660
661        while let Some(op) = self.tokens.consume_one_of(token_slice![Caret]) {
662            let lhs = expr;
663            let rhs = self.parse_unary()?;
664
665            let span_start = lhs.get_span().start();
666            let span_end = rhs.get_span().end();
667            let span = SourceSpan::new(span_start, span_end, self.source_id);
668
669            let binary_op = ast::BinaryOp::new(lhs, op.into(), rhs, span);
670
671            expr = ast::Expr::Binary(binary_op);
672        }
673
674        Ok(expr)
675    }
676
677    fn parse_unary(&mut self) -> Result<ast::Expr> {
678        if let Some(op) = self.tokens.consume_one_of(token_slice![Minus, Not]) {
679            let rhs = self.parse_unary()?;
680
681            let span_start = op.span.start();
682            let span_end = rhs.get_span().end();
683            let span = SourceSpan::new(span_start, span_end, self.source_id);
684
685            let unary_op = ast::UnaryOp::new(op.into(), rhs, span);
686
687            Ok(ast::Expr::Unary(unary_op))
688        } else {
689            self.parse_postfix()
690        }
691    }
692
693    fn parse_postfix(&mut self) -> Result<ast::Expr> {
694        let mut lhs = self.parse_primary()?;
695
696        while let Some(token) =
697            self.tokens
698                .consume_one_of(token_slice![LeftParen, LeftBracket, Dot])
699        {
700            match token.kind {
701                TokenKind::LeftParen => lhs = self.parse_function_call(lhs)?,
702                TokenKind::LeftBracket => lhs = self.parse_access(lhs)?,
703                TokenKind::Dot => lhs = self.parse_dot_access(lhs)?,
704                _ => unreachable!(),
705            }
706        }
707
708        Ok(lhs)
709    }
710
711    fn parse_function_call(&mut self, name: ast::Expr) -> Result<ast::Expr> {
712        let mut arguments = vec![];
713
714        if !self.tokens.is_next_token(TokenKind::RightParen) {
715            loop {
716                arguments.push(self.parse_expression()?);
717
718                if self.tokens.consume_one_of(token_slice![Comma]).is_none() {
719                    break;
720                }
721            }
722        }
723
724        if self.tokens.is_next_eof() {
725            return Err(vec![ParserError::UnexpectedEoi {
726                span: self.tokens.last_token().span.clone(),
727            }]);
728        }
729
730        let right_paran = match self.tokens.consume_one_of(token_slice![RightParen]) {
731            Some(token) => token,
732            _ => {
733                return Err(vec![ParserError::MissingParentheses {
734                    span: self.tokens.next().unwrap().span.clone(),
735                }]);
736            }
737        };
738
739        let span_start = name.get_span().start();
740        let span_end = right_paran.span.end();
741        let span = SourceSpan::new(span_start, span_end, self.source_id);
742
743        let call_expr = ast::Call::new(name, arguments, span);
744        let call_expr = ast::Expr::Call(call_expr);
745
746        Ok(call_expr)
747    }
748
749    fn parse_access(&mut self, name: ast::Expr) -> Result<ast::Expr> {
750        let index = self.parse_expression()?;
751
752        if self.tokens.is_next_eof() {
753            return Err(vec![ParserError::UnexpectedEoi {
754                span: self.tokens.last_token().span.clone(),
755            }]);
756        }
757
758        let closing_bracket = match self.tokens.consume_one_of(token_slice![RightBracket]) {
759            Some(token) => token,
760            _ => {
761                return Err(vec![ParserError::MissingBrackets {
762                    span: self.tokens.next().unwrap().span.clone(),
763                }]);
764            }
765        };
766
767        let span_start = name.get_span().start();
768        let span_end = closing_bracket.span.end();
769        let span = SourceSpan::new(span_start, span_end, self.source_id);
770
771        let access_expr = ast::Access::new(name, index, span);
772        let access_expr = ast::Expr::Access(access_expr);
773
774        Ok(access_expr)
775    }
776
777    fn parse_primary(&mut self) -> Result<ast::Expr> {
778        use TokenKind::*;
779
780        let token = match self.tokens.peek() {
781            Some(token) => token,
782            _ => unreachable!(),
783        };
784
785        let span = token.span.clone();
786
787        match token.kind {
788            Number | True | False | String | Nil => self.parse_literal(),
789            Identifier => self.parse_variable(),
790            LeftParen => self.parse_grouping(),
791            LeftBracket => self.parse_list(),
792            LeftBrace => self.parse_associative_array(),
793            Function => self.parse_anonymous_function(),
794            Eof => {
795                self.tokens.next().unwrap();
796                Err(vec![ParserError::UnexpectedEoi { span }])
797            }
798            _ => {
799                let token = self.tokens.next().unwrap();
800                Err(vec![unexpected_token!(token)])
801            }
802        }
803    }
804
805    fn parse_literal(&mut self) -> Result<ast::Expr> {
806        let token = self.tokens.next().unwrap();
807
808        let literal_expr = ast::Literal::new(
809            token.literal.as_ref().unwrap().clone(),
810            token.clone().span.clone(),
811        );
812
813        let literal_expr = ast::Expr::Literal(literal_expr);
814
815        Ok(literal_expr)
816    }
817
818    fn parse_variable(&mut self) -> Result<ast::Expr> {
819        let token = self.tokens.next().unwrap();
820        let span = token.span.clone();
821
822        let name = match token.literal.as_ref().unwrap() {
823            tenda_scanner::Literal::String(string) => string,
824            _ => unreachable!(),
825        };
826
827        let id = self.gen_uid();
828        let variable_expr = ast::Variable::new(name.clone(), id, span);
829
830        Ok(ast::Expr::Variable(variable_expr))
831    }
832
833    fn parse_grouping(&mut self) -> Result<ast::Expr> {
834        let token = self.tokens.next().unwrap();
835        let expr = self.parse_expression()?;
836
837        let closing_paren = match self.tokens.consume_one_of(token_slice![RightParen]) {
838            Some(token) => token,
839            _ => {
840                return Err(vec![ParserError::MissingParentheses {
841                    span: self.tokens.next().unwrap().span.clone(),
842                }])
843            }
844        };
845
846        let span_start = token.span.start();
847        let span_end = closing_paren.span.end();
848        let span = SourceSpan::new(span_start, span_end, self.source_id);
849
850        let grouping_expr = ast::Grouping::new(expr, span);
851        let grouping_expr = ast::Expr::Grouping(grouping_expr);
852
853        Ok(grouping_expr)
854    }
855
856    fn parse_anonymous_function(&mut self) -> Result<ast::Expr> {
857        let function_token = self.tokens.next().unwrap();
858        let parameters = self.parse_function_parameters_signature()?;
859
860        self.skip_token(TokenKind::Arrow)?;
861
862        let stmt = if self.tokens.is_next_token(TokenKind::Do) {
863            self.tokens.next().unwrap();
864
865            let (body, _) =
866                self.parse_block_contents(token_slice![BlockEnd], BlockScope::Function, None)?;
867
868            body
869        } else {
870            ast::Stmt::Expr(self.parse_expression()?)
871        };
872
873        let span_start = function_token.span.start();
874        let span_end = stmt.get_span().end();
875        let span = SourceSpan::new(span_start, span_end, self.source_id);
876
877        let function_expr = ast::AnonymousFunction::new(parameters, stmt, self.gen_uid(), span);
878        let function_expr = ast::Expr::AnonymousFunction(function_expr);
879
880        Ok(function_expr)
881    }
882
883    fn parse_function_parameters_signature(&mut self) -> Result<Vec<ast::FunctionParam>> {
884        self.skip_token(TokenKind::LeftParen)?;
885
886        let _guard = self.tokens.set_ignoring_newline();
887
888        if self.tokens.is_next_eof() {
889            return Err(vec![ParserError::UnexpectedEoi {
890                span: self.tokens.last_token().span.clone(),
891            }]);
892        }
893
894        let parameters = match self.tokens.consume_one_of(token_slice![RightParen]) {
895            Some(_) => vec![],
896            None => {
897                let parameters = self.parse_function_parameters()?;
898
899                if self
900                    .tokens
901                    .consume_one_of(token_slice![RightParen])
902                    .is_none()
903                {
904                    return Err(vec![ParserError::MissingParentheses {
905                        span: self.tokens.next().unwrap().span.clone(),
906                    }]);
907                }
908
909                parameters
910            }
911        };
912
913        Ok(parameters)
914    }
915
916    fn parse_function_parameters(&mut self) -> Result<Vec<FunctionParam>> {
917        let mut parameters: Vec<FunctionParam> = vec![];
918
919        loop {
920            let (param_name, param_span) = self.consume_identifier()?;
921
922            if parameters.iter().any(|p| p.name == param_name) {
923                return Err(vec![ParserError::DuplicateParameter {
924                    name: param_name.clone(),
925                    span: param_span,
926                }]);
927            }
928
929            parameters.push(FunctionParam::new(param_name, self.gen_uid(), param_span));
930
931            if self.tokens.consume_one_of(token_slice![Comma]).is_none() {
932                break;
933            }
934        }
935
936        Ok(parameters.into_iter().collect())
937    }
938
939    fn parse_list(&mut self) -> Result<ast::Expr> {
940        let span_start = self.tokens.next().unwrap().span.start();
941        let mut elements = vec![];
942
943        if !self.tokens.is_next_token(TokenKind::RightBracket) {
944            loop {
945                elements.push(self.parse_expression()?);
946
947                if self.tokens.consume_one_of(token_slice![Comma]).is_none() {
948                    break;
949                }
950            }
951        }
952
953        if self.tokens.is_next_eof() {
954            return Err(vec![ParserError::UnexpectedEoi {
955                span: self.tokens.last_token().span.clone(),
956            }]);
957        }
958
959        let closing_bracket = match self.tokens.consume_one_of(token_slice![RightBracket]) {
960            Some(token) => token,
961            _ => {
962                return Err(vec![ParserError::MissingBrackets {
963                    span: self.tokens.next().unwrap().span.clone(),
964                }]);
965            }
966        };
967
968        let span_end = closing_bracket.span.end();
969        let span = SourceSpan::new(span_start, span_end, self.source_id);
970
971        let elements = elements.into_iter().collect();
972        let list_expr = ast::List::new(elements, span);
973        let list_expr = ast::Expr::List(list_expr);
974
975        Ok(list_expr)
976    }
977
978    fn parse_associative_array(&mut self) -> Result<ast::Expr> {
979        let span_start = self.tokens.next().unwrap().span.start();
980        let mut elements = vec![];
981
982        if !self.tokens.is_next_token(TokenKind::RightBrace) {
983            loop {
984                let key = match self.tokens.consume_one_of(token_slice![Number, String]) {
985                    Some(token) => {
986                        ast::Literal::new(token.literal.clone().unwrap(), token.span.clone())
987                    }
988                    None => return Err(vec![unexpected_token!(self.tokens.next().unwrap())]),
989                };
990
991                if self.tokens.consume_one_of(token_slice![Colon]).is_none() {
992                    return Err(vec![ParserError::MissingColon {
993                        span: self.tokens.next().unwrap().span.clone(),
994                    }]);
995                }
996
997                let value = self.parse_expression()?;
998
999                elements.push((key, value));
1000
1001                if self.tokens.consume_one_of(token_slice![Comma]).is_none() {
1002                    break;
1003                }
1004            }
1005        }
1006
1007        if self.tokens.is_next_eof() {
1008            return Err(vec![ParserError::UnexpectedEoi {
1009                span: self.tokens.last_token().span.clone(),
1010            }]);
1011        }
1012
1013        let closing_brace = match self.tokens.consume_one_of(token_slice![RightBrace]) {
1014            Some(token) => token,
1015            _ => {
1016                return Err(vec![ParserError::MissingBraces {
1017                    span: self.tokens.next().unwrap().span.clone(),
1018                }]);
1019            }
1020        };
1021
1022        let span_end = closing_brace.span.end();
1023        let span = SourceSpan::new(span_start, span_end, self.source_id);
1024
1025        let elements = elements.into_iter().collect();
1026        let associative_array_expr = ast::AssociativeArray::new(elements, span);
1027        let associative_array_expr = ast::Expr::AssociativeArray(associative_array_expr);
1028
1029        Ok(associative_array_expr)
1030    }
1031
1032    fn parse_dot_access(&mut self, lhs: ast::Expr) -> Result<ast::Expr> {
1033        let (field, field_span) = self.consume_identifier()?;
1034        let literal = tenda_scanner::Literal::String(field);
1035
1036        let index_expr = ast::Literal::new(literal, field_span);
1037        let index_expr = ast::Expr::Literal(index_expr);
1038
1039        let span_start = lhs.get_span().start();
1040        let span_end = index_expr.get_span().end();
1041        let span = SourceSpan::new(span_start, span_end, self.source_id);
1042
1043        let access_expr = ast::Access::new(lhs, index_expr, span);
1044        let access_expr = ast::Expr::Access(access_expr);
1045
1046        Ok(access_expr)
1047    }
1048
1049    fn parse_ternary_branches(
1050        &mut self,
1051        condition: ast::Expr,
1052        span_start: usize,
1053    ) -> Result<ast::Expr> {
1054        let then_branch = self.parse_expression()?;
1055
1056        self.skip_token(TokenKind::Else)?;
1057
1058        let else_branch = self.parse_expression()?;
1059
1060        let span_end = else_branch.get_span().end();
1061        let span = SourceSpan::new(span_start, span_end, self.source_id);
1062        let stmt = ast::TernaryOp::new(condition, then_branch, else_branch, span);
1063
1064        Ok(ast::Expr::Ternary(stmt))
1065    }
1066}
1067
1068impl Parser<'_> {
1069    fn consume_identifier(&mut self) -> Result<(String, SourceSpan)> {
1070        match self.tokens.next() {
1071            Some(token) if token.kind == TokenKind::Identifier => {
1072                match token.literal.as_ref().unwrap() {
1073                    tenda_scanner::Literal::String(string) => {
1074                        Ok((string.to_string(), token.span.clone()))
1075                    }
1076                    _ => unreachable!(),
1077                }
1078            }
1079            Some(token) => Err(vec![unexpected_token!(token)]),
1080            None => Err(vec![ParserError::UnexpectedEoi {
1081                span: self.tokens.last_token().span.clone(),
1082            }]),
1083        }
1084    }
1085
1086    fn skip_token(&mut self, token_kind: TokenKind) -> Result<&Token> {
1087        match self.tokens.next() {
1088            Some(token) if token.kind == token_kind => Ok(token),
1089            Some(token) if token.kind == TokenKind::Eof => Err(vec![ParserError::UnexpectedEoi {
1090                span: token.span.clone(),
1091            }]),
1092            Some(token) => Err(vec![unexpected_token!(token)]),
1093            None => Err(vec![ParserError::UnexpectedEoi {
1094                span: self.tokens.last_token().span.clone(),
1095            }]),
1096        }
1097    }
1098
1099    fn gen_uid(&mut self) -> usize {
1100        self.uid_counter += 1;
1101        self.uid_counter
1102    }
1103}