Skip to main content

surql_parser/upstream/syn/parser/stmt/
if.rs

1use crate::upstream::sql::Expr;
2use crate::upstream::sql::statements::IfelseStatement;
3use crate::upstream::syn::parser::mac::{expected, unexpected};
4use crate::upstream::syn::parser::{ParseResult, Parser};
5use crate::upstream::syn::token::t;
6use reblessive::Stk;
7impl Parser<'_> {
8	pub async fn parse_if_stmt(&mut self, stk: &mut Stk) -> ParseResult<IfelseStatement> {
9		let condition = stk.run(|ctx| self.parse_expr_inherit(ctx)).await?;
10		let mut res = IfelseStatement {
11			exprs: Vec::new(),
12			close: None,
13		};
14		let next = self.next();
15		match next.kind {
16			t!("THEN") => {
17				let body = stk.run(|stk| self.parse_expr_inherit(stk)).await?;
18				self.eat(t!(";"));
19				res.exprs.push((condition, body));
20				self.parse_worded_tail(stk, &mut res).await?;
21			}
22			t!("{") => {
23				let body = self.parse_block(stk, next.span).await?;
24				res.exprs.push((condition, Expr::Block(Box::new(body))));
25				self.parse_bracketed_tail(stk, &mut res).await?;
26			}
27			_ => unexpected!(self, next, "THEN or '{'"),
28		}
29		Ok(res)
30	}
31	async fn parse_worded_tail(
32		&mut self,
33		stk: &mut Stk,
34		res: &mut IfelseStatement,
35	) -> ParseResult<()> {
36		loop {
37			let next = self.next();
38			match next.kind {
39				t!("END") => return Ok(()),
40				t!("ELSE") => {
41					if self.eat(t!("IF")) {
42						let condition = stk.run(|stk| self.parse_expr_inherit(stk)).await?;
43						expected!(self, t!("THEN"));
44						let body = stk.run(|ctx| self.parse_expr_inherit(ctx)).await?;
45						self.eat(t!(";"));
46						res.exprs.push((condition, body));
47					} else {
48						let value = stk.run(|stk| self.parse_expr_inherit(stk)).await?;
49						self.eat(t!(";"));
50						expected!(self, t!("END"));
51						res.close = Some(value);
52						return Ok(());
53					}
54				}
55				_ => unexpected!(self, next, "if to end"),
56			}
57		}
58	}
59	async fn parse_bracketed_tail(
60		&mut self,
61		stk: &mut Stk,
62		res: &mut IfelseStatement,
63	) -> ParseResult<()> {
64		loop {
65			match self.peek_kind() {
66				t!("ELSE") => {
67					self.pop_peek();
68					if self.eat(t!("IF")) {
69						let condition = stk.run(|ctx| self.parse_expr_inherit(ctx)).await?;
70						let span = expected!(self, t!("{")).span;
71						let body = self.parse_block(stk, span).await?;
72						res.exprs.push((condition, Expr::Block(Box::new(body))));
73					} else {
74						let span = expected!(self, t!("{")).span;
75						let value = self.parse_block(stk, span).await?;
76						res.close = Some(Expr::Block(Box::new(value)));
77						return Ok(());
78					}
79				}
80				_ => return Ok(()),
81			}
82		}
83	}
84}