luaparse/
parser.rs

1//! The Lua 5.3 parser.
2//!
3//! ```rust
4//! # use luaparse::{InputCursor, Lexer, Parser};
5//! let buf = "local a = 42;";
6//! let mut parser = Parser::new(Lexer::new(InputCursor::new(buf)));
7//!
8//! match parser.chunk() {
9//!     Ok(block) => println!("{}", block),
10//!     Err(e) => eprintln!("{}", e),
11//! }
12//! ```
13
14use std::borrow::Cow;
15use std::fmt::{self, Display};
16use std::iter::Iterator;
17use std::iter::Peekable;
18
19use crate::ast::*;
20use crate::lexer::{Lexer, LexerError};
21use crate::span::{HasSpan, Span};
22use crate::symbol::Symbol;
23use crate::token::{Token, TokenKind};
24
25/// The error type returned by the parser.
26#[derive(Clone, Debug)]
27#[allow(clippy::large_enum_variant)]
28pub enum ParseError<'a> {
29    /// An error that occured in the lexer.
30    LexerError(LexerError),
31
32    /// Expected one of X, Y, or Z, found A.
33    UnexpectedToken {
34        expected: Cow<'static, [TokenKind]>,
35        found: TokenReference<'a>,
36    },
37
38    /// Expected variable, found a function call / a parenthesized expression.
39    VarExpected {
40        expr: PrefixExpr<'a>,
41    },
42
43    /// Expected a statement, found a parenthesized expression.
44    StatementExpected {
45        expr: ParenthesizedExpr<'a>,
46    },
47
48    /// The `break` statement is not enclosed in any loop.
49    BreakOutsideLoop {
50        stat: BreakStat<'a>,
51    },
52}
53
54fn format_expected_list(expected: &[TokenKind]) -> String {
55    match expected.len() {
56        0 => "nothing".to_owned(),
57        1 => expected[0].to_string(),
58        2 => format!("{} or {}", expected[0], expected[1]),
59        _ => {
60            let mut tokens = expected
61                .iter()
62                .map(|kind| kind.to_string())
63                .collect::<Vec<_>>();
64
65            tokens.sort_unstable();
66
67            format!(
68                "one of {}, or {}",
69                tokens[..(tokens.len() - 1)].join(", "),
70                tokens[tokens.len() - 1],
71            )
72        },
73    }
74}
75
76impl Display for ParseError<'_> {
77    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
78        let s = match self {
79            Self::LexerError(e) => e.to_string(),
80            Self::UnexpectedToken { expected, found } => format!(
81                "expected {}, found {}",
82                format_expected_list(expected),
83                found.token.kind()
84            ),
85            Self::VarExpected { expr } => format!(
86                "expected a variable, found {}",
87                match expr {
88                    PrefixExpr::Parenthesized(_) => "a parenthesized expression",
89                    PrefixExpr::Call(_) => "a function call",
90                    _ => unreachable!(),
91                }
92            ),
93            Self::StatementExpected { .. } => {
94                "expected a statement, found a parenthesized expression".to_owned()
95            }
96            Self::BreakOutsideLoop { .. } => {
97                "the break statement is not enclosed in any loop".to_owned()
98            }
99        };
100
101        write!(formatter, "{}", s)
102    }
103}
104
105impl std::error::Error for ParseError<'_> {
106    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
107        match self {
108            Self::LexerError(ref e) => Some(e),
109            _ => None,
110        }
111    }
112}
113
114impl HasSpan for ParseError<'_> {
115    fn span(&self) -> Span {
116        match self {
117            Self::LexerError(e) => e.span(),
118            Self::UnexpectedToken { found, .. } => found.span(),
119            Self::VarExpected { expr } => expr.span(),
120            Self::StatementExpected { expr } => expr.span(),
121            Self::BreakOutsideLoop { stat } => stat.span(),
122        }
123    }
124}
125
126/// Lexer which skips whitespace and comment tokens, giving TokenReference
127#[derive(Clone, Debug)]
128struct RefLexer<'a> {
129    lexer: Peekable<Lexer<'a>>,
130    saved: Option<Token<'a>>, // same as using Peekable, but easier to use in this case
131    leading_trivia: Vec<Token<'a>>,
132    trailing_trivia: Vec<Token<'a>>,
133}
134
135impl<'a> RefLexer<'a> {
136    fn new(lexer: Lexer<'a>) -> RefLexer<'a> {
137        RefLexer {
138            lexer: lexer.peekable(),
139            saved: None,
140            leading_trivia: Vec::new(),
141            trailing_trivia: Vec::new(),
142        }
143    }
144}
145
146impl<'a> Iterator for RefLexer<'a> {
147    type Item = Result<TokenReference<'a>, LexerError>;
148
149    fn next(&mut self) -> Option<Self::Item> {
150        let token = loop {
151            let saved = self.saved.take().map(Ok).into_iter();
152            let next = saved.chain(&mut self.lexer).next()?;
153            match next {
154                Ok(t) if t.kind().is_trivia() => {
155                    self.leading_trivia.push(t);
156                }
157                Ok(t) => break t,
158                Err(e) => return Some(Err(e)),
159            }
160        };
161
162        loop {
163            match self.lexer.peek() {
164                Some(Ok(t)) if t.kind().is_trivia() => self
165                    .trailing_trivia
166                    .push(self.lexer.next().unwrap().unwrap()),
167                Some(Ok(_)) => {
168                    self.saved = Some(self.lexer.next().unwrap().unwrap());
169                    break;
170                }
171                _ => break,
172            }
173        }
174
175        Some(Ok(TokenReference {
176            leading_trivia: self.leading_trivia.drain(..).collect(),
177            token,
178            trailing_trivia: self.trailing_trivia.drain(..).collect(),
179        }))
180    }
181}
182
183/// The parser.
184#[derive(Clone, Debug)]
185pub struct Parser<'a> {
186    lexer: Peekable<RefLexer<'a>>,
187    is_inside_loop: bool,
188}
189
190trait Expect {
191    fn matches(&self, token: TokenKind) -> bool;
192    fn to_token_kinds(&self) -> Cow<'static, [TokenKind]>;
193}
194
195impl Expect for &'static [TokenKind] {
196    fn matches(&self, token: TokenKind) -> bool {
197        self.contains(&token)
198    }
199
200    fn to_token_kinds(&self) -> Cow<'static, [TokenKind]> {
201        (*self).into()
202    }
203}
204
205impl Expect for &'_ [Symbol] {
206    fn matches(&self, token: TokenKind) -> bool {
207        if let TokenKind::Symbol(symbol) = token {
208            self.contains(&symbol)
209        } else {
210            false
211        }
212    }
213
214    fn to_token_kinds(&self) -> Cow<'static, [TokenKind]> {
215        self.iter().copied().map(TokenKind::Symbol).collect()
216    }
217}
218
219impl<T: Clone + Into<TokenKind>> Expect for T {
220    fn matches(&self, token: TokenKind) -> bool {
221        self.clone().into() == token
222    }
223
224    fn to_token_kinds(&self) -> Cow<'static, [TokenKind]> {
225        vec![self.clone().into()].into()
226    }
227}
228
229macro_rules! lookahead {
230    ($s:ident { $($expect:expr => $expr:expr,)+ _ => $catch:expr, }) => ({
231        match $s.lexer.peek() {
232            $(Some(Ok(t)) if $expect.matches(t.token.kind()) => $expr,)+
233            _ => $catch,
234        }
235    });
236
237    ($s:ident { $($expect:expr => $expr:expr,)+ }) => ({
238        let expected = || {
239            vec![$($expect.to_token_kinds().into_owned(), )+].into_iter().flatten().collect()
240        };
241
242        match $s.lexer.peek() {
243            $(Some(Ok(t)) if $expect.matches(t.token.kind()) => $expr,)+
244            Some(Ok(t)) => return Err(ParseError::UnexpectedToken {
245                expected: expected(),
246                found: t.clone(),
247            }),
248            Some(Err(e)) => return Err(ParseError::LexerError(e.clone())),
249            None => panic!("lookahead called after reaching end of file"),
250        }
251    })
252}
253
254impl<'a> Parser<'a> {
255    /// Creates a new parser from the given lexer instance.
256    pub fn new(lexer: Lexer<'a>) -> Parser<'a> {
257        Parser {
258            lexer: RefLexer::new(lexer).peekable(),
259            is_inside_loop: false,
260        }
261    }
262
263    /// Parses the whole buffer as a Lua block.
264    pub fn chunk(&mut self) -> Result<Block<'a>, ParseError<'a>> {
265        let block = self.block()?;
266        self.expect(TokenKind::Eof)?;
267
268        Ok(block)
269    }
270
271    fn expect(&mut self, variants: impl Expect) -> Result<TokenReference<'a>, ParseError<'a>> {
272        match self.lexer.next() {
273            Some(Ok(t)) if variants.matches(t.token.kind()) => Ok(t),
274            Some(Ok(t)) => Err(ParseError::UnexpectedToken {
275                expected: variants.to_token_kinds(),
276                found: t,
277            }),
278            Some(Err(e)) => Err(ParseError::LexerError(e)),
279            None => panic!("expect called after reaching eof of file"),
280        }
281    }
282
283    fn number(&mut self) -> Result<NumberLit<'a>, ParseError<'a>> {
284        self.expect(TokenKind::Number).map(NumberLit)
285    }
286
287    fn nil(&mut self) -> Result<NilLit<'a>, ParseError<'a>> {
288        self.expect(Symbol::Nil).map(NilLit)
289    }
290
291    fn boolean(&mut self) -> Result<BooleanLit<'a>, ParseError<'a>> {
292        self.expect(BooleanLit::TOKEN_KINDS).map(BooleanLit)
293    }
294
295    fn string(&mut self) -> Result<StringLit<'a>, ParseError<'a>> {
296        self.expect(TokenKind::String).map(StringLit)
297    }
298
299    fn name(&mut self) -> Result<Name<'a>, ParseError<'a>> {
300        self.expect(TokenKind::Ident).map(Name)
301    }
302
303    fn table_constructor(&mut self) -> Result<TableConstructor<'a>, ParseError<'a>> {
304        let opening = self.expect(Symbol::CurlyBracketLeft)?;
305        let mut fields = Vec::<TableField<'a>>::new();
306
307        let closing = loop {
308            if let Some(last) = fields.last_mut() {
309                if last.separator.is_none() {
310                    let t = self.expect(
311                        &[Symbol::Comma, Symbol::Semicolon, Symbol::CurlyBracketRight][..],
312                    )?;
313
314                    if t.token.kind() == TokenKind::Symbol(Symbol::CurlyBracketRight) {
315                        break t;
316                    } else {
317                        last.separator = Some(t);
318                    }
319                }
320            }
321
322            let (key, value) = lookahead!(self {
323                Symbol::CurlyBracketRight => {
324                    break self.expect(Symbol::CurlyBracketRight)?
325                },
326
327                TokenKind::Ident => {
328                    let key = self.name()?;
329                    lookahead!(self {
330                        Symbol::Assign => {
331                            let eq = self.expect(Symbol::Assign)?;
332                            let value = self.expr()?;
333                            (Some((TableKey::Name { key }, eq)), value)
334                        },
335                        _ => {
336                            let prefix = self.prefix_expr_right(PrefixExpr::Var(Var::Name(key)))?;
337                            let expr = self.expr_rec_right(Expr::Prefix(prefix), 0)?;
338                            (None, expr)
339                        },
340                    })
341                },
342
343                Symbol::SquareBracketLeft => {
344                    let opening = self.expect(Symbol::SquareBracketLeft)?;
345                    let key = Box::new(self.expr()?);
346                    let closing = self.expect(Symbol::SquareBracketRight)?;
347                    let eq = self.expect(Symbol::Assign)?;
348                    let value = self.expr()?;
349                    let key = TableKey::Expr {
350                        brackets: Brackets(opening, closing), key,
351                    };
352                    (Some((key, eq)), value)
353                },
354
355                _ => (None, self.expr()?),
356            });
357
358            fields.push(TableField {
359                key,
360                value: Box::new(value),
361                separator: None,
362            });
363        };
364
365        Ok(TableConstructor {
366            brackets: Brackets(opening, closing),
367            fields,
368        })
369    }
370
371    fn unop(&mut self) -> Result<UnOp<'a>, ParseError<'a>> {
372        self.expect(UnOp::TOKEN_KINDS).map(UnOp)
373    }
374
375    fn binop(&mut self) -> Result<BinOp<'a>, ParseError<'a>> {
376        self.expect(BinOp::TOKEN_KINDS).map(BinOp)
377    }
378
379    fn peek_binop(&mut self) -> Option<BinOpKind> {
380        let t = self.lexer.peek()?.as_ref().ok()?;
381        match t.token.kind() {
382            TokenKind::Symbol(s) => BinOpKind::from_symbol(s),
383            _ => None,
384        }
385    }
386
387    fn var_field(&mut self) -> Result<VarField<'a>, ParseError<'a>> {
388        lookahead!(self {
389            Symbol::Period => {
390                let period = self.expect(Symbol::Period)?;
391                let key = self.name()?;
392                Ok(VarField::Name { period, key })
393            },
394            Symbol::SquareBracketLeft => {
395                let opening = self.expect(Symbol::SquareBracketLeft)?;
396                let key = Box::new(self.expr()?);
397                let closing = self.expect(Symbol::SquareBracketRight)?;
398                Ok(VarField::Expr { brackets: Brackets(opening, closing), key })
399            },
400        })
401    }
402
403    fn punctuated<T, P>(
404        &mut self,
405        sep: impl Expect + Clone,
406        mut f: P,
407    ) -> Result<Punctuated<'a, T>, ParseError<'a>>
408    where
409        P: FnMut(&mut Self) -> Result<T, ParseError<'a>>,
410    {
411        let mut pairs = Vec::new();
412
413        let first = f(self)?;
414        pairs.push((first, None));
415
416        loop {
417            lookahead!(self {
418                &sep => {
419                    let separator = self.expect(sep.clone())?;
420                    pairs.last_mut().unwrap().1.replace(separator);
421                    pairs.push((f(self)?, None));
422                },
423
424                _ => break,
425            });
426        }
427
428        Ok(Punctuated { pairs })
429    }
430
431    fn parenthesized_list<T, F>(&mut self, f: F) -> Result<ParenthesizedList<'a, T>, ParseError<'a>>
432    where
433        F: FnMut(&mut Self) -> Result<T, ParseError<'a>>,
434    {
435        let opening = self.expect(Symbol::RoundBracketLeft)?;
436        let list = lookahead!(self {
437            Symbol::RoundBracketRight => {
438                Punctuated { pairs: Vec::new() }
439            },
440            _ => self.punctuated(Symbol::Comma, f)?,
441        });
442
443        let closing = self.expect(Symbol::RoundBracketRight)?;
444        let brackets = Brackets(opening, closing);
445
446        Ok(ParenthesizedList { brackets, list })
447    }
448
449    fn function_call(
450        &mut self,
451        prefix_expr: PrefixExpr<'a>,
452    ) -> Result<FunctionCall<'a>, ParseError<'a>> {
453        let callee = lookahead!(self {
454            Symbol::Colon => {
455                let colon = self.expect(Symbol::Colon)?;
456                let name = self.name()?;
457
458                FunctionCallee::Method {
459                    object: Box::new(prefix_expr),
460                    colon,
461                    name,
462                }
463            },
464
465            _ => FunctionCallee::Expr(Box::new(prefix_expr)),
466        });
467
468        let args = lookahead!(self {
469            Symbol::CurlyBracketLeft => {
470                FunctionArgs::TableConstructor(self.table_constructor()?)
471            },
472
473            TokenKind::String => {
474                FunctionArgs::StringLit(self.string()?)
475            },
476
477            Symbol::RoundBracketLeft => {
478                FunctionArgs::ParenthesizedList(
479                    self.parenthesized_list(|s| s.expr().map(Box::new))?
480                )
481            },
482        });
483
484        Ok(FunctionCall { callee, args })
485    }
486
487    fn prefix_expr_right(
488        &mut self,
489        mut left: PrefixExpr<'a>,
490    ) -> Result<PrefixExpr<'a>, ParseError<'a>> {
491        const CALL_TOKENS: &[TokenKind] = &[
492            TokenKind::Symbol(Symbol::CurlyBracketLeft),
493            TokenKind::String,
494            TokenKind::Symbol(Symbol::RoundBracketLeft),
495            TokenKind::Symbol(Symbol::Colon),
496        ];
497
498        loop {
499            lookahead!(self {
500                &[Symbol::SquareBracketLeft, Symbol::Period][..] => {
501                    let field = self.var_field()?;
502                    left = PrefixExpr::Var(Var::Field(Box::new(left), field));
503                },
504
505                CALL_TOKENS => {
506                    left = PrefixExpr::Call(self.function_call(left)?);
507                },
508
509                _ => break,
510            });
511        }
512
513        Ok(left)
514    }
515
516    fn prefix_expr(&mut self) -> Result<PrefixExpr<'a>, ParseError<'a>> {
517        let left = lookahead!(self {
518            Symbol::RoundBracketLeft => {
519                PrefixExpr::Parenthesized(self.parenthesized_expr()?)
520            },
521
522            TokenKind::Ident => {
523                PrefixExpr::Var(Var::Name(self.name()?))
524            },
525        });
526
527        self.prefix_expr_right(left)
528    }
529
530    fn parenthesized_expr(&mut self) -> Result<ParenthesizedExpr<'a>, ParseError<'a>> {
531        let opening = self.expect(Symbol::RoundBracketLeft)?;
532        let expr = self.expr()?;
533        let closing = self.expect(Symbol::RoundBracketRight)?;
534        Ok(ParenthesizedExpr {
535            brackets: Brackets(opening, closing),
536            expr: Box::new(expr),
537        })
538    }
539
540    /// Parses a Lua expression.
541    pub fn expr(&mut self) -> Result<Expr<'a>, ParseError<'a>> {
542        self.expr_rec(0)
543    }
544
545    fn expr_rec(&mut self, min_bp: u8) -> Result<Expr<'a>, ParseError<'a>> {
546        let left = lookahead!(self {
547            Symbol::Nil => {
548                Expr::Nil(self.nil()?)
549            },
550
551            BooleanLit::TOKEN_KINDS => {
552                Expr::Boolean(self.boolean()?)
553            },
554
555            TokenKind::Number => {
556                Expr::Number(self.number()?)
557            },
558
559            TokenKind::String => {
560                Expr::String(self.string()?)
561            },
562
563            Symbol::TriplePeriod => {
564                Expr::Vararg(self.vararg()?)
565            },
566
567            Symbol::CurlyBracketLeft => {
568                Expr::TableConstructor(self.table_constructor()?)
569            },
570
571            &[TokenKind::Ident, TokenKind::Symbol(Symbol::RoundBracketLeft)][..] => {
572                Expr::Prefix(self.prefix_expr()?)
573            },
574
575            Symbol::Function => Expr::Function(self.function_expr()?),
576
577            UnOp::TOKEN_KINDS => {
578                let op = self.unop()?;
579                let ((), r_bp) = op.kind().binding_power();
580                let right = self.expr_rec(r_bp)?;
581                Expr::UnOp(UnOpExpr {
582                    op, right: Box::new(right)
583                })
584            },
585        });
586
587        self.expr_rec_right(left, min_bp)
588    }
589
590    fn expr_rec_right(
591        &mut self,
592        mut left: Expr<'a>,
593        min_bp: u8,
594    ) -> Result<Expr<'a>, ParseError<'a>> {
595        while let Some(op_kind) = self.peek_binop() {
596            let (l_bp, r_bp) = op_kind.binding_power();
597            if l_bp < min_bp {
598                break;
599            }
600
601            let op = self.binop()?;
602            let right = self.expr_rec(r_bp)?;
603            left = Expr::BinOp(BinOpExpr {
604                left: Box::new(left),
605                op,
606                right: Box::new(right),
607            });
608        }
609
610        Ok(left)
611    }
612
613    const TERMINATORS: &'static [TokenKind] = &[
614        TokenKind::Symbol(Symbol::End),
615        TokenKind::Symbol(Symbol::Until),
616        TokenKind::Symbol(Symbol::Else),
617        TokenKind::Symbol(Symbol::ElseIf),
618        TokenKind::Eof,
619    ];
620
621    /// Parses a block (a list of statements).
622    ///
623    /// Unless you don't need to parse the whole buffer, use `chunk` instead.
624    pub fn block(&mut self) -> Result<Block<'a>, ParseError<'a>> {
625        let mut statements = Vec::new();
626
627        while let Some(t) = self.lexer.peek().and_then(|v| v.as_ref().ok()) {
628            if t.token.kind() == TokenKind::Symbol(Symbol::Return) {
629                statements.push(Statement::Return(self.return_stat()?));
630                break;
631            }
632
633            if Self::TERMINATORS.contains(&t.token.kind()) {
634                break;
635            }
636
637            statements.push(self.statement()?);
638        }
639
640        Ok(Block { statements })
641    }
642
643    fn empty_stat(&mut self) -> Result<EmptyStat<'a>, ParseError<'a>> {
644        let semi = self.expect(Symbol::Semicolon)?;
645        Ok(EmptyStat(semi))
646    }
647
648    fn block_stat(&mut self) -> Result<BlockStat<'a>, ParseError<'a>> {
649        let do_ = self.expect(Symbol::Do)?;
650        let block = Box::new(self.block()?);
651        let end = self.expect(Symbol::End)?;
652        Ok(BlockStat { do_, block, end })
653    }
654
655    fn while_stat(&mut self) -> Result<WhileStat<'a>, ParseError<'a>> {
656        let was_inside_loop = self.is_inside_loop;
657        self.is_inside_loop = true;
658
659        let stat = WhileStat {
660            while_: self.expect(Symbol::While)?,
661            condition: Box::new(self.expr()?),
662            do_: self.expect(Symbol::Do)?,
663            block: Box::new(self.block()?),
664            end: self.expect(Symbol::End)?,
665        };
666
667        self.is_inside_loop = was_inside_loop;
668
669        Ok(stat)
670    }
671
672    fn generic_for(
673        &mut self,
674        for_: TokenReference<'a>,
675        names: Punctuated<'a, Name<'a>>,
676    ) -> Result<GenericFor<'a>, ParseError<'a>> {
677        Ok(GenericFor {
678            for_,
679            names,
680            in_: self.expect(Symbol::In)?,
681            exprs: self.punctuated(Symbol::Comma, |s| s.expr().map(Box::new))?,
682            do_: self.expect(Symbol::Do)?,
683            block: Box::new(self.block()?),
684            end: self.expect(Symbol::End)?,
685        })
686    }
687
688    fn numerical_for(
689        &mut self,
690        for_: TokenReference<'a>,
691        mut names: Punctuated<'a, Name<'a>>,
692    ) -> Result<NumericalFor<'a>, ParseError<'a>> {
693        Ok(NumericalFor {
694            for_,
695            name: names.pairs.remove(0).0,
696            assign: self.expect(Symbol::Assign)?,
697            from: Box::new(self.expr()?),
698            comma: self.expect(Symbol::Comma)?,
699            to: Box::new(self.expr()?),
700            step: lookahead!(self {
701                Symbol::Comma => {
702                    let comma = self.expect(Symbol::Comma)?;
703                    let expr = Box::new(self.expr()?);
704                    Some((comma, expr))
705                },
706                _ => None,
707            }),
708            do_: self.expect(Symbol::Do)?,
709            block: Box::new(self.block()?),
710            end: self.expect(Symbol::End)?,
711        })
712    }
713
714    fn for_stat(&mut self) -> Result<ForStat<'a>, ParseError<'a>> {
715        let was_inside_loop = self.is_inside_loop;
716        self.is_inside_loop = true;
717
718        let for_ = self.expect(Symbol::For)?;
719
720        let names = self.punctuated(Symbol::Comma, Self::name)?;
721
722        let stat = if names.pairs.len() > 1 {
723            self.generic_for(for_, names).map(ForStat::Generic)?
724        } else {
725            lookahead!(self {
726                Symbol::In => {
727                    self.generic_for(for_, names).map(ForStat::Generic)?
728                },
729                Symbol::Assign => {
730                    self.numerical_for(for_, names).map(ForStat::Numerical)?
731                },
732            })
733        };
734
735        self.is_inside_loop = was_inside_loop;
736
737        Ok(stat)
738    }
739
740    fn return_stat(&mut self) -> Result<ReturnStat<'a>, ParseError<'a>> {
741        let return_ = self.expect(Symbol::Return)?;
742
743        let next = self.lexer.peek().and_then(|v| v.as_ref().ok());
744        let has_expr = next
745            .filter(|t| !Self::TERMINATORS.contains(&t.token.kind()))
746            .is_some();
747
748        let exprs = if has_expr {
749            self.punctuated(Symbol::Comma, |s| s.expr().map(Box::new))?
750        } else {
751            Punctuated { pairs: Vec::new() }
752        };
753
754        let semi = lookahead!(self {
755            Symbol::Semicolon => {
756                self.expect(Symbol::Semicolon).map(Some)?
757            },
758            _ => None,
759        });
760
761        Ok(ReturnStat {
762            return_,
763            exprs,
764            semi,
765        })
766    }
767
768    fn break_stat(&mut self) -> Result<BreakStat<'a>, ParseError<'a>> {
769        let stat = self.expect(Symbol::Break).map(BreakStat)?;
770        if self.is_inside_loop {
771            Ok(stat)
772        } else {
773            Err(ParseError::BreakOutsideLoop { stat })
774        }
775    }
776
777    /// Parses a single statement.
778    pub fn statement(&mut self) -> Result<Statement<'a>, ParseError<'a>> {
779        lookahead!(self {
780            Symbol::Semicolon => self.empty_stat().map(Statement::Empty),
781            Symbol::Do => self.block_stat().map(Statement::Block),
782            Symbol::While => self.while_stat().map(Statement::While),
783            Symbol::For => self.for_stat().map(Statement::For),
784            Symbol::Repeat => self.repeat_stat().map(Statement::Repeat),
785            Symbol::Return => self.return_stat().map(Statement::Return),
786            Symbol::Break => self.break_stat().map(Statement::Break),
787            Symbol::Function => self.function_declaration(None).map(Statement::FunctionDeclaration),
788            Symbol::DoubleColon => self.label_stat().map(Statement::Label),
789            Symbol::Goto => self.goto_stat().map(Statement::Goto),
790            Symbol::If => self.if_stat().map(Statement::If),
791            &[TokenKind::Symbol(Symbol::RoundBracketLeft), TokenKind::Ident][..] => {
792                let expr = self.prefix_expr()?;
793                match expr {
794                    PrefixExpr::Var(var) => self.assignment(var).map(Statement::Assignment),
795                    PrefixExpr::Call(call) => Ok(Statement::FunctionCall(call)),
796                    PrefixExpr::Parenthesized(expr) => Err(ParseError::StatementExpected { expr })
797                }
798            },
799            Symbol::Local => self.local(),
800        })
801    }
802
803    fn var(&mut self) -> Result<Var<'a>, ParseError<'a>> {
804        match self.prefix_expr()? {
805            PrefixExpr::Var(v) => Ok(v),
806            expr => Err(ParseError::VarExpected { expr }),
807        }
808    }
809
810    fn varlist(&mut self, first: Var<'a>) -> Result<Punctuated<'a, Var<'a>>, ParseError<'a>> {
811        let mut first = (first, None);
812        let list = lookahead!(self {
813            Symbol::Comma => {
814                first.1 = self.expect(Symbol::Comma).map(Some)?;
815                let mut rest = self.punctuated(Symbol::Comma, |s| s.var())?;
816                rest.pairs.insert(0, first);
817                rest
818            },
819            _ => Punctuated { pairs: vec![first] },
820        });
821        Ok(list)
822    }
823
824    fn assignment(&mut self, first: Var<'a>) -> Result<AssignmentStat<'a>, ParseError<'a>> {
825        let vars = self.varlist(first)?;
826        let assign = self.expect(Symbol::Assign)?;
827        let exprs = self.punctuated(Symbol::Comma, |s| s.expr().map(Box::new))?;
828        Ok(AssignmentStat {
829            vars,
830            assign,
831            exprs,
832        })
833    }
834
835    fn local(&mut self) -> Result<Statement<'a>, ParseError<'a>> {
836        let local = self.expect(Symbol::Local)?;
837
838        lookahead!(self {
839            Symbol::Function => {
840                self.function_declaration(Some(local)).map(Statement::FunctionDeclaration)
841            },
842
843            _ => self.local_declaration(local).map(Statement::LocalDeclaration),
844        })
845    }
846
847    fn local_declaration(
848        &mut self,
849        local: TokenReference<'a>,
850    ) -> Result<LocalDeclarationStat<'a>, ParseError<'a>> {
851        let names = self.punctuated(Symbol::Comma, |s| s.name())?;
852
853        let definition = lookahead!(self {
854            Symbol::Assign => {
855                let assign = self.expect(Symbol::Assign)?;
856                let exprs = self.punctuated(
857                    Symbol::Comma,
858                    |s| s.expr().map(Box::new)
859                )?;
860
861                Some(LocalDefinition { assign, exprs })
862            },
863            _ => None,
864        });
865
866        Ok(LocalDeclarationStat {
867            local,
868            names,
869            definition,
870        })
871    }
872
873    fn function_declaration(
874        &mut self,
875        local: Option<TokenReference<'a>>,
876    ) -> Result<FunctionDeclarationStat<'a>, ParseError<'a>> {
877        let function = self.expect(Symbol::Function)?;
878
879        Ok(match local {
880            Some(local) => {
881                let name = self.name()?;
882                let body = self.function_body()?;
883
884                FunctionDeclarationStat::Local {
885                    local,
886                    function,
887                    name,
888                    body,
889                }
890            }
891
892            None => {
893                let name = self.function_name()?;
894                let body = self.function_body()?;
895
896                FunctionDeclarationStat::Nonlocal {
897                    function,
898                    name,
899                    body,
900                }
901            }
902        })
903    }
904
905    fn function_name(&mut self) -> Result<FunctionName<'a>, ParseError<'a>> {
906        let mut name = self.punctuated(Symbol::Period, |s| s.name())?;
907
908        Ok(lookahead!(self {
909            Symbol::Colon => {
910                let colon = self.expect(Symbol::Colon)?;
911                let method = self.name()?;
912
913                FunctionName::Method {
914                    receiver: name,
915                    colon,
916                    method
917                }
918            },
919
920            _ => if name.pairs.len() == 1 {
921                FunctionName::PlainName(name.pairs.remove(0).0)
922            } else {
923                FunctionName::Indexed(name)
924            },
925        }))
926    }
927
928    fn function_body(&mut self) -> Result<FunctionBody<'a>, ParseError<'a>> {
929        let was_inside_loop = self.is_inside_loop;
930        self.is_inside_loop = false;
931
932        let mut params = Vec::new();
933        let opening = self.expect(Symbol::RoundBracketLeft)?;
934
935        let mut vararg = None;
936
937        let closing = lookahead!(self {
938            Symbol::RoundBracketRight => self.expect(Symbol::RoundBracketRight)?,
939            Symbol::TriplePeriod => {
940                vararg.replace(self.vararg()?);
941
942                self.expect(Symbol::RoundBracketRight)?
943            },
944            _ => {
945                params.push((self.name()?, None));
946
947                loop {
948                    lookahead!(self {
949                        Symbol::Comma => {
950                            params.last_mut().unwrap().1.replace(self.expect(Symbol::Comma)?);
951
952                            lookahead!(self {
953                                Symbol::TriplePeriod => {
954                                    vararg.replace(self.vararg()?);
955                                    break self.expect(Symbol::RoundBracketRight)?;
956                                },
957                                _ => params.push((self.name()?, None)),
958                            });
959                        },
960                        Symbol::RoundBracketRight => break self.expect(Symbol::RoundBracketRight)?,
961                    });
962                }
963            },
964        });
965
966        let block = Box::new(self.block()?);
967        let end = self.expect(Symbol::End)?;
968
969        let params = ParenthesizedList {
970            brackets: Brackets(opening, closing),
971            list: Punctuated { pairs: params },
972        };
973
974        self.is_inside_loop = was_inside_loop;
975
976        Ok(FunctionBody {
977            params,
978            vararg,
979            block,
980            end,
981        })
982    }
983
984    fn vararg(&mut self) -> Result<Vararg<'a>, ParseError<'a>> {
985        self.expect(Symbol::TriplePeriod).map(Vararg)
986    }
987
988    fn function_expr(&mut self) -> Result<FunctionExpr<'a>, ParseError<'a>> {
989        let function = self.expect(Symbol::Function)?;
990        let body = self.function_body()?;
991
992        Ok(FunctionExpr { function, body })
993    }
994
995    fn repeat_stat(&mut self) -> Result<RepeatStat<'a>, ParseError<'a>> {
996        let was_inside_loop = self.is_inside_loop;
997        self.is_inside_loop = true;
998
999        let repeat = self.expect(Symbol::Repeat)?;
1000        let block = Box::new(self.block()?);
1001        let until = self.expect(Symbol::Until)?;
1002        let condition = self.expr()?;
1003
1004        self.is_inside_loop = was_inside_loop;
1005
1006        Ok(RepeatStat {
1007            repeat,
1008            block,
1009            until,
1010            condition,
1011        })
1012    }
1013
1014    fn label_stat(&mut self) -> Result<LabelStat<'a>, ParseError<'a>> {
1015        let preceding = self.expect(Symbol::DoubleColon)?;
1016        let name = self.name()?;
1017        let following = self.expect(Symbol::DoubleColon)?;
1018
1019        Ok(LabelStat {
1020            preceding,
1021            name,
1022            following,
1023        })
1024    }
1025
1026    fn goto_stat(&mut self) -> Result<GotoStat<'a>, ParseError<'a>> {
1027        let goto = self.expect(Symbol::Goto)?;
1028        let label = self.name()?;
1029
1030        Ok(GotoStat { goto, label })
1031    }
1032
1033    fn if_stat(&mut self) -> Result<IfStat<'a>, ParseError<'a>> {
1034        let if_ = self.expect(Symbol::If)?;
1035        let condition = self.expr()?;
1036        let then = self.expect(Symbol::Then)?;
1037        let block = Box::new(self.block()?);
1038
1039        let mut elseifs = Vec::new();
1040
1041        loop {
1042            lookahead!(self {
1043                Symbol::ElseIf => {
1044                    elseifs.push(self.else_if()?);
1045                },
1046
1047                _ => break,
1048            })
1049        }
1050
1051        let else_ = lookahead!(self {
1052            Symbol::Else => Some(self.else_()?),
1053            _ => None,
1054        });
1055
1056        let end = self.expect(Symbol::End)?;
1057
1058        Ok(IfStat {
1059            if_,
1060            condition,
1061            then,
1062            block,
1063            elseifs,
1064            else_,
1065            end,
1066        })
1067    }
1068
1069    fn else_if(&mut self) -> Result<ElseIf<'a>, ParseError<'a>> {
1070        let elseif = self.expect(Symbol::ElseIf)?;
1071        let condition = self.expr()?;
1072        let then = self.expect(Symbol::Then)?;
1073        let block = self.block()?;
1074
1075        Ok(ElseIf {
1076            elseif,
1077            condition,
1078            then,
1079            block,
1080        })
1081    }
1082
1083    fn else_(&mut self) -> Result<Else<'a>, ParseError<'a>> {
1084        let else_ = self.expect(Symbol::Else)?;
1085        let block = self.block()?;
1086
1087        Ok(Else { else_, block })
1088    }
1089}