cas_parser/parser/ast/
branch.rs1use cas_error::Error;
2use crate::parser::{
3 ast::expr::Expr,
4 error::{OfOutsideSumProduct, ThenOutsideIfWhileFor},
5 fmt::Latex,
6 keyword::{Of as OfToken, Then as ThenToken},
7 Parse,
8 Parser,
9};
10use std::{fmt, ops::Range};
11
12#[cfg(feature = "serde")]
13use serde::{Deserialize, Serialize};
14
15#[derive(Debug, Clone, PartialEq, Eq)]
21#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
22pub struct Then {
23 pub expr: Box<Expr>,
25
26 pub span: Range<usize>,
28
29 pub then_span: Range<usize>,
31}
32
33impl Then {
34 pub fn span(&self) -> Range<usize> {
36 self.span.clone()
37 }
38}
39
40impl<'source> Parse<'source> for Then {
41 fn std_parse(
42 input: &mut Parser<'source>,
43 recoverable_errors: &mut Vec<Error>
44 ) -> Result<Self, Vec<Error>> {
45 let then_token = input.try_parse::<ThenToken>().forward_errors(recoverable_errors)?;
46
47 if !input.state.allow_then {
48 recoverable_errors.push(Error::new(
49 vec![then_token.span.clone()],
50 ThenOutsideIfWhileFor,
51 ));
52 }
53
54 let body = input.try_parse_with_state::<_, Expr>(|input| {
56 input.allow_then = false;
57 }).forward_errors(recoverable_errors)?;
58 let span = then_token.span.start..body.span().end;
59
60 Ok(Self {
61 expr: Box::new(body),
62 span,
63 then_span: then_token.span,
64 })
65 }
66}
67
68impl std::fmt::Display for Then {
69 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
70 write!(f, "then {}", self.expr)
71 }
72}
73
74impl Latex for Then {
75 fn fmt_latex(&self, f: &mut fmt::Formatter) -> fmt::Result {
76 write!(f, "\\text{{ then }}")?;
77 self.expr.fmt_latex(f)?;
78 Ok(())
79 }
80}
81
82#[derive(Debug, Clone, PartialEq, Eq)]
90#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
91pub struct Of {
92 pub expr: Box<Expr>,
94
95 pub span: Range<usize>,
97
98 pub of_span: Range<usize>,
100}
101
102impl Of {
103 pub fn span(&self) -> Range<usize> {
105 self.span.clone()
106 }
107}
108
109impl<'source> Parse<'source> for Of {
110 fn std_parse(
111 input: &mut Parser<'source>,
112 recoverable_errors: &mut Vec<Error>
113 ) -> Result<Self, Vec<Error>> {
114 let of_token = input.try_parse::<OfToken>().forward_errors(recoverable_errors)?;
115
116 if !input.state.allow_of {
117 recoverable_errors.push(Error::new(
118 vec![of_token.span.clone()],
119 OfOutsideSumProduct,
120 ));
121 }
122
123 let body = input.try_parse_with_state::<_, Expr>(|input| {
125 input.allow_of = false;
126 }).forward_errors(recoverable_errors)?;
127 let span = of_token.span.start..body.span().end;
128
129 Ok(Self {
130 expr: Box::new(body),
131 span,
132 of_span: of_token.span,
133 })
134 }
135}
136
137impl std::fmt::Display for Of {
138 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
139 write!(f, "of {}", self.expr)
140 }
141}
142
143impl Latex for Of {
144 fn fmt_latex(&self, f: &mut fmt::Formatter) -> fmt::Result {
145 write!(f, "\\text{{ of }}")?;
146 self.expr.fmt_latex(f)?;
147 Ok(())
148 }
149}