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}