zen_parser/parser/unary/
mod.rs

1use bumpalo::Bump;
2
3use crate::ast::Node;
4use crate::lexer::token::{Token, TokenKind};
5use crate::parser::definitions::{Arity, Associativity};
6use crate::parser::error::{ParserError, ParserResult};
7use crate::parser::iter::ParserIterator;
8use crate::parser::unary::constants::{BUILT_INS, OPERATORS};
9
10mod constants;
11
12pub struct UnaryParser<'a, 'b>
13where
14    'b: 'a,
15{
16    iterator: ParserIterator<'a, 'b>,
17    bump: &'b Bump,
18}
19
20const MAIN_NODE: Node<'static> = Node::Identifier("$");
21
22impl<'a, 'b> UnaryParser<'a, 'b>
23where
24    'b: 'a,
25{
26    pub fn try_new(tokens: &'a Vec<Token>, bump: &'b Bump) -> ParserResult<Self> {
27        Ok(Self {
28            iterator: ParserIterator::try_new(tokens, bump)?,
29            bump,
30        })
31    }
32
33    pub fn parse(&self) -> ParserResult<&'b Node<'b>> {
34        self.parse_expression(0, true)
35    }
36
37    fn parse_expression(&self, precedence: u8, root: bool) -> ParserResult<&'b Node<'b>> {
38        let mut node_left: &'b Node<'b> = self.iterator.node(MAIN_NODE)?;
39        let mut token = self.iterator.current();
40
41        while !self.iterator.is_done() {
42            match token.kind {
43                TokenKind::Operator => {
44                    if token.value == "," {
45                        self.iterator.next()?;
46                        let node_right: &'b Node<'b> = self.parse_expression(0, true)?;
47
48                        token = self.iterator.current();
49                        node_left = self.iterator.node(Node::Binary {
50                            left: node_left,
51                            operator: "or",
52                            right: node_right,
53                        })?;
54                        continue;
55                    } else if let Some(op) = OPERATORS.get(token.value) {
56                        if op.precedence >= precedence {
57                            self.iterator.next()?;
58                            let node_right = match op.associativity {
59                                Associativity::Left => {
60                                    self.parse_expression(op.precedence + 1, false)?
61                                }
62                                Associativity::Right => {
63                                    self.parse_expression(op.precedence, false)?
64                                }
65                            };
66
67                            node_left = self.iterator.node(Node::Binary {
68                                left: node_left,
69                                operator: self.iterator.str_value(token.value),
70                                right: node_right,
71                            })?;
72                            token = self.iterator.current();
73                            continue;
74                        }
75                    }
76                }
77                TokenKind::Identifier | TokenKind::String | TokenKind::Number => {
78                    let node_right = self.parse_primary()?;
79                    if !root {
80                        return Ok(node_right);
81                    }
82
83                    token = self.iterator.current();
84                    node_left = self.iterator.node(Node::Binary {
85                        left: node_left,
86                        operator: "==",
87                        right: node_right,
88                    })?;
89                    continue;
90                }
91                TokenKind::Bracket => {
92                    let node_right: &Node;
93
94                    if let Some(interval) = self.parse_interval(node_left)? {
95                        node_left = interval;
96                    } else if token.value == "[" {
97                        let should_wrap = !self.iterator.lookup_back(
98                            1,
99                            TokenKind::Operator,
100                            Some(&["not in", "in"]),
101                        );
102                        node_right = self.parse_array(token)?;
103
104                        if should_wrap {
105                            node_left = self.iterator.node(Node::Binary {
106                                left: node_left,
107                                right: node_right,
108                                operator: "in",
109                            })?;
110                        } else {
111                            node_left = node_right;
112                        }
113                    }
114                    continue;
115                }
116            }
117        }
118
119        Ok(node_left)
120    }
121
122    fn parse_interval(&self, node: &'b Node<'b>) -> ParserResult<Option<&'b Node<'b>>> {
123        let current_token = self.iterator.current();
124        if current_token.kind != TokenKind::Bracket {
125            return Ok(None);
126        }
127
128        if !self.iterator.lookup(2, TokenKind::Operator, Some(&[".."])) {
129            return Ok(None);
130        }
131
132        let should_wrap =
133            !self
134                .iterator
135                .lookup_back(1, TokenKind::Operator, Some(&["not in", "in"]));
136
137        let left_bracket = self.iterator.current().value;
138        self.iterator.expect(TokenKind::Bracket, None)?;
139        let left = self.parse_primary()?;
140        self.iterator.expect(TokenKind::Operator, Some(&[".."]))?;
141        let right = self.parse_primary()?;
142        let right_bracket = self.iterator.current().value;
143        self.iterator.expect(TokenKind::Bracket, None)?;
144
145        let interval_node = self.iterator.node(Node::Interval {
146            left,
147            left_bracket: self.iterator.str_value(left_bracket),
148            right,
149            right_bracket: self.iterator.str_value(right_bracket),
150        })?;
151
152        if should_wrap {
153            return Ok(Some(self.iterator.node(Node::Binary {
154                left: node,
155                right: interval_node,
156                operator: "in",
157            })?));
158        }
159
160        Ok(Some(interval_node))
161    }
162
163    fn parse_array(&self, _token: &Token) -> ParserResult<&'b Node<'b>> {
164        let mut nodes = Vec::new();
165
166        self.iterator.expect(TokenKind::Bracket, Some(&["["]))?;
167        while self.iterator.current().kind != TokenKind::Bracket
168            && self.iterator.current().value != "]"
169        {
170            if !nodes.is_empty() {
171                self.iterator.expect(TokenKind::Operator, Some(&[","]))?;
172                if self.iterator.current().value == "]" {
173                    break;
174                }
175            }
176
177            nodes.push(self.parse_primary()?);
178        }
179
180        self.iterator.expect(TokenKind::Bracket, Some(&["]"]))?;
181        let node = Node::Array(self.bump.alloc_slice_copy(nodes.as_slice()));
182        self.iterator.node(node)
183    }
184
185    fn parse_primary(&self) -> ParserResult<&'b Node<'b>> {
186        let token = self.iterator.current();
187
188        match token.kind {
189            TokenKind::Identifier => {
190                self.iterator.next()?;
191                match token.value {
192                    "true" | "false" => self.iterator.bool(token),
193                    "null" => self.iterator.null(token),
194                    _ => self.parse_prebuilt(token),
195                }
196            }
197            TokenKind::Number => self.iterator.number(token),
198            TokenKind::String => self.iterator.string(token),
199            _ => Err(ParserError::UnexpectedToken {
200                expected: "one of [identifier, number, string]".to_string(),
201                received: format!("{:?}", token.kind),
202            }),
203        }
204    }
205
206    fn parse_prebuilt(&self, token: &Token<'a>) -> ParserResult<&'b Node<'b>> {
207        let current_token = self.iterator.current();
208        let valid_token = current_token.kind == TokenKind::Bracket && current_token.value == "(";
209
210        if !valid_token {
211            return Err(ParserError::UnknownBuiltIn {
212                token: token.value.to_string(),
213            });
214        }
215
216        let built_in = BUILT_INS
217            .get(token.value)
218            .ok_or_else(|| ParserError::UnknownBuiltIn {
219                token: token.value.to_string(),
220            })?;
221
222        self.iterator.expect(TokenKind::Bracket, Some(&["("]))?;
223
224        match built_in.arity {
225            Arity::Single => {
226                let arg = self.parse_primary()?;
227                let node = self.iterator.node(Node::BuiltIn {
228                    name: self.iterator.str_value(token.value),
229                    arguments: self.bump.alloc_slice_copy(&[arg]),
230                })?;
231
232                self.iterator.expect(TokenKind::Bracket, Some(&[")"]))?;
233
234                Ok(node)
235            }
236            _ => Err(ParserError::UnsupportedBuiltIn {
237                token: token.value.to_string(),
238            }),
239        }
240    }
241}