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