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