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