cas_parser/parser/ast/
paren.rs1use cas_error::Error;
2use crate::parser::{
3 ast::expr::Expr,
4 error::UnclosedParenthesis,
5 fmt::Latex,
6 garbage::Garbage,
7 token::{CloseParen, OpenParen},
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)]
18#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
19pub struct Paren {
20 pub expr: Box<Expr>,
22
23 pub span: Range<usize>,
25}
26
27impl Paren {
28 pub fn span(&self) -> Range<usize> {
30 self.span.clone()
31 }
32
33 pub fn innermost(&self) -> &Expr {
35 let mut inner = &self.expr;
36 while let Expr::Paren(paren) = inner.as_ref() {
37 inner = &paren.expr;
38 }
39 inner
40 }
41
42 pub fn into_innermost(self) -> Expr {
44 let mut inner = self.expr;
45 while let Expr::Paren(paren) = *inner {
46 inner = paren.expr;
47 }
48 *inner
49 }
50}
51
52impl<'source> Parse<'source> for Paren {
53 fn std_parse(
54 input: &mut Parser<'source>,
55 recoverable_errors: &mut Vec<Error>
56 ) -> Result<Self, Vec<Error>> {
57 let open_paren = input.try_parse::<OpenParen>().forward_errors(recoverable_errors)?;
58 let expr = input.try_parse().forward_errors(recoverable_errors)?;
59 let close_paren = input.try_parse::<CloseParen>()
60 .forward_errors(recoverable_errors)
61 .unwrap_or_else(|_| {
62 recoverable_errors.push(Error::new(
63 vec![open_paren.span.clone()],
64 UnclosedParenthesis { opening: true },
65 ));
66
67 Garbage::garbage()
69 });
70 Ok(Self {
71 expr: Box::new(expr),
72 span: open_paren.span.start..close_paren.span.end,
73 })
74 }
75}
76
77impl std::fmt::Display for Paren {
78 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
79 write!(f, "(")?;
80 self.expr.fmt(f)?;
81 write!(f, ")")
82 }
83}
84
85impl Latex for Paren {
86 fn fmt_latex(&self, f: &mut fmt::Formatter) -> fmt::Result {
87 write!(f, "\\left(")?;
88 self.expr.fmt_latex(f)?;
89 write!(f, "\\right)")
90 }
91}