cas_parser/parser/ast/
block.rs1use cas_error::Error;
2use crate::parser::{
3 ast::stmt::Stmt,
4 error::UnclosedParenthesis,
5 fmt::Latex,
6 garbage::Garbage,
7 token::{CloseCurly, OpenCurly},
8 Parse,
9 Parser,
10};
11use std::{fmt, ops::Range};
12
13#[cfg(feature = "serde")]
14use serde::{Deserialize, Serialize};
15
16#[derive(Debug, Clone, PartialEq, Eq)]
19#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
20pub struct Block {
21 pub stmts: Vec<Stmt>,
23
24 pub span: Range<usize>,
26}
27
28impl Block {
29 pub fn span(&self) -> Range<usize> {
31 self.span.clone()
32 }
33}
34
35impl<'source> Parse<'source> for Block {
36 fn std_parse(
37 input: &mut Parser<'source>,
38 recoverable_errors: &mut Vec<Error>
39 ) -> Result<Self, Vec<Error>> {
40 let open_curly = input.try_parse::<OpenCurly>().forward_errors(recoverable_errors)?;
41 let mut stmts = Vec::new();
42 while let Ok(stmt) = input.try_parse().forward_errors(recoverable_errors) {
43 stmts.push(stmt);
44 }
45 let close_curly = input.try_parse::<CloseCurly>()
46 .forward_errors(recoverable_errors)
47 .unwrap_or_else(|_| {
48 recoverable_errors.push(Error::new(
49 vec![open_curly.span.clone()],
50 UnclosedParenthesis { opening: true },
51 ));
52
53 Garbage::garbage()
55 });
56 Ok(Self {
57 stmts,
58 span: open_curly.span.start..close_curly.span.end,
59 })
60 }
61}
62
63impl std::fmt::Display for Block {
64 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
65 write!(f, "{{")?;
66 for stmt in &self.stmts {
67 stmt.fmt(f)?;
68 }
69 write!(f, "}}")
70 }
71}
72
73impl Latex for Block {
74 fn fmt_latex(&self, f: &mut fmt::Formatter) -> fmt::Result {
75 write!(f, "{{")?;
76 for stmt in &self.stmts {
77 stmt.fmt_latex(f)?;
78 }
79 write!(f, "}}")
80 }
81}