cas_parser/parser/ast/
index.rs1use cas_error::Error;
2use crate::parser::{
3 ast::{expr::{Expr, Primary}, helper::Square},
4 fmt::Latex,
5 Parser,
6};
7use std::{fmt, ops::Range};
8
9#[cfg(feature = "serde")]
10use serde::{Deserialize, Serialize};
11
12#[derive(Debug, Clone, PartialEq, Eq)]
16#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
17pub struct Index {
18 pub target: Box<Expr>,
20
21 pub index: Box<Expr>,
23
24 pub span: Range<usize>,
26
27 pub bracket_span: Range<usize>,
29}
30
31impl Index {
32 pub fn span(&self) -> Range<usize> {
34 self.span.clone()
35 }
36
37 pub fn outer_span(&self) -> [Range<usize>; 2] {
40 [
41 self.target.span().start..self.bracket_span.start + 1,
42 self.bracket_span.end - 1..self.bracket_span.end,
43 ]
44 }
45
46 pub fn parse_or_lower(
57 input: &mut Parser,
58 recoverable_errors: &mut Vec<Error>,
59 mut target: Primary,
60 ) -> (Primary, bool) {
61 let mut changed = false;
62
63 while let Ok(surrounded) = input.try_parse::<Square<_>>().forward_errors(recoverable_errors) {
65 let span = target.span().start..surrounded.close.span.end;
66 target = Primary::Index(Self {
67 target: Box::new(target.into()),
68 index: Box::new(surrounded.value),
69 span,
70 bracket_span: surrounded.open.span.start..surrounded.close.span.end,
71 });
72 changed = true;
73 }
74
75 (target, changed)
76 }
77}
78
79impl std::fmt::Display for Index {
80 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
81 write!(f, "{}[{}]", self.target, self.index)
82 }
83}
84
85impl Latex for Index {
86 fn fmt_latex(&self, f: &mut fmt::Formatter) -> fmt::Result {
87 write!(f, "{}_{{{}}}", self.target, self.index)
88 }
89}