Skip to main content

asciimath_parser/
tree.rs

1//! The module containing all of the structures that defined a parsed representation of asciimath
2//!
3//! - [`Expression`] - A full expression containing a sequence of intermediate expressions
4//! - [`Intermediate`] - The most complicated single expression, this can be a high level fraction
5//! - [`Frac`] - A high level fraction, often parsed with a `/`
6//! - [`ScriptFunc`] - A scripted expression that can be a [`Func`] or just a simple expression
7//! - [`Func`] - A function like `sin` that can contain independent super- and subscripts
8//!   prior to its argument
9//! - [`SimpleScript`] - A simple expression that has super- and subscripts
10//! - [`Simple`] - A simple expression like a [`Symbol`][Simple::Symbol] or
11//!   [`Ident`][Simple::Ident]ifier
12//!
13//! The exceptions to this hierarchy are [`Group`] and [`Matrix`] that "reset" the hierarchy by
14//! wrapping expressions.
15use std::iter::FusedIterator;
16use std::ops::{Deref, Index};
17use std::slice::ChunksExact;
18
19/// A unary operator like "sqrt"
20#[derive(Debug, Clone, PartialEq, Eq)]
21pub struct SimpleUnary<'a> {
22    /// The operator name
23    pub op: &'a str,
24    /// The operator argument
25    arg: Box<Simple<'a>>,
26}
27
28impl<'a> SimpleUnary<'a> {
29    /// Create a unary with its op and argument
30    pub fn new<S>(op: &'a str, arg: S) -> Self
31    where
32        S: Into<Simple<'a>>,
33    {
34        SimpleUnary {
35            op,
36            arg: Box::new(arg.into()),
37        }
38    }
39
40    /// The operator argument
41    #[must_use]
42    pub fn arg(&self) -> &Simple<'a> {
43        &self.arg
44    }
45}
46
47/// A simple func like "sin"
48///
49/// When encountering a func keyword while parsing a simple context, it can't have attached power
50/// arguments or complicated arguments, but it will still be parsed as a unary function.
51#[derive(Debug, Clone, PartialEq, Eq)]
52pub struct SimpleFunc<'a> {
53    /// The function name
54    pub func: &'a str,
55    /// The function argument
56    arg: Box<Simple<'a>>,
57}
58
59impl<'a> SimpleFunc<'a> {
60    /// Create a simple function from its name and argument
61    pub fn new<S>(func: &'a str, arg: S) -> Self
62    where
63        S: Into<Simple<'a>>,
64    {
65        SimpleFunc {
66            func,
67            arg: Box::new(arg.into()),
68        }
69    }
70
71    /// The function argument
72    #[must_use]
73    pub fn arg(&self) -> &Simple<'a> {
74        &self.arg
75    }
76}
77
78#[derive(Debug, Clone, PartialEq, Eq)]
79/// A binary operator like "root"
80pub struct SimpleBinary<'a> {
81    /// The operator name
82    pub op: &'a str,
83    /// The first operator argument
84    first: Box<Simple<'a>>,
85    /// The second operator argument
86    second: Box<Simple<'a>>,
87}
88
89impl<'a> SimpleBinary<'a> {
90    /// Create a binary operator with its name and both arguments
91    pub fn new<F, S>(op: &'a str, first: F, second: S) -> Self
92    where
93        F: Into<Simple<'a>>,
94        S: Into<Simple<'a>>,
95    {
96        SimpleBinary {
97            op,
98            first: Box::new(first.into()),
99            second: Box::new(second.into()),
100        }
101    }
102
103    /// The first operator argument
104    #[must_use]
105    pub fn first(&self) -> &Simple<'a> {
106        &self.first
107    }
108
109    /// The second operator argument
110    #[must_use]
111    pub fn second(&self) -> &Simple<'a> {
112        &self.second
113    }
114}
115
116#[derive(Debug, Clone, PartialEq, Eq)]
117/// A bracketd group that allows inserting complicated expressions in simplex contexts
118///
119/// In some instances a bracket won't be parsed to close a group out, in that case the bracket will
120/// be the empty string.
121pub struct Group<'a> {
122    /// The left bracket
123    pub left_bracket: &'a str,
124    /// The grouped expression
125    pub expr: Expression<'a>,
126    /// The right bracket
127    pub right_bracket: &'a str,
128}
129
130impl<'a> Group<'a> {
131    /// Create a new group with two brackets and an expression
132    pub fn new<E: Into<Expression<'a>>>(
133        left_bracket: &'a str,
134        expr: E,
135        right_bracket: &'a str,
136    ) -> Self {
137        Group {
138            left_bracket,
139            expr: expr.into(),
140            right_bracket,
141        }
142    }
143
144    /// Create a new bracket with an iterable of intermediates instead of a fully formed expression
145    pub fn from_iter<T, I>(left_bracket: &'a str, inters: T, right_bracket: &'a str) -> Self
146    where
147        T: IntoIterator<Item = I>,
148        I: Into<Intermediate<'a>>,
149    {
150        Group {
151            left_bracket,
152            expr: inters.into_iter().collect(),
153            right_bracket,
154        }
155    }
156}
157
158/// A matrix e.g. "[[a, b], [x, y]]"
159///
160/// Individual expressions can be accessed with [rows][Matrix::rows] to get a random access iterator of row
161/// slices, or by indexing with a 2d array of indices, e.g. `matrix[[0, 0]]`
162#[derive(Debug, Clone, PartialEq, Eq)]
163pub struct Matrix<'a> {
164    /// The matrix's left bracket
165    pub left_bracket: &'a str,
166    /// The cells in the matrix in colum-wise order
167    cells: Box<[Expression<'a>]>,
168    /// The number of columns in the matrix
169    num_cols: usize,
170    /// The matrix's right bracket
171    pub right_bracket: &'a str,
172}
173
174impl<'a> Matrix<'a> {
175    /// Create a new matrix
176    ///
177    /// `cells` is a slice of expressiongs in row-major top-down order. `num_cols` is how many
178    /// columns exist in the final matrix.
179    ///
180    /// # Panics
181    /// When `cells.into().len()` is not divisible by `num_cols`.
182    pub fn new<E>(left_bracket: &'a str, cells: E, num_cols: usize, right_bracket: &'a str) -> Self
183    where
184        E: Into<Box<[Expression<'a>]>>,
185    {
186        let cells = cells.into();
187        assert_eq!(cells.len() / num_cols * num_cols, cells.len());
188        Matrix {
189            left_bracket,
190            cells,
191            num_cols,
192            right_bracket,
193        }
194    }
195
196    /// The number of columns
197    #[must_use]
198    pub fn num_cols(&self) -> usize {
199        self.num_cols
200    }
201
202    /// The number of rows
203    #[must_use]
204    pub fn num_rows(&self) -> usize {
205        self.cells.len() / self.num_cols
206    }
207
208    /// The number of total cells
209    #[must_use]
210    pub fn num_cells(&self) -> usize {
211        self.cells.len()
212    }
213
214    /// A top-down iterator over rows as slices
215    #[must_use]
216    pub fn rows(&self) -> MatrixRows<'a, '_> {
217        MatrixRows(self.cells.chunks_exact(self.num_cols))
218    }
219
220    /// A top-down iterator over rows as slices
221    #[must_use]
222    pub fn iter(&self) -> MatrixRows<'a, '_> {
223        self.into_iter()
224    }
225}
226
227/// Matrix references iterate over rows
228impl<'a, 'b> IntoIterator for &'b Matrix<'a> {
229    type IntoIter = MatrixRows<'a, 'b>;
230    type Item = &'b [Expression<'a>];
231
232    fn into_iter(self) -> Self::IntoIter {
233        self.rows()
234    }
235}
236
237/// usize indices get rows
238impl<'a> Index<usize> for Matrix<'a> {
239    type Output = [Expression<'a>];
240
241    /// Get an individual expression
242    ///
243    /// # Panics
244    /// When index is out of bounds `idx >= num_rows`
245    fn index(&self, row: usize) -> &Self::Output {
246        self.rows().nth(row).expect("index out of bounds")
247    }
248}
249
250/// 2D indices get individual expressions
251impl<'a> Index<[usize; 2]> for Matrix<'a> {
252    type Output = Expression<'a>;
253
254    /// Get an individual expression
255    ///
256    /// # Panics
257    /// When indices are out of bounds `[x, y]`, `x >= num_cols`, `y >= num_rows`
258    fn index(&self, idx: [usize; 2]) -> &Self::Output {
259        let [x, y] = idx;
260        assert!(x < self.num_cols, "index out of bounds");
261        &self.cells[x + self.num_cols * y]
262    }
263}
264
265/// An iterator over rows of a matrix
266#[derive(Debug, Clone)]
267pub struct MatrixRows<'a, 'b>(ChunksExact<'b, Expression<'a>>);
268
269impl<'a, 'b> Iterator for MatrixRows<'a, 'b> {
270    type Item = &'b [Expression<'a>];
271
272    fn next(&mut self) -> Option<Self::Item> {
273        self.0.next()
274    }
275
276    fn size_hint(&self) -> (usize, Option<usize>) {
277        self.0.size_hint()
278    }
279
280    fn count(self) -> usize {
281        self.len()
282    }
283
284    fn nth(&mut self, n: usize) -> Option<Self::Item> {
285        self.0.nth(n)
286    }
287
288    fn last(mut self) -> Option<Self::Item> {
289        self.next_back()
290    }
291}
292impl FusedIterator for MatrixRows<'_, '_> {}
293
294impl DoubleEndedIterator for MatrixRows<'_, '_> {
295    fn next_back(&mut self) -> Option<Self::Item> {
296        self.0.next_back()
297    }
298
299    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
300        self.0.nth_back(n)
301    }
302}
303
304impl ExactSizeIterator for MatrixRows<'_, '_> {}
305
306/// A simple element of parsing
307///
308/// This is the lowest level in the parse tree, but can be scaled back up with a group or matrix
309#[derive(Default, Debug, Clone, PartialEq, Eq)]
310pub enum Simple<'a> {
311    /// A missing expression
312    ///
313    /// This is found in places where something didn't exist, e.g. "sin" by itself will have a
314    /// missing argument, but still be parsed.
315    #[default]
316    Missing,
317    /// A raw number
318    Number(&'a str),
319    /// Raw text
320    Text(&'a str),
321    /// An identity, usually a single character of something that doesn't have asciimath meaning
322    Ident(&'a str),
323    /// A recognized symbol
324    Symbol(&'a str),
325    /// A unary operator
326    Unary(SimpleUnary<'a>),
327    /// A simple unary function
328    Func(SimpleFunc<'a>),
329    /// A binary function
330    Binary(SimpleBinary<'a>),
331    /// A bracketed group
332    Group(Group<'a>),
333    /// A matrix
334    Matrix(Matrix<'a>),
335}
336
337impl Simple<'_> {
338    /// Get as an option where Missing is None
339    #[must_use]
340    pub fn as_option(&self) -> Option<&Self> {
341        match self {
342            Simple::Missing => None,
343            simple => Some(simple),
344        }
345    }
346}
347
348// macro to derive from for component types
349macro_rules! simple_from {
350    ($from:ty => $to:ident) => {
351        impl<'a> From<$from> for Simple<'a> {
352            fn from(inp: $from) -> Self {
353                Simple::$to(inp)
354            }
355        }
356    };
357}
358
359simple_from!(SimpleUnary<'a> => Unary);
360simple_from!(SimpleFunc<'a> => Func);
361simple_from!(SimpleBinary<'a> => Binary);
362simple_from!(Group<'a> => Group);
363simple_from!(Matrix<'a> => Matrix);
364
365/// scripts attached to some other object
366///
367/// Note that an object can have a script attached, but the corresponding [Simple] expression can
368/// still be [missing][Simple::Missing]. Objects with Scripts Deref to them so these raw objects
369/// probably aren't necessary.
370#[derive(Default, Debug, Clone, PartialEq, Eq)]
371pub enum Script<'a> {
372    /// No super or subscripts
373    #[default]
374    None,
375    /// Only a subscript
376    Sub(Simple<'a>),
377    /// Only a superscript
378    Super(Simple<'a>),
379    /// A sub and superscript
380    Subsuper(Simple<'a>, Simple<'a>),
381}
382
383impl<'a> Script<'a> {
384    /// Get the subscript
385    #[must_use]
386    pub fn sub(&self) -> Option<&Simple<'a>> {
387        match self {
388            Script::Sub(sub) | Script::Subsuper(sub, _) => Some(sub),
389            _ => None,
390        }
391    }
392
393    /// Get the superscript
394    #[must_use]
395    pub fn sup(&self) -> Option<&Simple<'a>> {
396        match self {
397            Script::Super(sup) | Script::Subsuper(_, sup) => Some(sup),
398            _ => None,
399        }
400    }
401}
402
403/// A simple expressiong with attached scripts
404#[derive(Default, Debug, Clone, PartialEq, Eq)]
405pub struct SimpleScript<'a> {
406    /// The simple argument
407    pub simple: Simple<'a>,
408    /// Any script modifications
409    pub script: Script<'a>,
410}
411
412impl<'a> SimpleScript<'a> {
413    /// Create a new simple script with a simple and script
414    pub fn new<S>(simple: S, script: Script<'a>) -> Self
415    where
416        S: Into<Simple<'a>>,
417    {
418        SimpleScript {
419            simple: simple.into(),
420            script,
421        }
422    }
423
424    /// Create an unscripted simple expression
425    pub fn without_scripts<S>(simple: S) -> Self
426    where
427        S: Into<Simple<'a>>,
428    {
429        Self::new(simple, Script::None)
430    }
431
432    /// Create a simple script with a subscript
433    pub fn with_sub<S, Sub>(simple: S, sub: Sub) -> Self
434    where
435        S: Into<Simple<'a>>,
436        Sub: Into<Simple<'a>>,
437    {
438        Self::new(simple, Script::Sub(sub.into()))
439    }
440
441    /// Create a simple script with a super script
442    pub fn with_super<S, Sup>(simple: S, sup: Sup) -> Self
443    where
444        S: Into<Simple<'a>>,
445        Sup: Into<Simple<'a>>,
446    {
447        Self::new(simple, Script::Super(sup.into()))
448    }
449
450    /// Create a simple script with sub and super scripts
451    pub fn with_subsuper<S, Sub, Sup>(simple: S, sub: Sub, sup: Sup) -> Self
452    where
453        S: Into<Simple<'a>>,
454        Sub: Into<Simple<'a>>,
455        Sup: Into<Simple<'a>>,
456    {
457        Self::new(simple, Script::Subsuper(sub.into(), sup.into()))
458    }
459}
460
461impl<'a, S> From<S> for SimpleScript<'a>
462where
463    S: Into<Simple<'a>>,
464{
465    fn from(inp: S) -> Self {
466        SimpleScript::without_scripts(inp.into())
467    }
468}
469
470/// Add sub and super
471impl<'a> Deref for SimpleScript<'a> {
472    type Target = Script<'a>;
473
474    fn deref(&self) -> &Self::Target {
475        &self.script
476    }
477}
478
479/// A full function that has complicated arguments and attached scripts
480#[derive(Debug, Clone, PartialEq, Eq)]
481pub struct Func<'a> {
482    /// The function name
483    pub func: &'a str,
484    /// Any script modifications of the function
485    pub script: Script<'a>,
486    /// The function argument
487    arg: Box<ScriptFunc<'a>>,
488}
489
490impl<'a> Func<'a> {
491    /// Create a new function with all attached parts
492    pub fn new<Arg>(func: &'a str, script: Script<'a>, arg: Arg) -> Self
493    where
494        Arg: Into<ScriptFunc<'a>>,
495    {
496        Func {
497            func,
498            script,
499            arg: Box::new(arg.into()),
500        }
501    }
502
503    /// Create a new function without scripts
504    pub fn without_scripts<Arg>(func: &'a str, arg: Arg) -> Self
505    where
506        Arg: Into<ScriptFunc<'a>>,
507    {
508        Self::new(func, Script::None, arg)
509    }
510
511    /// Create a new function with subscripts
512    pub fn with_sub<Sub, Arg>(func: &'a str, sub: Sub, arg: Arg) -> Self
513    where
514        Sub: Into<Simple<'a>>,
515        Arg: Into<ScriptFunc<'a>>,
516    {
517        Self::new(func, Script::Sub(sub.into()), arg)
518    }
519
520    /// Create a new function with superscripts
521    pub fn with_super<Sup, Arg>(func: &'a str, sup: Sup, arg: Arg) -> Self
522    where
523        Sup: Into<Simple<'a>>,
524        Arg: Into<ScriptFunc<'a>>,
525    {
526        Self::new(func, Script::Super(sup.into()), arg)
527    }
528
529    /// Create a new function with sub and superscripts
530    pub fn with_subsuper<Sub, Sup, Arg>(func: &'a str, sub: Sub, sup: Sup, arg: Arg) -> Self
531    where
532        Sub: Into<Simple<'a>>,
533        Sup: Into<Simple<'a>>,
534        Arg: Into<ScriptFunc<'a>>,
535    {
536        Self::new(func, Script::Subsuper(sub.into(), sup.into()), arg)
537    }
538
539    /// The function argument
540    #[must_use]
541    pub fn arg(&self) -> &ScriptFunc<'a> {
542        &self.arg
543    }
544}
545
546impl<'a> Deref for Func<'a> {
547    type Target = Script<'a>;
548
549    fn deref(&self) -> &Self::Target {
550        &self.script
551    }
552}
553
554/// A scripted object or a scripted function
555#[derive(Debug, Clone, PartialEq, Eq)]
556pub enum ScriptFunc<'a> {
557    /// A scripted simple expression
558    Simple(SimpleScript<'a>),
559    /// A function with sub abd superscripts
560    Func(Func<'a>),
561}
562
563impl Default for ScriptFunc<'_> {
564    fn default() -> Self {
565        ScriptFunc::Simple(SimpleScript::default())
566    }
567}
568
569impl<'a> From<Func<'a>> for ScriptFunc<'a> {
570    fn from(func: Func<'a>) -> Self {
571        ScriptFunc::Func(func)
572    }
573}
574
575impl<'a, S> From<S> for ScriptFunc<'a>
576where
577    S: Into<SimpleScript<'a>>,
578{
579    fn from(inp: S) -> Self {
580        ScriptFunc::Simple(inp.into())
581    }
582}
583
584/// A high level fraction
585#[derive(Debug, Clone, PartialEq, Eq)]
586pub struct Frac<'a> {
587    /// The numerator
588    pub numer: ScriptFunc<'a>,
589    /// The denominator
590    pub denom: ScriptFunc<'a>,
591}
592
593impl<'a> Frac<'a> {
594    /// Create a high level fraction
595    pub fn new<N, D>(numer: N, denom: D) -> Self
596    where
597        N: Into<ScriptFunc<'a>>,
598        D: Into<ScriptFunc<'a>>,
599    {
600        Frac {
601            numer: numer.into(),
602            denom: denom.into(),
603        }
604    }
605}
606
607/// An intermediate expression
608#[derive(Debug, Clone, PartialEq, Eq)]
609pub enum Intermediate<'a> {
610    /// A simple scripted object
611    ScriptFunc(ScriptFunc<'a>),
612    /// A fraction between scripted objects
613    Frac(Frac<'a>),
614}
615
616impl Default for Intermediate<'_> {
617    fn default() -> Self {
618        Intermediate::ScriptFunc(ScriptFunc::default())
619    }
620}
621
622impl<'a> From<Frac<'a>> for Intermediate<'a> {
623    fn from(frac: Frac<'a>) -> Self {
624        Intermediate::Frac(frac)
625    }
626}
627
628impl<'a, S> From<S> for Intermediate<'a>
629where
630    S: Into<ScriptFunc<'a>>,
631{
632    fn from(inp: S) -> Self {
633        Intermediate::ScriptFunc(inp.into())
634    }
635}
636
637/// A full expression
638///
639/// This is a sequence of intermediate expressions and Derefs to a slice of them.
640#[derive(Default, Debug, Clone, PartialEq, Eq)]
641pub struct Expression<'a>(Box<[Intermediate<'a>]>);
642
643impl<'a> Deref for Expression<'a> {
644    type Target = [Intermediate<'a>];
645
646    fn deref(&self) -> &Self::Target {
647        &self.0
648    }
649}
650
651impl<'a, I> FromIterator<I> for Expression<'a>
652where
653    I: Into<Intermediate<'a>>,
654{
655    fn from_iter<T>(iter: T) -> Self
656    where
657        T: IntoIterator<Item = I>,
658    {
659        Expression(iter.into_iter().map(std::convert::Into::into).collect())
660    }
661}
662
663impl<'a, B> From<B> for Expression<'a>
664where
665    B: Into<Box<[Intermediate<'a>]>>,
666{
667    fn from(inp: B) -> Self {
668        Expression(inp.into())
669    }
670}