use ast::ASTNode;
use name::{parse_label, parse_name};
use exp::parse_explist;
named!(parse_goto<ASTNode>, map!(map!(preceded!(tag!("goto"), ws!(parse_name)), Box::new), ASTNode::Goto));
named!(parse_semicolon, ws!(tag!(";")));
named!(parse_semicolon_statement<ASTNode>, map!(parse_semicolon, |_| ASTNode::EmptyStatement));
named!(pub parse_statement<ASTNode>, alt!(
parse_semicolon_statement |
parse_label |
parse_goto
));
named!(pub parse_retstat<ASTNode>, map!(map!(
delimited!(
tag!("return"),
ws!(opt!(complete!(parse_explist))),
opt!(complete!(tag!(";")))
),
Box::new), ASTNode::RetStat));
#[cfg(test)]
mod tests {
use ast::ASTNode::*;
ast_valid!(parse_semicolon, parse_semicolon, ";");
ast_test!(parse_goto_1, parse_goto, "goto valid",
astb!(Goto, ast!(Name, "valid".into())));
ast_panic_test!(parse_goto_2, parse_goto, "goto 17");
ast_panic_test!(parse_goto_3, parse_goto, "got 17");
ast_test!(parse_retstat_1, parse_retstat, "return false,true ;",
astb!(RetStat, Some(ast!(ExpList, vec![
ast!(Bool, false),
ast!(Bool, true)
]))));
ast_test!(parse_retstat_2, parse_retstat, "return 1.0",
astb!(RetStat, Some(ast!(ExpList, vec![
ast!(Float, 1.0),
]))));
ast_test!(parse_retstat_3, parse_retstat, "return",
astb!(RetStat, None));
}