expr/ast/
node.rs

1use indexmap::IndexMap;
2use crate::ast::operator::Operator;
3use crate::ast::postfix_operator::PostfixOperator;
4use crate::ast::unary_operator::UnaryOperator;
5use crate::pratt::PRATT_PARSER;
6use crate::{Rule, Value};
7use log::trace;
8use pest::iterators::{Pair, Pairs};
9use crate::ast::program::Program;
10
11#[derive(Debug, Clone)]
12pub enum Node {
13    Ident(String),
14    Array(Vec<Node>),
15    Range(Box<Node>, Box<Node>),
16    Value(Value),
17    Func { ident: String, args: Vec<Node>, predicate: Option<Box<Program>> },
18    Unary {
19        operator: UnaryOperator,
20        node: Box<Node>,
21    },
22    Operation {
23        operator: Operator,
24        left: Box<Node>,
25        right: Box<Node>,
26    },
27    Postfix {
28        operator: PostfixOperator,
29        node: Box<Node>,
30    },
31}
32
33impl Default for Node {
34    fn default() -> Self {
35        Node::Value(Value::default())
36    }
37}
38
39impl From<Pairs<'_, Rule>> for Node {
40    fn from(pairs: Pairs<Rule>) -> Self {
41        PRATT_PARSER
42            .map_primary(|primary| primary.into())
43            .map_prefix(|operator, right| Node::Unary {
44                operator: operator.into(),
45                node: Box::new(right),
46            })
47            .map_postfix(|left, operator| Node::Postfix {
48                operator: operator.into(),
49                node: Box::new(left),
50            })
51            .map_infix(|left, operator, right| Node::Operation {
52                operator: operator.into(),
53                left: Box::new(left),
54                right: Box::new(right),
55            })
56            .parse(pairs)
57    }
58}
59
60impl From<Pair<'_, Rule>> for Node {
61    fn from(pair: Pair<Rule>) -> Self {
62        trace!("{:?} = {}", &pair.as_rule(), pair.as_str());
63        match pair.as_rule() {
64            Rule::expr => pair.into_inner().into(),
65            Rule::value => Node::Value(pair.into_inner().into()),
66            Rule::ident => Node::Ident(pair.as_str().to_string()),
67            Rule::func => {
68                let mut inner = pair.into_inner();
69                let ident = inner.next().unwrap().as_str().to_string();
70                let mut predicate = None;
71                let mut args = Vec::new();
72                for arg in inner {
73                    match arg.as_rule() {
74                        Rule::predicate => {
75                            predicate = Some(Box::new(arg.into_inner().into()));
76                        },
77                        _ => {
78                            args.push(arg.into());
79                        },
80                    }
81                }
82                Node::Func { ident, args, predicate }
83            },
84            Rule::array => Node::Array(pair.into_inner().map(|p| p.into()).collect()),
85            Rule::map => {
86                let mut map = IndexMap::new();
87                let vals = pair.clone();
88                for (key, val) in pair
89                    .into_inner()
90                    .step_by(2)
91                    .zip(vals.into_inner().skip(1).step_by(2))
92                {
93                    let key = key.as_str().to_string();
94                    map.insert(key, val.into_inner().into());
95                }
96                Node::Value(Value::Map(map))
97            }
98            Rule::range => {
99                let mut inner = pair.into_inner();
100                let start = Box::new(inner.next().unwrap().into());
101                let end = Box::new(inner.next().unwrap().into());
102                Node::Range(start, end)
103            }
104            rule => unreachable!("Unexpected rule: {rule:?}"),
105        }
106    }
107}