duskphantom_frontend/parse/
stmt.rs1use rayon::iter::Either;
18
19use super::*;
20
21pub fn box_stmt(input: &mut &str) -> PResult<Box<Stmt>> {
22 stmt.map(Box::new).parse_next(input)
23}
24
25pub fn vec_stmt(input: &mut &str) -> PResult<Vec<Stmt>> {
26 repeat(0.., stmt).parse_next(input)
27}
28
29pub fn expr_sc(input: &mut &str) -> PResult<Expr> {
31 (expr, cut_err(token(";")))
32 .map(|(e, _)| e)
33 .parse_next(input)
34}
35
36pub fn decl_or_expr(input: &mut &str) -> PResult<Either<Decl, Expr>> {
38 alt((decl.map(Either::Left), expr_sc.map(Either::Right))).parse_next(input)
39}
40
41pub fn stmt(input: &mut &str) -> PResult<Stmt> {
42 let disp = dispatch! { peek(any);
43 'b' => (token("break"), cut_err(token(";"))).value(Stmt::Break),
44 'c' => (token("continue"), cut_err(token(";"))).value(Stmt::Continue),
45 'i' => (token("if"), cut_err((paren(expr), box_stmt, opt((token("else"), box_stmt)))))
46 .map(|(_, (cond, pass, fail))| Stmt::If(cond, pass, fail.map_or(Stmt::Block(vec![]).into(), |(_, s)| s))),
47 'w' => (token("while"), cut_err((paren(expr), box_stmt))).map(|(_, (cond, body))| Stmt::While(cond, body)),
48 'd' => (token("do"), cut_err((box_stmt, token("while"), paren(expr), token(";"))))
49 .map(|(_, (body, _, cond, _))| Stmt::DoWhile(body, cond)),
50 'r' => (token("return"), cut_err((opt(expr), token(";"))))
51 .map(|(_, (e, _))| Stmt::Return(e)),
52 '{' => curly(cut_err(vec_stmt)).map(Stmt::Block),
53 _ => fail
54 };
55 alt((
56 disp,
57 decl.map(Stmt::Decl),
58 (opt(terminated(expr, token("="))), expr_sc).map(|(lval, expr)| Stmt::Expr(lval, expr)),
59 token(";").value(Stmt::Nothing),
60 ))
61 .parse_next(input)
62}