cas_parser/parser/ast/
while_expr.rs1use cas_error::Error;
2use crate::parser::{
3 ast::expr::Expr,
4 fmt::Latex,
5 keyword::While as WhileToken,
6 Parse,
7 Parser,
8};
9use std::{fmt, ops::Range};
10
11#[cfg(feature = "serde")]
12use serde::{Deserialize, Serialize};
13
14#[derive(Debug, Clone, PartialEq, Eq)]
17#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
18pub struct While {
19 pub condition: Box<Expr>,
21
22 pub body: Box<Expr>,
24
25 pub span: Range<usize>,
27
28 pub while_span: Range<usize>,
30}
31
32impl While {
33 pub fn span(&self) -> Range<usize> {
35 self.span.clone()
36 }
37}
38
39impl<'source> Parse<'source> for While {
40 fn std_parse(
41 input: &mut Parser<'source>,
42 recoverable_errors: &mut Vec<Error>
43 ) -> Result<Self, Vec<Error>> {
44 let while_token = input.try_parse::<WhileToken>().forward_errors(recoverable_errors)?;
45 let condition = input.try_parse::<Expr>().forward_errors(recoverable_errors)?;
46 let then_body = input.try_parse_with_state::<_, Expr>(|state| {
47 state.allow_then = true;
48 state.allow_loop_control = true;
49 }).forward_errors(recoverable_errors)?;
50 let span = while_token.span.start..then_body.span().end;
51
52 Ok(Self {
53 condition: Box::new(condition),
54 body: Box::new(then_body),
55 span,
56 while_span: while_token.span,
57 })
58 }
59}
60
61impl std::fmt::Display for While {
62 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
63 write!(f, "while {} {}", self.condition, self.body)
64 }
65}
66
67impl Latex for While {
68 fn fmt_latex(&self, f: &mut fmt::Formatter) -> fmt::Result {
69 write!(f, "\\text{{while }}")?;
70 self.condition.fmt_latex(f)?;
71 self.body.fmt_latex(f)?;
72 Ok(())
73 }
74}