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}