luallaby 0.1.0

**Work in progress** A pure-Rust Lua interpreter/compiler
Documentation
use crate::ast::{Block, Exp, Parser};
use crate::error::{LuaError, Result};
use crate::lexer::{Pos, Token};

/// ```text
/// stat ::= if exp then block {elseif exp then block} [else block] end
/// ```
pub struct If {
    pub conds: Vec<(Exp, Block, Pos)>,
    pub els: Option<Box<Block>>,
    pub pos_end: Pos,
}

impl<'a> Parser<'a> {
    pub(super) fn parse_if(&mut self) -> Result<If> {
        tok_expect!(self, Token::If);

        let mut conds = vec![self.parse_cond()?];
        let mut els = None;
        let pos_end;
        loop {
            match self.tok_next()?.into() {
                (_, Token::Elseif) => conds.push(self.parse_cond()?),
                (_, Token::Else) => {
                    els = Some(Box::new(self.parse_block()?));
                    pos_end = tok_expect!(self, Token::End);
                    break;
                }
                (pos, Token::End) => {
                    pos_end = pos;
                    break;
                }
                (pos, tok) => return err!(&*self.source, pos, LuaError::UnexpectedToken(tok)),
            }
        }

        Ok(If {
            conds,
            els,
            pos_end,
        })
    }

    fn parse_cond(&mut self) -> Result<(Exp, Block, Pos)> {
        let exp = self.parse_exp()?;
        let pos = tok_expect!(self, Token::Then);
        let block = self.parse_block()?;
        Ok((exp, block, pos))
    }
}