rush_parser/
parser.rs

1use std::mem;
2
3use either::Either;
4
5use crate::{ast::*, Error, Lex, Location, Result, Span, Token, TokenKind};
6
7pub struct Parser<'src, Lexer: Lex<'src>> {
8    lexer: Lexer,
9    prev_tok: Token<'src>,
10    curr_tok: Token<'src>,
11    errors: Vec<Error<'src>>,
12}
13
14impl<'src, Lexer: Lex<'src>> Parser<'src, Lexer> {
15    /// Creates a new Parser
16    pub fn new(lexer: Lexer) -> Self {
17        Self {
18            lexer,
19            // initialize with dummy Eof tokens
20            prev_tok: Token::dummy(),
21            curr_tok: Token::dummy(),
22            errors: vec![],
23        }
24    }
25
26    /// Consumes this parser and tries to parse a [`Program`].
27    ///
28    /// # Returns
29    /// This function returns a tuple of a `Result<Program>`
30    /// and a `Vec<Error>`. Parsing can be
31    /// - successful: `(Some(Program), [])`
32    /// - partially successful: `(Some(Program), [..errors])`
33    /// - unsuccessful: `(Err(fatal_error), [..errors])`
34    pub fn parse(mut self) -> (Result<'src, Program<'src>>, Vec<Error<'src>>) {
35        if let Err(err) = self.next() {
36            return (Err(err), self.errors);
37        }
38
39        let program = match self.program() {
40            Ok(program) => program,
41            Err(err) => return (Err(err), self.errors),
42        };
43
44        if self.curr_tok.kind != TokenKind::Eof {
45            self.errors.push(Error::new(
46                format!("expected EOF, found `{}`", self.curr_tok.kind),
47                self.curr_tok.span,
48                self.lexer.source(),
49            ))
50        }
51
52        (Ok(program), self.errors)
53    }
54
55    // moves cursor to next token
56    fn next(&mut self) -> Result<'src, ()> {
57        // swap prev_tok and curr_tok in memory so that what was curr_tok is now prev_tok
58        mem::swap(&mut self.prev_tok, &mut self.curr_tok);
59        // overwrite curr_tok (which is now what prev_tok was) with the next token from the lexer
60        self.curr_tok = self.lexer.next_token()?;
61
62        Ok(())
63    }
64
65    // expects the curr_tok to be of the specified kind
66    fn expect(&mut self, kind: TokenKind) -> Result<'src, ()> {
67        if self.curr_tok.kind != kind {
68            return Err(Error::new_boxed(
69                format!("expected `{kind}`, found `{}`", self.curr_tok.kind),
70                self.curr_tok.span,
71                self.lexer.source(),
72            ));
73        }
74        self.next()?;
75        Ok(())
76    }
77
78    // expects the curr_tok to be an identifier and returns its name if this is the case
79    fn expect_ident(&mut self) -> Result<'src, Spanned<'src, &'src str>> {
80        match self.curr_tok.kind {
81            TokenKind::Ident(ident) => {
82                let ident = Spanned {
83                    span: self.curr_tok.span,
84                    inner: ident,
85                };
86                self.next()?;
87                Ok(ident)
88            }
89            _ => Err(Error::new_boxed(
90                format!("expected identifier, found `{}`", self.curr_tok.kind),
91                self.curr_tok.span,
92                self.lexer.source(),
93            )),
94        }
95    }
96
97    // expects curr_tok to be the specified token kind and adds a soft error otherwise
98    fn expect_recoverable(
99        &mut self,
100        kind: TokenKind,
101        message: impl Into<String>,
102        span: Span<'src>,
103    ) -> Result<'src, Span<'src>> {
104        let start_loc = self.curr_tok.span.start;
105        let end_loc = if self.curr_tok.kind != kind {
106            self.errors
107                .push(Error::new(message.into(), span, self.lexer.source()));
108            self.curr_tok.span.start
109        } else {
110            self.next()?;
111            self.prev_tok.span.end
112        };
113        Ok(start_loc.until(end_loc))
114    }
115
116    //////////////////////////
117
118    fn program(&mut self) -> Result<'src, Program<'src>> {
119        let start_loc = self.curr_tok.span.start;
120        let mut functions = vec![];
121        let mut globals = vec![];
122
123        while self.curr_tok.kind != TokenKind::Eof {
124            match self.curr_tok.kind {
125                TokenKind::Fn => functions.push(self.function_definition()?),
126                TokenKind::Let => globals.push(self.let_stmt()?),
127                _ => {
128                    return Err(Error::new_boxed(
129                        format!(
130                            "expected either `fn` or `let`, found `{}`",
131                            self.curr_tok.kind
132                        ),
133                        self.curr_tok.span,
134                        self.lexer.source(),
135                    ))
136                }
137            }
138        }
139
140        Ok(Program {
141            span: start_loc.until(self.prev_tok.span.end),
142            functions,
143            globals,
144        })
145    }
146
147    fn type_(&mut self) -> Result<'src, Spanned<'src, Type>> {
148        let start_loc = self.curr_tok.span.start;
149
150        let mut ptr_count = 0;
151        while matches!(self.curr_tok.kind, TokenKind::Star | TokenKind::Pow) {
152            ptr_count += match self.curr_tok.kind == TokenKind::Star {
153                true => 1,
154                false => 2,
155            };
156            self.next()?;
157        }
158
159        let type_ = match self.curr_tok.kind {
160            TokenKind::Ident("int") => Type::Int(ptr_count),
161            TokenKind::Ident("float") => Type::Float(ptr_count),
162            TokenKind::Ident("bool") => Type::Bool(ptr_count),
163            TokenKind::Ident("char") => Type::Char(ptr_count),
164            TokenKind::Ident(ident) => {
165                self.errors.push(Error::new(
166                    format!("unknown type `{ident}`"),
167                    self.curr_tok.span,
168                    self.lexer.source(),
169                ));
170                Type::Unknown
171            }
172            TokenKind::LParen => {
173                self.next()?;
174                self.expect_recoverable(
175                    TokenKind::RParen,
176                    "missing closing parenthesis",
177                    self.curr_tok.span,
178                )?;
179
180                if ptr_count > 0 {
181                    self.errors.push(Error::new(
182                        format!("illegal type `{}()`", "*".repeat(ptr_count)),
183                        start_loc.until(self.prev_tok.span.end),
184                        self.lexer.source(),
185                    ))
186                }
187
188                return Ok(Spanned {
189                    span: start_loc.until(self.prev_tok.span.end),
190                    inner: Type::Unit,
191                });
192            }
193            invalid => {
194                return Err(Error::new_boxed(
195                    format!("expected a type, found `{invalid}`"),
196                    self.curr_tok.span,
197                    self.lexer.source(),
198                ));
199            }
200        };
201        self.next()?;
202        Ok(Spanned {
203            span: start_loc.until(self.prev_tok.span.end),
204            inner: type_,
205        })
206    }
207
208    fn function_definition(&mut self) -> Result<'src, FunctionDefinition<'src>> {
209        let start_loc = self.curr_tok.span.start;
210
211        self.expect(TokenKind::Fn)?;
212        let name = self.expect_ident()?;
213        let l_paren = self.curr_tok.span;
214        self.expect(TokenKind::LParen)?;
215
216        let mut params = vec![];
217        if !matches!(self.curr_tok.kind, TokenKind::RParen | TokenKind::Eof) {
218            params.push(self.parameter()?);
219            while self.curr_tok.kind == TokenKind::Comma {
220                self.next()?;
221                if matches!(self.curr_tok.kind, TokenKind::RParen | TokenKind::Eof) {
222                    break;
223                }
224                params.push(self.parameter()?);
225            }
226        }
227
228        let r_paren = self.expect_recoverable(
229            TokenKind::RParen,
230            "missing closing parenthesis",
231            self.curr_tok.span,
232        )?;
233
234        let params = Spanned {
235            span: l_paren.start.until(r_paren.end),
236            inner: params,
237        };
238
239        let return_type = match self.curr_tok.kind {
240            TokenKind::Arrow => {
241                self.next()?;
242                let type_ = self.type_()?;
243                Spanned {
244                    span: type_.span,
245                    inner: Some(type_.inner),
246                }
247            }
248            _ => Spanned {
249                span: r_paren.start.until(self.curr_tok.span.end),
250                inner: None,
251            },
252        };
253
254        let block = self.block()?;
255
256        Ok(FunctionDefinition {
257            span: start_loc.until(self.prev_tok.span.end),
258            name,
259            params,
260            return_type,
261            block,
262        })
263    }
264
265    fn parameter(&mut self) -> Result<'src, Parameter<'src>> {
266        let mutable = self.curr_tok.kind == TokenKind::Mut;
267        if mutable {
268            self.next()?;
269        }
270
271        let name = self.expect_ident()?;
272        let type_ = match self.curr_tok.kind {
273            TokenKind::Comma | TokenKind::RParen => {
274                self.errors.push(Error::new(
275                    format!("missing type for parameter `{}`", name.inner),
276                    name.span,
277                    self.lexer.source(),
278                ));
279                Spanned {
280                    span: Span::dummy(),
281                    inner: Type::Unknown,
282                }
283            }
284            _ => {
285                self.expect(TokenKind::Colon)?;
286                self.type_()?
287            }
288        };
289        Ok(Parameter {
290            mutable,
291            name,
292            type_,
293        })
294    }
295
296    fn block(&mut self) -> Result<'src, Block<'src>> {
297        let start_loc = self.curr_tok.span.start;
298
299        self.expect(TokenKind::LBrace)?;
300
301        let mut stmts = vec![];
302        let mut expr = None;
303        while !matches!(self.curr_tok.kind, TokenKind::RBrace | TokenKind::Eof) {
304            match self.statement()? {
305                Either::Left(stmt) => stmts.push(stmt),
306                Either::Right(expression) => {
307                    expr = Some(expression);
308                    break;
309                }
310            }
311        }
312
313        self.expect_recoverable(
314            TokenKind::RBrace,
315            "missing closing brace",
316            self.curr_tok.span,
317        )?;
318
319        Ok(Block {
320            span: start_loc.until(self.prev_tok.span.end),
321            stmts,
322            expr,
323        })
324    }
325
326    fn statement(&mut self) -> Result<'src, Either<Statement<'src>, Expression<'src>>> {
327        Ok(match self.curr_tok.kind {
328            TokenKind::Let => Either::Left(Statement::Let(self.let_stmt()?)),
329            TokenKind::Return => Either::Left(self.return_stmt()?),
330            TokenKind::Loop => Either::Left(self.loop_stmt()?),
331            TokenKind::While => Either::Left(self.while_stmt()?),
332            TokenKind::For => Either::Left(self.for_stmt()?),
333            TokenKind::Break => Either::Left(self.break_stmt()?),
334            TokenKind::Continue => Either::Left(self.continue_stmt()?),
335            _ => self.expr_stmt()?,
336        })
337    }
338
339    fn let_stmt(&mut self) -> Result<'src, LetStmt<'src>> {
340        let start_loc = self.curr_tok.span.start;
341
342        // skip let token: this function is only called when self.curr_tok.kind == TokenKind::Let
343        self.next()?;
344
345        let mutable = self.curr_tok.kind == TokenKind::Mut;
346        if mutable {
347            self.next()?;
348        }
349
350        let name = self.expect_ident()?;
351
352        let type_ = match self.curr_tok.kind {
353            TokenKind::Colon => {
354                self.next()?;
355                Some(self.type_()?)
356            }
357            _ => None,
358        };
359
360        self.expect(TokenKind::Assign)?;
361        let expr = self.expression(0)?;
362        self.expect_recoverable(
363            TokenKind::Semicolon,
364            "missing semicolon after statement",
365            start_loc.until(self.prev_tok.span.end),
366        )?;
367
368        Ok(LetStmt {
369            span: start_loc.until(self.prev_tok.span.end),
370            mutable,
371            type_,
372            name,
373            expr,
374        })
375    }
376
377    fn return_stmt(&mut self) -> Result<'src, Statement<'src>> {
378        let start_loc = self.curr_tok.span.start;
379
380        // skip return token: this function is only called when self.curr_tok.kind == TokenKind::Return
381        self.next()?;
382
383        let expr = match self.curr_tok.kind {
384            TokenKind::Semicolon | TokenKind::RBrace | TokenKind::Eof => None,
385            _ => Some(self.expression(0)?),
386        };
387
388        self.expect_recoverable(
389            TokenKind::Semicolon,
390            "missing semicolon after statement",
391            start_loc.until(self.prev_tok.span.end),
392        )?;
393
394        Ok(Statement::Return(ReturnStmt {
395            span: start_loc.until(self.prev_tok.span.end),
396            expr,
397        }))
398    }
399
400    fn loop_stmt(&mut self) -> Result<'src, Statement<'src>> {
401        let start_loc = self.curr_tok.span.start;
402
403        // skip loop token: this function is only called when self.curr_tok.kind == TokenKind::Loop
404        self.next()?;
405
406        let block = self.block()?;
407
408        // skip optional semicolon
409        if self.curr_tok.kind == TokenKind::Semicolon {
410            self.next()?;
411        }
412
413        Ok(Statement::Loop(LoopStmt {
414            span: start_loc.until(self.prev_tok.span.end),
415            block,
416        }))
417    }
418
419    fn while_stmt(&mut self) -> Result<'src, Statement<'src>> {
420        let start_loc = self.curr_tok.span.start;
421
422        // skip while token: this function is only called when self.curr_tok.kind == TokenKind::While
423        self.next()?;
424
425        let cond = self.expression(0)?;
426
427        let block = self.block()?;
428
429        // skip optional semicolon
430        if self.curr_tok.kind == TokenKind::Semicolon {
431            self.next()?;
432        }
433
434        Ok(Statement::While(WhileStmt {
435            span: start_loc.until(self.prev_tok.span.end),
436            cond,
437            block,
438        }))
439    }
440
441    fn for_stmt(&mut self) -> Result<'src, Statement<'src>> {
442        let start_loc = self.curr_tok.span.start;
443
444        // skip for token: this function is only called when self.curr_tok.kind == TokenKind::For
445        self.next()?;
446
447        // parse the initializer
448        let ident = self.expect_ident()?;
449        self.expect_recoverable(
450            TokenKind::Assign,
451            format!("expected `=`, found `{}`", self.curr_tok.kind),
452            self.curr_tok.span,
453        )?;
454        let initializer = self.expression(0)?;
455
456        // parse the condition expression
457        self.expect_recoverable(
458            TokenKind::Semicolon,
459            format!("expected semicolon, found `{}`", self.curr_tok.kind),
460            self.curr_tok.span,
461        )?;
462        let cond = self.expression(0)?;
463
464        // parse the update expression
465        self.expect_recoverable(
466            TokenKind::Semicolon,
467            format!("expected semicolon, found `{}`", self.curr_tok.kind),
468            self.curr_tok.span,
469        )?;
470        let update = self.expression(0)?;
471
472        // parse the block
473        let block = self.block()?;
474
475        // skip optional semicolon
476        if self.curr_tok.kind == TokenKind::Semicolon {
477            self.next()?;
478        }
479
480        Ok(Statement::For(ForStmt {
481            span: start_loc.until(self.prev_tok.span.end),
482            ident,
483            initializer,
484            cond,
485            update,
486            block,
487        }))
488    }
489
490    fn break_stmt(&mut self) -> Result<'src, Statement<'src>> {
491        let start_loc = self.curr_tok.span.start;
492
493        // skip break token: this function is only called when self.curr_tok.kind == TokenKind::Break
494        self.next()?;
495
496        self.expect_recoverable(
497            TokenKind::Semicolon,
498            "missing semicolon after statement",
499            self.prev_tok.span,
500        )?;
501
502        Ok(Statement::Break(BreakStmt {
503            span: start_loc.until(self.prev_tok.span.end),
504        }))
505    }
506
507    fn continue_stmt(&mut self) -> Result<'src, Statement<'src>> {
508        let start_loc = self.curr_tok.span.start;
509
510        // skip continue token: this function is only called when self.curr_tok.kind == TokenKind::Continue
511        self.next()?;
512
513        self.expect_recoverable(
514            TokenKind::Semicolon,
515            "missing semicolon after statement",
516            self.prev_tok.span,
517        )?;
518
519        Ok(Statement::Continue(ContinueStmt {
520            span: start_loc.until(self.prev_tok.span.end),
521        }))
522    }
523
524    fn expr_stmt(&mut self) -> Result<'src, Either<Statement<'src>, Expression<'src>>> {
525        let start_loc = self.curr_tok.span.start;
526
527        let (expr, with_block) = match self.curr_tok.kind {
528            TokenKind::If => (Expression::If(self.if_expr()?.into()), true),
529            TokenKind::LBrace => (Expression::Block(self.block()?.into()), true),
530            _ => (self.expression(0)?, false),
531        };
532
533        match (self.curr_tok.kind, with_block) {
534            (TokenKind::Semicolon, true) => self.next()?,
535            (TokenKind::Semicolon, false) => self.next()?,
536            (TokenKind::RBrace, _) => return Ok(Either::Right(expr)),
537            (_, true) => {}
538            (_, false) => self.errors.push(Error::new(
539                "missing semicolon after statement".to_string(),
540                expr.span(),
541                self.lexer.source(),
542            )),
543        }
544
545        Ok(Either::Left(Statement::Expr(ExprStmt {
546            span: start_loc.until(self.prev_tok.span.end),
547            expr,
548        })))
549    }
550
551    fn expression(&mut self, prec: u8) -> Result<'src, Expression<'src>> {
552        let start_loc = self.curr_tok.span.start;
553
554        let mut lhs = match self.curr_tok.kind {
555            TokenKind::LBrace => Expression::Block(self.block()?.into()),
556            TokenKind::If => Expression::If(self.if_expr()?.into()),
557            TokenKind::Int(num) => Expression::Int(self.atom(num)?),
558            TokenKind::Float(num) => Expression::Float(self.atom(num)?),
559            TokenKind::True => Expression::Bool(self.atom(true)?),
560            TokenKind::False => Expression::Bool(self.atom(false)?),
561            TokenKind::Char(char) => Expression::Char(self.atom(char)?),
562            TokenKind::Ident(ident) => Expression::Ident(self.atom(ident)?),
563            TokenKind::Not => Expression::Prefix(self.prefix_expr(PrefixOp::Not, false)?.into()),
564            TokenKind::Minus => Expression::Prefix(self.prefix_expr(PrefixOp::Neg, false)?.into()),
565            TokenKind::Star => Expression::Prefix(self.prefix_expr(PrefixOp::Deref, false)?.into()),
566            TokenKind::Pow => Expression::Prefix(self.prefix_expr(PrefixOp::Deref, true)?.into()),
567            TokenKind::BitAnd => Expression::Prefix(self.prefix_expr(PrefixOp::Ref, false)?.into()),
568            TokenKind::LParen => Expression::Grouped(self.grouped_expr()?),
569            invalid => {
570                return Err(Error::new_boxed(
571                    format!("expected an expression, found `{invalid}`"),
572                    self.curr_tok.span,
573                    self.lexer.source(),
574                ));
575            }
576        };
577
578        while self.curr_tok.kind.prec().0 > prec {
579            lhs = match self.curr_tok.kind {
580                TokenKind::Plus => self.infix_expr(start_loc, lhs, InfixOp::Plus)?,
581                TokenKind::Minus => self.infix_expr(start_loc, lhs, InfixOp::Minus)?,
582                TokenKind::Star => self.infix_expr(start_loc, lhs, InfixOp::Mul)?,
583                TokenKind::Slash => self.infix_expr(start_loc, lhs, InfixOp::Div)?,
584                TokenKind::Percent => self.infix_expr(start_loc, lhs, InfixOp::Rem)?,
585                TokenKind::Pow => self.infix_expr(start_loc, lhs, InfixOp::Pow)?,
586                TokenKind::Eq => self.infix_expr(start_loc, lhs, InfixOp::Eq)?,
587                TokenKind::Neq => self.infix_expr(start_loc, lhs, InfixOp::Neq)?,
588                TokenKind::Lt => self.infix_expr(start_loc, lhs, InfixOp::Lt)?,
589                TokenKind::Gt => self.infix_expr(start_loc, lhs, InfixOp::Gt)?,
590                TokenKind::Lte => self.infix_expr(start_loc, lhs, InfixOp::Lte)?,
591                TokenKind::Gte => self.infix_expr(start_loc, lhs, InfixOp::Gte)?,
592                TokenKind::Shl => self.infix_expr(start_loc, lhs, InfixOp::Shl)?,
593                TokenKind::Shr => self.infix_expr(start_loc, lhs, InfixOp::Shr)?,
594                TokenKind::BitOr => self.infix_expr(start_loc, lhs, InfixOp::BitOr)?,
595                TokenKind::BitAnd => self.infix_expr(start_loc, lhs, InfixOp::BitAnd)?,
596                TokenKind::BitXor => self.infix_expr(start_loc, lhs, InfixOp::BitXor)?,
597                TokenKind::And => self.infix_expr(start_loc, lhs, InfixOp::And)?,
598                TokenKind::Or => self.infix_expr(start_loc, lhs, InfixOp::Or)?,
599                TokenKind::Assign => self.assign_expr(start_loc, lhs, AssignOp::Basic)?,
600                TokenKind::PlusAssign => self.assign_expr(start_loc, lhs, AssignOp::Plus)?,
601                TokenKind::MinusAssign => self.assign_expr(start_loc, lhs, AssignOp::Minus)?,
602                TokenKind::MulAssign => self.assign_expr(start_loc, lhs, AssignOp::Mul)?,
603                TokenKind::DivAssign => self.assign_expr(start_loc, lhs, AssignOp::Div)?,
604                TokenKind::RemAssign => self.assign_expr(start_loc, lhs, AssignOp::Rem)?,
605                TokenKind::PowAssign => self.assign_expr(start_loc, lhs, AssignOp::Pow)?,
606                TokenKind::ShlAssign => self.assign_expr(start_loc, lhs, AssignOp::Shl)?,
607                TokenKind::ShrAssign => self.assign_expr(start_loc, lhs, AssignOp::Shr)?,
608                TokenKind::BitOrAssign => self.assign_expr(start_loc, lhs, AssignOp::BitOr)?,
609                TokenKind::BitAndAssign => self.assign_expr(start_loc, lhs, AssignOp::BitAnd)?,
610                TokenKind::BitXorAssign => self.assign_expr(start_loc, lhs, AssignOp::BitXor)?,
611                TokenKind::LParen => self.call_expr(start_loc, lhs)?,
612                TokenKind::As => self.cast_expr(start_loc, lhs)?,
613                _ => return Ok(lhs),
614            };
615        }
616
617        Ok(lhs)
618    }
619
620    fn if_expr(&mut self) -> Result<'src, IfExpr<'src>> {
621        let start_loc = self.curr_tok.span.start;
622
623        // skip if token: this function is only called when self.curr_tok.kind == TokenKind::If
624        self.next()?;
625
626        let cond = self.expression(0)?;
627        let then_block = self.block()?;
628        let else_block = match self.curr_tok.kind {
629            TokenKind::Else => {
630                self.next()?;
631                Some(match self.curr_tok.kind {
632                    TokenKind::If => {
633                        let if_expr = self.if_expr()?;
634                        Block {
635                            span: if_expr.span,
636                            stmts: vec![],
637                            expr: Some(Expression::If(if_expr.into())),
638                        }
639                    }
640                    TokenKind::LBrace => self.block()?,
641                    invalid => {
642                        return Err(Error::new_boxed(
643                            format!(
644                                "expected either `if` or block after `else`, found `{invalid}`"
645                            ),
646                            self.curr_tok.span,
647                            self.lexer.source(),
648                        ));
649                    }
650                })
651            }
652            _ => None,
653        };
654
655        Ok(IfExpr {
656            span: start_loc.until(self.prev_tok.span.end),
657            cond,
658            then_block,
659            else_block,
660        })
661    }
662
663    fn atom<T>(&mut self, inner: T) -> Result<'src, Spanned<'src, T>> {
664        let start_loc = self.curr_tok.span.start;
665        self.next()?;
666        Ok(Spanned {
667            span: start_loc.until(self.prev_tok.span.end),
668            inner,
669        })
670    }
671
672    fn prefix_expr(
673        &mut self,
674        op: PrefixOp,
675        deref_counts_double: bool,
676    ) -> Result<'src, PrefixExpr<'src>> {
677        let start_loc = self.curr_tok.span.start;
678
679        // skip the operator token
680        self.next()?;
681
682        // PrefixExpr precedence is 27, higher than all InfixExpr precedences except CallExpr
683        let expr = self.expression(27)?;
684
685        match (op, &expr) {
686            (PrefixOp::Ref | PrefixOp::Deref, Expression::Ident(_)) => Ok(PrefixExpr {
687                span: start_loc.until(self.prev_tok.span.end),
688                op,
689                expr: match deref_counts_double {
690                    true => Expression::Prefix(Box::new(PrefixExpr {
691                        span: start_loc.until(self.prev_tok.span.end),
692                        op,
693                        expr,
694                    })),
695                    false => expr,
696                },
697            }),
698            (PrefixOp::Deref, Expression::Prefix(_)) => Ok(PrefixExpr {
699                span: start_loc.until(self.prev_tok.span.end),
700                op,
701                expr: match deref_counts_double {
702                    true => Expression::Prefix(Box::new(PrefixExpr {
703                        span: start_loc.until(self.prev_tok.span.end),
704                        op,
705                        expr,
706                    })),
707                    false => expr,
708                },
709            }),
710            (PrefixOp::Ref | PrefixOp::Deref, _) => {
711                self.errors.push(Error::new(
712                    format!("prefix operator `{op}` requires an identifier on its right hand side"),
713                    expr.span(),
714                    self.lexer.source(),
715                ));
716                Ok(PrefixExpr {
717                    span: start_loc.until(self.prev_tok.span.end),
718                    op,
719                    expr: Expression::Ident(Spanned {
720                        span: Span::dummy(),
721                        inner: "",
722                    }),
723                })
724            }
725            _ => Ok(PrefixExpr {
726                span: start_loc.until(self.prev_tok.span.end),
727                op,
728                expr,
729            }),
730        }
731    }
732
733    fn grouped_expr(&mut self) -> Result<'src, Spanned<'src, Box<Expression<'src>>>> {
734        let start_loc = self.curr_tok.span.start;
735        // skip the opening parenthesis
736        self.next()?;
737
738        let expr = self.expression(0)?;
739        self.expect_recoverable(
740            TokenKind::RParen,
741            "missing closing parenthesis",
742            self.curr_tok.span,
743        )?;
744
745        Ok(Spanned {
746            span: start_loc.until(self.prev_tok.span.end),
747            inner: expr.into(),
748        })
749    }
750
751    fn infix_expr(
752        &mut self,
753        start_loc: Location<'src>,
754        lhs: Expression<'src>,
755        op: InfixOp,
756    ) -> Result<'src, Expression<'src>> {
757        let right_prec = self.curr_tok.kind.prec().1;
758        self.next()?;
759        let rhs = self.expression(right_prec)?;
760
761        Ok(Expression::Infix(
762            InfixExpr {
763                span: start_loc.until(self.prev_tok.span.end),
764                lhs,
765                op,
766                rhs,
767            }
768            .into(),
769        ))
770    }
771
772    fn assign_expr(
773        &mut self,
774        start_loc: Location<'src>,
775        lhs: Expression<'src>,
776        op: AssignOp,
777    ) -> Result<'src, Expression<'src>> {
778        let lhs_start_loc = lhs.span().start;
779        let (assignee, assignee_ptr_count) =
780            match self.reduce_prefix_expr_to_ident(lhs, lhs_start_loc, 0) {
781                Ok(res) => res,
782                Err(err) => {
783                    self.errors.push(*err);
784                    (
785                        Spanned {
786                            span: Span::dummy(),
787                            inner: "",
788                        },
789                        0,
790                    )
791                }
792            };
793
794        let right_prec = self.curr_tok.kind.prec().1;
795        self.next()?;
796        let expr = self.expression(right_prec)?;
797
798        Ok(Expression::Assign(
799            AssignExpr {
800                span: start_loc.until(self.prev_tok.span.end),
801                assignee,
802                assignee_ptr_count,
803                op,
804                expr,
805            }
806            .into(),
807        ))
808    }
809
810    /// Reduces nested [`PrefixExpr`]s which have the [`PrefixOp::Deref`] operator to an
811    /// identifier. The returned span also includes the deref symbols `*`.
812    fn reduce_prefix_expr_to_ident(
813        &self,
814        expr: Expression<'src>,
815        start_loc: Location<'src>,
816        count: usize,
817    ) -> Result<'src, (Spanned<'src, &'src str>, usize)> {
818        match expr {
819            Expression::Ident(ident) => {
820                let mut ident = ident;
821                ident.span = start_loc.until(ident.span.end);
822                Ok((ident, count))
823            }
824            Expression::Prefix(prefix) => {
825                self.reduce_prefix_expr_to_ident(prefix.expr, start_loc, count + 1)
826            }
827            _ => Err(Error::new_boxed(
828                "left hand side of assignment must be an identifier".to_string(),
829                expr.span(),
830                self.lexer.source(),
831            )),
832        }
833    }
834
835    fn call_expr(
836        &mut self,
837        start_loc: Location<'src>,
838        expr: Expression<'src>,
839    ) -> Result<'src, Expression<'src>> {
840        let func = match expr {
841            Expression::Ident(func) => func,
842            _ => {
843                self.errors.push(Error::new(
844                    "only identifiers can be called".to_string(),
845                    self.curr_tok.span,
846                    self.lexer.source(),
847                ));
848                Spanned {
849                    span: Span::dummy(),
850                    inner: "",
851                }
852            }
853        };
854
855        // skip opening parenthesis
856        self.next()?;
857
858        let mut args = vec![];
859        if !matches!(self.curr_tok.kind, TokenKind::RParen | TokenKind::Eof) {
860            args.push(self.expression(0)?);
861
862            while self.curr_tok.kind == TokenKind::Comma {
863                self.next()?;
864                if let TokenKind::RParen | TokenKind::Eof = self.curr_tok.kind {
865                    break;
866                }
867                args.push(self.expression(0)?);
868            }
869        }
870
871        self.expect_recoverable(
872            TokenKind::RParen,
873            "missing closing parenthesis",
874            self.curr_tok.span,
875        )?;
876
877        Ok(Expression::Call(
878            CallExpr {
879                span: start_loc.until(self.prev_tok.span.end),
880                func,
881                args,
882            }
883            .into(),
884        ))
885    }
886
887    fn cast_expr(
888        &mut self,
889        start_loc: Location<'src>,
890        expr: Expression<'src>,
891    ) -> Result<'src, Expression<'src>> {
892        // skip `as` token
893        self.next()?;
894
895        let type_ = self.type_()?;
896
897        Ok(Expression::Cast(
898            CastExpr {
899                span: start_loc.until(self.prev_tok.span.end),
900                expr,
901                type_,
902            }
903            .into(),
904        ))
905    }
906}
907
908#[cfg(test)]
909mod tests {
910    use super::*;
911
912    // Impl Lex trait for any iterator over tokens
913    impl<'src, T> Lex<'src> for T
914    where
915        T: Iterator<Item = Token<'src>>,
916    {
917        fn next_token(&mut self) -> Result<'src, Token<'src>> {
918            Ok(self.next().unwrap_or_else(Token::dummy))
919        }
920
921        fn source(&self) -> &'src str {
922            ""
923        }
924    }
925
926    /// Parses the `tokens` into an [`Expression`] and asserts equality with `tree`
927    /// without any errors
928    fn expr_test(
929        tokens: impl IntoIterator<Item = Token<'static>>,
930        tree: Expression<'static>,
931    ) -> Result<'static, ()> {
932        let mut parser = Parser::new(tokens.into_iter());
933        parser.next()?;
934        let expr = parser.expression(0)?;
935        assert!(dbg!(parser.errors).is_empty());
936        assert_eq!(dbg!(expr), dbg!(tree));
937        Ok(())
938    }
939
940    /// Parses the `tokens` into a [`Statement`] and asserts equality with `tree`
941    /// without any errors
942    fn stmt_test(
943        tokens: impl IntoIterator<Item = Token<'static>>,
944        tree: Statement<'static>,
945    ) -> Result<'static, ()> {
946        let mut parser = Parser::new(tokens.into_iter());
947        parser.next()?;
948        let stmt = parser.statement()?;
949        assert!(dbg!(parser.errors).is_empty());
950        assert_eq!(dbg!(stmt), Either::Left(dbg!(tree)));
951        Ok(())
952    }
953
954    /// Parses the `tokens` into a [`Program`] and asserts equality with `tree`
955    /// without any errors
956    fn program_test(
957        tokens: impl IntoIterator<Item = Token<'static>>,
958        tree: Program<'static>,
959    ) -> Result<'static, ()> {
960        let parser = Parser::new(tokens.into_iter());
961        let (res, errors) = parser.parse();
962        assert!(dbg!(errors).is_empty());
963        assert_eq!(dbg!(res?), dbg!(tree));
964        Ok(())
965    }
966
967    #[test]
968    fn arithmetic_expressions() -> Result<'static, ()> {
969        // 3-2-1
970        expr_test(
971            tokens![
972                Int(3) @ 0..1,
973                Minus @ 1..2,
974                Int(2) @ 2..3,
975                Minus @ 3..4,
976                Int(1) @ 4..5,
977            ],
978            tree! {
979                (InfixExpr @ 0..5,
980                    lhs: (InfixExpr @ 0..3,
981                        lhs: (Int 3, @ 0..1),
982                        op: InfixOp::Minus,
983                        rhs: (Int 2, @ 2..3)),
984                    op: InfixOp::Minus,
985                    rhs: (Int 1, @ 4..5))
986            },
987        )?;
988
989        // 1+2*3
990        expr_test(
991            tokens![
992                Int(1) @ 0..1,
993                Plus @ 1..2,
994                Int(2) @ 2..3,
995                Star @ 3..4,
996                Int(3) @ 4..5,
997            ],
998            tree! {
999                (InfixExpr @ 0..5,
1000                    lhs: (Int 1, @ 0..1),
1001                    op: InfixOp::Plus,
1002                    rhs: (InfixExpr @ 2..5,
1003                        lhs: (Int 2, @ 2..3),
1004                        op: InfixOp::Mul,
1005                        rhs: (Int 3, @ 4..5)))
1006            },
1007        )?;
1008
1009        // 2**3**4
1010        expr_test(
1011            tokens![
1012                Int(2) @ 0..1,
1013                Pow @ 1..3,
1014                Int(3) @ 3..4,
1015                Pow @ 4..6,
1016                Int(4) @ 6..7,
1017            ],
1018            tree! {
1019                (InfixExpr @ 0..7,
1020                    lhs: (Int 2, @ 0..1),
1021                    op: InfixOp::Pow,
1022                    rhs: (InfixExpr @ 3..7,
1023                        lhs: (Int 3, @ 3..4),
1024                        op: InfixOp::Pow,
1025                        rhs: (Int 4, @ 6..7)))
1026            },
1027        )?;
1028
1029        Ok(())
1030    }
1031
1032    #[test]
1033    fn assignment_expressions() -> Result<'static, ()> {
1034        // a=1
1035        expr_test(
1036            tokens![
1037                Ident("a") @ 0..1,
1038                Assign @ 1..2,
1039                Int(1) @ 2..3,
1040            ],
1041            tree! {
1042                (AssignExpr @ 0..3,
1043                    assignee: ("a", @ 0..1),
1044                    assignee_ptr_count: 0,
1045                    op: AssignOp::Basic,
1046                    expr: (Int 1, @ 2..3))
1047            },
1048        )?;
1049
1050        // answer += 42.0 - 0f
1051        expr_test(
1052            tokens![
1053                Ident("answer") @ 0..6,
1054                PlusAssign @ 7..9,
1055                Float(42.0) @ 10..14,
1056                Minus @ 15..16,
1057                Float(0.0) @ 17..19,
1058            ],
1059            tree! {
1060                (AssignExpr @ 0..19,
1061                    assignee: ("answer", @ 0..6),
1062                    assignee_ptr_count: 0,
1063                    op: AssignOp::Plus,
1064                    expr: (InfixExpr @ 10..19,
1065                        lhs: (Float 42.0, @ 10..14),
1066                        op: InfixOp::Minus,
1067                        rhs: (Float 0.0, @ 17..19)))
1068            },
1069        )?;
1070
1071        Ok(())
1072    }
1073
1074    #[test]
1075    fn if_expr() -> Result<'static, ()> {
1076        // if true{}
1077        expr_test(
1078            tokens![
1079                If @ 0..2,
1080                True @ 3..7,
1081                LBrace @ 7..8,
1082                RBrace @ 8..9,
1083            ],
1084            tree! {
1085                (IfExpr @ 0..9,
1086                    cond: (Bool true, @ 3..7),
1087                    then_block: (Block @ 7..9,
1088                        stmts: [],
1089                        expr: (None)),
1090                    else_block: (None))
1091            },
1092        )?;
1093
1094        // if 2 > 1 { 1 } else { { 2 } }
1095        expr_test(
1096            tokens![
1097                If @ 0..2,
1098                Int(2) @ 3..4,
1099                Gt @ 5..6,
1100                Int(1) @ 7..8,
1101                LBrace @ 9..10,
1102                Int(1) @ 11..12,
1103                RBrace @ 13..14,
1104                Else @ 15..19,
1105                LBrace @ 20..21,
1106                LBrace @ 22..23,
1107                Int(2) @ 24..25,
1108                RBrace @ 26..27,
1109                RBrace @ 28..29,
1110            ],
1111            tree! {
1112                (IfExpr @ 0..29,
1113                    cond: (InfixExpr @ 3..8,
1114                        lhs: (Int 2, @ 3..4),
1115                        op: InfixOp::Gt,
1116                        rhs: (Int 1, @ 7..8)),
1117                    then_block: (Block @ 9..14,
1118                        stmts: [],
1119                        expr: (Some(Int 1, @ 11..12))),
1120                    else_block: (Some(Block @ 20..29,
1121                        stmts: [],
1122                        expr: (Some(BlockExpr @ 22..27,
1123                            stmts: [],
1124                            expr: (Some(Int 2, @ 24..25)))))))
1125            },
1126        )?;
1127
1128        // if false {} else if cond {1;}
1129        expr_test(
1130            tokens![
1131                If @ 0..2,
1132                False @ 3..8,
1133                LBrace @ 9..10,
1134                RBrace @ 10..11,
1135                Else @ 12..16,
1136                If @ 17..19,
1137                Ident("cond") @ 20..24,
1138                LBrace @ 25..26,
1139                Int(1) @ 26..27,
1140                Semicolon @ 27..28,
1141                RBrace @ 28..29,
1142            ],
1143            tree! {
1144                (IfExpr @ 0..29,
1145                    cond: (Bool false, @ 3..8),
1146                    then_block: (Block @ 9..11,
1147                        stmts: [],
1148                        expr: (None)),
1149                    else_block: (Some(Block @ 17..29,
1150                        stmts: [],
1151                        expr: (Some(IfExpr @ 17..29,
1152                            cond: (Ident "cond", @ 20..24),
1153                            then_block: (Block @ 25..29,
1154                                stmts: [
1155                                    (ExprStmt @ 26..28, (Int 1, @ 26..27))],
1156                                expr: (None)),
1157                            else_block: (None))))))
1158            },
1159        )?;
1160
1161        Ok(())
1162    }
1163
1164    #[test]
1165    fn prefix_expressions() -> Result<'static, ()> {
1166        // !func()
1167        expr_test(
1168            tokens![
1169                Not @ 0..1,
1170                Ident("func") @ 1..5,
1171                LParen @ 5..6,
1172                RParen @ 6..7,
1173            ],
1174            tree! {
1175                (PrefixExpr @ 0..7,
1176                    op: PrefixOp::Not,
1177                    expr: (CallExpr @ 1..7,
1178                        func: ("func", @ 1..5),
1179                        args: []))
1180            },
1181        )?;
1182
1183        Ok(())
1184    }
1185
1186    fn infix_expr_test(token: TokenKind<'static>, op: InfixOp) -> Result<()> {
1187        expr_test(
1188            [
1189                TokenKind::Int(1).spanned(span!(0..1)),
1190                token.spanned(span!(1..2)),
1191                TokenKind::Int(2).spanned(span!(2..3)),
1192            ],
1193            tree! {
1194                (InfixExpr @ 0..3,
1195                    lhs: (Int 1, @ 0..1),
1196                    op: op,
1197                    rhs: (Int 2, @ 2..3))
1198            },
1199        )
1200    }
1201
1202    #[test]
1203    fn infix_expr() -> Result<'static, ()> {
1204        infix_expr_test(TokenKind::Plus, InfixOp::Plus)?;
1205        infix_expr_test(TokenKind::Minus, InfixOp::Minus)?;
1206        infix_expr_test(TokenKind::Star, InfixOp::Mul)?;
1207        infix_expr_test(TokenKind::Slash, InfixOp::Div)?;
1208        infix_expr_test(TokenKind::Percent, InfixOp::Rem)?;
1209        infix_expr_test(TokenKind::Pow, InfixOp::Pow)?;
1210        infix_expr_test(TokenKind::Eq, InfixOp::Eq)?;
1211        infix_expr_test(TokenKind::Neq, InfixOp::Neq)?;
1212        infix_expr_test(TokenKind::Lt, InfixOp::Lt)?;
1213        infix_expr_test(TokenKind::Gt, InfixOp::Gt)?;
1214        infix_expr_test(TokenKind::Lte, InfixOp::Lte)?;
1215        infix_expr_test(TokenKind::Gte, InfixOp::Gte)?;
1216        infix_expr_test(TokenKind::Shl, InfixOp::Shl)?;
1217        infix_expr_test(TokenKind::Shr, InfixOp::Shr)?;
1218        infix_expr_test(TokenKind::BitOr, InfixOp::BitOr)?;
1219        infix_expr_test(TokenKind::BitAnd, InfixOp::BitAnd)?;
1220        infix_expr_test(TokenKind::BitXor, InfixOp::BitXor)?;
1221        infix_expr_test(TokenKind::And, InfixOp::And)?;
1222        infix_expr_test(TokenKind::Or, InfixOp::Or)?;
1223
1224        Ok(())
1225    }
1226
1227    fn assign_expr_test(token: TokenKind<'static>, op: AssignOp) -> Result<()> {
1228        expr_test(
1229            [
1230                TokenKind::Ident("a").spanned(span!(0..1)),
1231                token.spanned(span!(1..2)),
1232                TokenKind::Int(2).spanned(span!(2..3)),
1233            ],
1234            tree! {
1235                (AssignExpr @ 0..3,
1236                    assignee: ("a", @ 0..1),
1237                    assignee_ptr_count: 0,
1238                    op: op,
1239                    expr: (Int 2, @ 2..3))
1240            },
1241        )
1242    }
1243
1244    #[test]
1245    fn assign_expr() -> Result<'static, ()> {
1246        assign_expr_test(TokenKind::Assign, AssignOp::Basic)?;
1247        assign_expr_test(TokenKind::PlusAssign, AssignOp::Plus)?;
1248        assign_expr_test(TokenKind::MinusAssign, AssignOp::Minus)?;
1249        assign_expr_test(TokenKind::MulAssign, AssignOp::Mul)?;
1250        assign_expr_test(TokenKind::DivAssign, AssignOp::Div)?;
1251        assign_expr_test(TokenKind::RemAssign, AssignOp::Rem)?;
1252        assign_expr_test(TokenKind::PowAssign, AssignOp::Pow)?;
1253        assign_expr_test(TokenKind::ShlAssign, AssignOp::Shl)?;
1254        assign_expr_test(TokenKind::ShrAssign, AssignOp::Shr)?;
1255        assign_expr_test(TokenKind::BitOrAssign, AssignOp::BitOr)?;
1256        assign_expr_test(TokenKind::BitAndAssign, AssignOp::BitAnd)?;
1257        assign_expr_test(TokenKind::BitXorAssign, AssignOp::BitXor)?;
1258
1259        Ok(())
1260    }
1261
1262    #[test]
1263    fn let_stmt() -> Result<'static, ()> {
1264        // let a=1;
1265        stmt_test(
1266            tokens![
1267                Let @ 0..3,
1268                Ident("a") @ 4..5,
1269                Assign @ 5..6,
1270                Int(1) @ 6..7,
1271                Semicolon @ 7..8,
1272            ],
1273            tree! {
1274                (LetStmt @ 0..8,
1275                    mutable: false,
1276                    name: ("a", @ 4..5),
1277                    type: (None),
1278                    expr: (Int 1, @ 6..7))
1279            },
1280        )?;
1281
1282        // let mut b = 2;
1283        stmt_test(
1284            tokens![
1285                Let @ 0..3,
1286                Mut @ 4..7,
1287                Ident("b") @ 8..9,
1288                Assign @ 10..11,
1289                Int(2) @ 12..13,
1290                Semicolon @ 13..14,
1291            ],
1292            tree! {
1293                (LetStmt @ 0..14,
1294                    mutable: true,
1295                    name: ("b", @ 8..9),
1296                    type: (None),
1297                    expr: (Int 2, @ 12..13))
1298            },
1299        )?;
1300
1301        // let c: float = 3f;
1302        stmt_test(
1303            tokens![
1304                Let @ 0..3,
1305                Ident("c") @ 4..5,
1306                Colon @ 5..6,
1307                Ident("float") @ 7..12,
1308                Assign @ 13..14,
1309                Float(3.0) @ 15..17,
1310                Semicolon @ 17..18,
1311            ],
1312            tree! {
1313                (LetStmt @ 0..18,
1314                    mutable: false,
1315                    name: ("c", @ 4..5),
1316                    type: (Some(Type::Float(0), @ 7..12)),
1317                    expr: (Float 3.0, @ 15..17))
1318            },
1319        )?;
1320
1321        Ok(())
1322    }
1323
1324    #[test]
1325    fn return_stmt() -> Result<'static, ()> {
1326        // return;
1327        stmt_test(
1328            tokens![
1329                Return @ 0..6,
1330                Semicolon @ 6..7,
1331            ],
1332            tree! { (ReturnStmt @ 0..7, (None)) },
1333        )?;
1334
1335        // return 1;
1336        stmt_test(
1337            tokens![
1338                Return @ 0..6,
1339                Int(1) @ 6..7,
1340                Semicolon @ 7..8,
1341            ],
1342            tree! { (ReturnStmt @ 0..8, (Some(Int 1, @ 6..7))) },
1343        )?;
1344
1345        Ok(())
1346    }
1347
1348    #[test]
1349    fn expr_stmt() -> Result<'static, ()> {
1350        // 1;
1351        stmt_test(
1352            tokens![
1353                Int(1) @ 0..1,
1354                Semicolon @ 1..2,
1355            ],
1356            tree! { (ExprStmt @ 0..2, (Int 1, @ 0..1)) },
1357        )?;
1358
1359        // {}
1360        stmt_test(
1361            tokens![
1362                LBrace @ 0..1,
1363                RBrace @ 1..2,
1364            ],
1365            tree! {
1366                (ExprStmt @ 0..2, (BlockExpr @ 0..2,
1367                    stmts: [],
1368                    expr: (None)))
1369            },
1370        )?;
1371
1372        Ok(())
1373    }
1374
1375    #[test]
1376    fn programs() -> Result<'static, ()> {
1377        // fn main() { let a = true; a; }
1378        program_test(
1379            tokens![
1380                Fn @ 0..2,
1381                Ident("main") @ 3..7,
1382                LParen @ 7..8,
1383                RParen @ 8..9,
1384                LBrace @ 10..11,
1385                Let @ 12..15,
1386                Ident("a") @ 16..17,
1387                Assign @ 18..19,
1388                True @ 20..24,
1389                Semicolon @ 24..25,
1390                Ident("a") @ 26..27,
1391                Semicolon @ 27..28,
1392                RBrace @ 29..30,
1393            ],
1394            tree! {
1395                (Program @ 0..30,
1396                    functions: [
1397                        (FunctionDefinition @ 0..30,
1398                            name: ("main", @ 3..7),
1399                            params @ 7..9: [],
1400                            return_type: (None, @ 8..11),
1401                            block: (Block @ 10..30,
1402                                stmts: [
1403                                    (LetStmt @ 12..25,
1404                                        mutable: false,
1405                                        name: ("a", @ 16..17),
1406                                        type: (None),
1407                                        expr: (Bool true, @ 20..24)),
1408                                    (ExprStmt @ 26..28, (Ident "a", @ 26..27))],
1409                                expr: (None)))],
1410                    globals: [])
1411            },
1412        )?;
1413
1414        // fn add(left: int, right: int) -> int { return left + right; }
1415        program_test(
1416            tokens![
1417                Fn @ 0..2,
1418                Ident("add") @ 3..6,
1419                LParen @ 6..7,
1420                Ident("left") @ 7..11,
1421                Colon @ 11..12,
1422                Ident("int") @ 13..16,
1423                Comma @ 16..17,
1424                Ident("right") @ 18..23,
1425                Colon @ 23..24,
1426                Ident("int") @ 25..28,
1427                RParen @ 28..29,
1428                Arrow @ 30..32,
1429                Ident("int") @ 33..36,
1430                LBrace @ 37..38,
1431                Return @ 39..45,
1432                Ident("left") @ 46..50,
1433                Plus @ 51..52,
1434                Ident("right") @ 53..58,
1435                Semicolon @ 58..59,
1436                RBrace @ 60..61,
1437            ],
1438            tree! {
1439                (Program @ 0..61,
1440                    functions: [
1441                        (FunctionDefinition @ 0..61,
1442                            name: ("add", @ 3..6),
1443                            params @ 6..29: [
1444                                (Parameter,
1445                                    mutable: false,
1446                                    name: ("left", @ 7..11),
1447                                    type: (Type::Int(0), @ 13..16)),
1448                                (Parameter,
1449                                    mutable: false,
1450                                    name: ("right", @ 18..23),
1451                                    type: (Type::Int(0), @ 25..28))],
1452                            return_type: (Some(Type::Int(0)), @ 33..36),
1453                            block: (Block @ 37..61,
1454                                stmts: [
1455                                    (ReturnStmt @ 39..59, (Some(InfixExpr @ 46..58,
1456                                        lhs: (Ident "left", @ 46..50),
1457                                        op: InfixOp::Plus,
1458                                        rhs: (Ident "right", @ 53..58))))],
1459                                expr: (None)))],
1460                    globals: [])
1461            },
1462        )?;
1463
1464        // fn a() {} fn b() {} let a = 1;
1465        program_test(
1466            tokens![
1467                Fn @ 0..2,
1468                Ident("a") @ 3..4,
1469                LParen @ 4..5,
1470                RParen @ 5..6,
1471                LBrace @ 7..8,
1472                RBrace @ 8..9,
1473                Fn @ 10..12,
1474                Ident("b") @ 13..14,
1475                LParen @ 14..15,
1476                RParen @ 15..16,
1477                LBrace @ 17..18,
1478                RBrace @ 18..19,
1479                Let @ 20..23,
1480                Ident("a") @ 24..25,
1481                Assign @ 26..27,
1482                Int(1) @ 28..29,
1483                Semicolon @ 29..30,
1484            ],
1485            tree! {
1486                (Program @ 0..30,
1487                    functions: [
1488                        (FunctionDefinition @ 0..9,
1489                            name: ("a", @ 3..4),
1490                            params @ 4..6: [],
1491                            return_type: (None, @ 5..8),
1492                            block: (Block @ 7..9,
1493                                stmts: [],
1494                                expr: (None))),
1495                        (FunctionDefinition @ 10..19,
1496                            name: ("b", @ 13..14),
1497                            params @ 14..16: [],
1498                            return_type: (None, @ 15..18),
1499                            block: (Block @ 17..19,
1500                                stmts: [],
1501                                expr: (None)))],
1502                    globals: [
1503                        (Let @ 20..30,
1504                            mutable: false,
1505                            name: ("a", @ 24..25),
1506                            type: (None),
1507                            expr: (Int 1, @ 28..29))])
1508            },
1509        )?;
1510
1511        Ok(())
1512    }
1513}