cas_parser/parser/ast/
stmt.rs1use crate::parser::{
2 ast::expr::Expr,
3 error::Error,
4 fmt::Latex,
5 token::Semicolon,
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)]
16#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
17pub struct Stmt {
18 pub expr: Expr,
20
21 pub semicolon: Option<Range<usize>>,
27
28 pub span: Range<usize>,
30}
31
32impl Stmt {
33 pub fn span(&self) -> Range<usize> {
35 self.span.clone()
36 }
37}
38
39impl<'source> Parse<'source> for Stmt {
40 fn std_parse(
41 input: &mut Parser<'source>,
42 recoverable_errors: &mut Vec<Error>
43 ) -> Result<Self, Vec<Error>> {
44 let expr = input.try_parse::<Expr>().forward_errors(recoverable_errors)?;
45 let semicolon = if let Ok(semi) = input.try_parse::<Semicolon>().forward_errors(recoverable_errors) {
46 Some(semi.span.clone())
47 } else {
48 None
49 };
50 let stmt_span = if let Some(semicolon) = &semicolon {
51 expr.span().start..semicolon.end
52 } else {
53 expr.span()
54 };
55
56 Ok(Stmt {
57 expr,
58 semicolon,
59 span: stmt_span,
60 })
61 }
62}
63
64impl std::fmt::Display for Stmt {
65 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
66 write!(f, "{}", self.expr)?;
67 if self.semicolon.is_some() {
68 write!(f, ";")?;
69 }
70 Ok(())
71 }
72}
73
74impl Latex for Stmt {
75 fn fmt_latex(&self, f: &mut fmt::Formatter) -> fmt::Result {
76 self.expr.fmt_latex(f)?;
77 if self.semicolon.is_some() {
78 write!(f, ";")?;
79 }
80 Ok(())
81 }
82}