polymath_rs/ast/
predictive.rs

1//!
2//! This module is used to convert the PredictiveCST into an AST
3//!
4
5use std::collections::VecDeque;
6
7use crate::{
8    cst::predictive::{
9        Expression as CSTExpression, IntermediateExpression, PredictiveCST, SimpleExpression,
10    },
11    tokens::Token,
12};
13
14use super::{
15    BiExpression, Binary, Expression, Expressions, Group, Literal, TriExpression, Unary, AST,
16};
17
18pub fn convert<'a>(cst: &'a PredictiveCST<'a>) -> AST<'a> {
19    AST {
20        expressions: convert_e(&cst.expression),
21    }
22}
23
24fn convert_e<'a>(expression: &CSTExpression<'a>) -> Expressions<'a> {
25    let mut expressions = VecDeque::new();
26
27    match &expression {
28        CSTExpression::IE(left, right) => {
29            expressions.append(&mut convert_ie(left, right).expressions);
30        }
31        CSTExpression::II(left, _, right) => {
32            let mut right_expressions = convert_e(right);
33
34            expressions.push_back(Expression::Frac(BiExpression {
35                expression_1: Box::new(convert_i(left)),
36                expression_2: Box::new(right_expressions.expressions.pop_front().unwrap()),
37            }));
38
39            expressions.append(&mut right_expressions.expressions);
40        }
41        CSTExpression::Unit => {}
42    };
43
44    Expressions { expressions }
45}
46
47fn convert_ie<'a>(left: &IntermediateExpression<'a>, right: &CSTExpression<'a>) -> Expressions<'a> {
48    let left = convert_i(left);
49    let mut expressions = VecDeque::new();
50    let mut right = convert_e(right);
51
52    expressions.push_back(left);
53    expressions.append(&mut right.expressions);
54
55    Expressions { expressions }
56}
57
58fn convert_i<'a>(expr: &IntermediateExpression<'a>) -> Expression<'a> {
59    match expr {
60        IntermediateExpression::SimpleSub(s1, _, s2) => Expression::Sub(BiExpression {
61            expression_1: Box::new(convert_simple(s1)),
62            expression_2: Box::new(convert_simple(s2)),
63        }),
64        IntermediateExpression::SimpleSup(s1, _, s2) => Expression::Pow(BiExpression {
65            expression_1: Box::new(convert_simple(s1)),
66            expression_2: Box::new(convert_simple(s2)),
67        }),
68        IntermediateExpression::SimpleSubSup(s1, _, s2, _, s3) => {
69            Expression::SubPow(TriExpression {
70                expression_1: Box::new(convert_simple(s1)),
71                expression_2: Box::new(convert_simple(s2)),
72                expression_3: Box::new(convert_simple(s3)),
73            })
74        }
75        IntermediateExpression::Simple(simple) => convert_simple(simple),
76    }
77}
78
79fn convert_simple<'a>(expr: &SimpleExpression<'a>) -> Expression<'a> {
80    match expr {
81        SimpleExpression::Symbol(symbol) => Expression::Literal(convert_literal(symbol)),
82        SimpleExpression::Group(l_brace, expr, r_brace) => Expression::Group(Group {
83            l_brace: l_brace.to_owned(),
84            expressions: convert_e(expr),
85            r_brace: r_brace.to_owned(),
86        }),
87        SimpleExpression::UnarySymbol(operator, e) => Expression::Unary(Unary {
88            operator: operator.clone(),
89            expression: Box::new(convert_simple(e.as_ref())),
90        }),
91        SimpleExpression::BinarySymbol(operator, e, e1) => Expression::Binary(Binary {
92            operator: operator.clone(),
93            expression_1: Box::new(convert_simple(e)),
94            expression_2: Box::new(convert_simple(e1)),
95        }),
96    }
97}
98
99fn convert_literal<'a>(literal: &Token<'a>) -> Literal<'a> {
100    Literal::Literal(literal.to_owned())
101}