use crate::ast::{Block, Exp, Parser};
use crate::error::{LuaError, Result};
use crate::lexer::{Pos, Token};
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))
}
}