Skip to main content

exprkit/
parser.rs

1use crate::{
2    ast::{Node, Op},
3    tokenizer::{Token, Tokenizer},
4};
5
6#[derive(Debug, PartialEq)]
7pub enum ParserError {
8    UnexpectedToken(Token),
9    MismatchedParentheses,
10    InvalidExpression,
11}
12
13#[allow(dead_code)]
14#[derive(PartialEq, PartialOrd)]
15enum Precedence {
16    None,
17    Assignment, // =
18    Or,         // or
19    And,        // and
20    Equality,   // == !=
21    Comparison, // < > <= >=
22    Term,       // + -
23    Factor,     // * /
24    Exponent,   // ^
25    Unary,      // - !
26    Call,       // .
27}
28
29fn get_precedence(token: &Token) -> Precedence {
30    match token {
31        Token::Assignment
32        | Token::PlusEqual
33        | Token::MinusEqual
34        | Token::AsteriskEqual
35        | Token::SlashEqual
36        | Token::PercentEqual
37        | Token::Swap => Precedence::Assignment,
38        Token::Or | Token::Pipe => Precedence::Or,
39        Token::Nor | Token::Xor | Token::Xnor => Precedence::Or,
40        Token::Equal | Token::NotEqual => Precedence::Equality,
41        Token::LessThan
42        | Token::LessThanOrEqual
43        | Token::GreaterThan
44        | Token::GreaterThanOrEqual
45        | Token::In
46        | Token::Like
47        | Token::Ilike => Precedence::Comparison,
48        Token::And => Precedence::And,
49        Token::Nand => Precedence::And,
50        Token::Ampersand => Precedence::And,
51        Token::Caret => Precedence::Exponent,
52        Token::Plus | Token::Minus => Precedence::Term,
53        Token::Asterisk | Token::Slash | Token::Percent => Precedence::Factor,
54        Token::LParen | Token::LBracket => Precedence::Call,
55        _ => Precedence::None,
56    }
57}
58
59fn implicit_mul_token(token: &Token) -> bool {
60    matches!(
61        token,
62        Token::Number(_)
63            | Token::Symbol(_)
64            | Token::StringLiteral(_)
65            | Token::LParen
66            | Token::LBrace
67    )
68}
69
70fn is_value_node(node: &Node) -> bool {
71    matches!(
72        node,
73        Node::Number(_)
74            | Node::Null
75            | Node::Variable(_)
76            | Node::ArrayLiteral(_)
77            | Node::BracketArrayLiteral(_)
78            | Node::RangeLiteral { .. }
79            | Node::StringLiteral(_)
80            | Node::Index { .. }
81            | Node::ArraySize(_)
82            | Node::UnaryOp(_, _)
83            | Node::BinaryOp(_, _, _)
84            | Node::Function(_, _)
85            | Node::Ternary { .. }
86            | Node::Block(_)
87    )
88}
89
90pub struct Parser<'a, T> {
91    tokenizer: Tokenizer<'a>,
92    current_token: Token,
93    _marker: std::marker::PhantomData<T>,
94}
95
96impl<'a, T> Parser<'a, T> {
97    pub fn new(expression_string: &'a str) -> Self {
98        let mut tokenizer = Tokenizer::new(expression_string);
99        let current_token = tokenizer.next_token();
100        Self {
101            tokenizer,
102            current_token,
103            _marker: std::marker::PhantomData,
104        }
105    }
106
107    fn advance(&mut self) {
108        self.current_token = self.tokenizer.next_token();
109    }
110
111    pub fn parse(&mut self) -> Result<Node, ParserError> {
112        let mut statements = Vec::new();
113        while self.current_token != Token::Eof {
114            if self.current_token == Token::Semicolon {
115                self.advance();
116                continue;
117            }
118            statements.push(self.parse_statement()?);
119        }
120        match statements.len() {
121            0 => Ok(Node::Number(0.0)),
122            1 => Ok(statements.into_iter().next().unwrap()),
123            _ => Ok(Node::Block(statements)),
124        }
125    }
126
127    fn parse_statement(&mut self) -> Result<Node, ParserError> {
128        match self.current_token {
129            Token::Const => self.parse_const_var_declaration(),
130            Token::Function => self.parse_function_declaration(),
131            Token::Switch => self.parse_switch_statement(),
132            Token::While => self.parse_while_statement(),
133            Token::For => self.parse_for_loop(),
134            Token::Repeat => self.parse_repeat_statement(),
135            Token::Break => self.parse_break_statement(),
136            Token::Continue => self.parse_continue_statement(),
137            Token::Return => self.parse_return_statement(),
138            Token::Var => self.parse_var_declaration(),
139            Token::Else => Err(ParserError::UnexpectedToken(self.current_token.clone())),
140            _ => {
141                let expr = self.parse_expression(Precedence::None)?;
142                if self.current_token == Token::Semicolon {
143                    self.advance();
144                }
145                Ok(expr)
146            }
147        }
148    }
149
150    fn parse_const_var_declaration(&mut self) -> Result<Node, ParserError> {
151        self.advance(); // consume 'const'
152        if self.current_token != Token::Var {
153            return Err(ParserError::InvalidExpression);
154        }
155        self.advance(); // consume 'var'
156
157        let name = if let Token::Symbol(name) = self.current_token.clone() {
158            name
159        } else {
160            return Err(ParserError::InvalidExpression);
161        };
162        self.advance();
163
164        if self.current_token == Token::LBracket {
165            return Err(ParserError::InvalidExpression);
166        }
167
168        if self.current_token != Token::Assignment {
169            return Err(ParserError::InvalidExpression);
170        }
171        self.advance();
172        let expr = self.parse_expression(Precedence::None)?;
173        if self.current_token == Token::Semicolon {
174            self.advance();
175        }
176        Ok(Node::ConstVar {
177            name,
178            expr: Box::new(expr),
179        })
180    }
181
182    fn parse_function_declaration(&mut self) -> Result<Node, ParserError> {
183        self.advance(); // consume 'function'
184        let name = if let Token::Symbol(name) = self.current_token.clone() {
185            name
186        } else {
187            return Err(ParserError::InvalidExpression);
188        };
189        self.advance();
190
191        if self.current_token != Token::LParen {
192            return Err(ParserError::MismatchedParentheses);
193        }
194        self.advance();
195
196        let mut params = Vec::new();
197        if self.current_token != Token::RParen {
198            loop {
199                if let Token::Symbol(param) = self.current_token.clone() {
200                    params.push(param);
201                    self.advance();
202                } else {
203                    return Err(ParserError::InvalidExpression);
204                }
205                if self.current_token == Token::Comma {
206                    self.advance();
207                } else {
208                    break;
209                }
210            }
211        }
212        if self.current_token != Token::RParen {
213            return Err(ParserError::MismatchedParentheses);
214        }
215        self.advance();
216
217        if self.current_token != Token::Assignment {
218            return Err(ParserError::InvalidExpression);
219        }
220        self.advance();
221
222        let body = if self.current_token == Token::LBrace {
223            self.parse_block()?
224        } else {
225            self.parse_expression(Precedence::None)?
226        };
227
228        if self.current_token == Token::Semicolon {
229            self.advance();
230        }
231
232        Ok(Node::FunctionDecl {
233            name,
234            params,
235            body: Box::new(body),
236        })
237    }
238
239    fn parse_for_loop(&mut self) -> Result<Node, ParserError> {
240        self.advance(); // consume 'for'
241        if self.current_token != Token::LParen {
242            return Err(ParserError::MismatchedParentheses);
243        }
244        self.advance(); // consume '('
245        let init = self.parse_statement()?;
246        let cond = self.parse_statement()?;
247        let incr = if self.current_token == Token::RParen {
248            Node::Number(0.0)
249        } else {
250            self.parse_expression(Precedence::None)?
251        };
252        if self.current_token != Token::RParen {
253            return Err(ParserError::MismatchedParentheses);
254        }
255        self.advance(); // consume ')'
256        let body = self.parse_statement()?;
257        Ok(Node::For(
258            Box::new(init),
259            Box::new(cond),
260            Box::new(incr),
261            Box::new(body),
262        ))
263    }
264
265    fn parse_repeat_statement(&mut self) -> Result<Node, ParserError> {
266        self.advance(); // consume 'repeat'
267        let mut stmts = Vec::new();
268        while self.current_token != Token::Until && self.current_token != Token::Eof {
269            stmts.push(self.parse_statement()?);
270        }
271        let body = if stmts.len() == 1 {
272            stmts.pop().unwrap()
273        } else {
274            Node::Block(stmts)
275        };
276        if self.current_token != Token::Until {
277            return Err(ParserError::InvalidExpression);
278        }
279        self.advance();
280        let condition = if self.current_token == Token::LParen {
281            self.advance();
282            let cond = self.parse_expression(Precedence::None)?;
283            if self.current_token != Token::RParen {
284                return Err(ParserError::MismatchedParentheses);
285            }
286            self.advance();
287            cond
288        } else {
289            self.parse_expression(Precedence::None)?
290        };
291        if self.current_token == Token::Semicolon {
292            self.advance();
293        }
294        Ok(Node::Repeat {
295            body: Box::new(body),
296            condition: Box::new(condition),
297        })
298    }
299
300    fn parse_if_branch(&mut self) -> Result<Node, ParserError> {
301        match self.current_token {
302            Token::LBrace => self.parse_block(),
303            Token::Break
304            | Token::Continue
305            | Token::Return
306            | Token::Const
307            | Token::Function
308            | Token::Var
309            | Token::Switch
310            | Token::While
311            | Token::For
312            | Token::Repeat => self.parse_statement(),
313            Token::If => self.parse_if_expression(),
314            _ => {
315                let expr = self.parse_expression(Precedence::None)?;
316                if self.current_token == Token::Semicolon {
317                    self.advance();
318                }
319                Ok(expr)
320            }
321        }
322    }
323
324    fn parse_if_expression(&mut self) -> Result<Node, ParserError> {
325        self.advance(); // consume 'if'
326        if self.current_token != Token::LParen {
327            return Err(ParserError::MismatchedParentheses);
328        }
329        self.advance();
330        let condition = self.parse_expression(Precedence::None)?;
331        if self.current_token == Token::Comma {
332            let mut args = vec![condition];
333            loop {
334                self.advance();
335                args.push(self.parse_expression(Precedence::None)?);
336                if self.current_token == Token::Comma {
337                    continue;
338                }
339                break;
340            }
341            if self.current_token != Token::RParen {
342                return Err(ParserError::MismatchedParentheses);
343            }
344            self.advance();
345            return Ok(Node::Function("if".to_string(), args));
346        }
347        if self.current_token != Token::RParen {
348            return Err(ParserError::MismatchedParentheses);
349        }
350        self.advance();
351        let then_branch = self.parse_if_branch()?;
352        let else_branch = if self.current_token == Token::Else {
353            self.advance();
354            Some(Box::new(self.parse_if_branch()?))
355        } else {
356            None
357        };
358        Ok(Node::If {
359            condition: Box::new(condition),
360            then_branch: Box::new(then_branch),
361            else_branch,
362        })
363    }
364
365    fn parse_while_statement(&mut self) -> Result<Node, ParserError> {
366        self.advance(); // consume 'while'
367        if self.current_token != Token::LParen {
368            return Err(ParserError::MismatchedParentheses);
369        }
370        self.advance();
371        let condition = self.parse_expression(Precedence::None)?;
372        if self.current_token != Token::RParen {
373            return Err(ParserError::MismatchedParentheses);
374        }
375        self.advance();
376        let body = self.parse_statement()?;
377        Ok(Node::While {
378            condition: Box::new(condition),
379            body: Box::new(body),
380        })
381    }
382
383    fn parse_break_statement(&mut self) -> Result<Node, ParserError> {
384        self.advance(); // consume 'break'
385        let expr = if self.current_token == Token::LBracket {
386            self.advance();
387            let inner = self.parse_expression(Precedence::None)?;
388            if self.current_token != Token::RBracket {
389                return Err(ParserError::MismatchedParentheses);
390            }
391            self.advance();
392            Some(Box::new(inner))
393        } else {
394            None
395        };
396        if self.current_token == Token::Semicolon {
397            self.advance();
398        }
399        Ok(Node::Break(expr))
400    }
401
402    fn parse_continue_statement(&mut self) -> Result<Node, ParserError> {
403        self.advance(); // consume 'continue'
404        if self.current_token == Token::Semicolon {
405            self.advance();
406        }
407        Ok(Node::Continue)
408    }
409
410    fn parse_return_statement(&mut self) -> Result<Node, ParserError> {
411        self.advance(); // consume 'return'
412        let expr = match self.current_token {
413            Token::Semicolon | Token::RBrace => None,
414            _ => Some(Box::new(self.parse_expression(Precedence::None)?)),
415        };
416        if self.current_token == Token::Semicolon {
417            self.advance();
418        }
419        Ok(Node::Return(expr))
420    }
421
422    fn parse_switch_statement(&mut self) -> Result<Node, ParserError> {
423        self.advance(); // consume 'switch'
424        self.parse_switch_body()
425    }
426
427    fn parse_switch_body(&mut self) -> Result<Node, ParserError> {
428        if self.current_token != Token::LBrace {
429            return Err(ParserError::InvalidExpression);
430        }
431        self.advance();
432
433        let mut cases = Vec::new();
434        let mut default_case: Option<Box<Node>> = None;
435
436        while self.current_token != Token::RBrace && self.current_token != Token::Eof {
437            match self.current_token {
438                Token::Case => {
439                    self.advance();
440                    let condition = self.parse_expression(Precedence::None)?;
441                    if self.current_token != Token::Colon {
442                        return Err(ParserError::InvalidExpression);
443                    }
444                    self.advance();
445                    let statement = self.parse_statement()?;
446                    cases.push((condition, statement));
447                }
448                Token::Default => {
449                    self.advance();
450                    if self.current_token != Token::Colon {
451                        return Err(ParserError::InvalidExpression);
452                    }
453                    self.advance();
454                    let statement = self.parse_statement()?;
455                    default_case = Some(Box::new(statement));
456                }
457                Token::Semicolon => {
458                    self.advance();
459                }
460                _ => return Err(ParserError::InvalidExpression),
461            }
462        }
463
464        if self.current_token != Token::RBrace {
465            return Err(ParserError::MismatchedParentheses);
466        }
467        self.advance();
468        if self.current_token == Token::Semicolon {
469            self.advance();
470        }
471
472        Ok(Node::Switch {
473            cases,
474            default: default_case,
475        })
476    }
477
478    fn parse_var_declaration(&mut self) -> Result<Node, ParserError> {
479        self.advance(); // consume 'var'
480        let name = if let Token::Symbol(name) = self.current_token.clone() {
481            name
482        } else {
483            return Err(ParserError::InvalidExpression);
484        };
485        self.advance();
486
487        let mut array_size: Option<Box<Node>> = None;
488        let mut is_array = false;
489
490        if self.current_token == Token::LBracket {
491            is_array = true;
492            self.advance();
493            if self.current_token != Token::RBracket {
494                array_size = Some(Box::new(self.parse_expression(Precedence::None)?));
495            }
496            if self.current_token != Token::RBracket {
497                return Err(ParserError::MismatchedParentheses);
498            }
499            self.advance();
500        }
501
502        match self.current_token {
503            Token::Assignment => {
504                self.advance();
505                if is_array && self.current_token == Token::LBrace {
506                    let literal = self.parse_array_literal_from_brace()?;
507                    if self.current_token == Token::Semicolon {
508                        self.advance();
509                    }
510                    Ok(Node::ArrayDeclaration {
511                        name,
512                        size: array_size,
513                        initializer: Some(Box::new(literal)),
514                    })
515                } else {
516                    let expr = self.parse_expression(Precedence::None)?;
517                    if self.current_token == Token::Semicolon {
518                        self.advance();
519                    }
520                    if is_array {
521                        Ok(Node::ArrayDeclaration {
522                            name,
523                            size: array_size,
524                            initializer: Some(Box::new(expr)),
525                        })
526                    } else {
527                        Ok(Node::Assignment(
528                            Box::new(Node::Variable(name)),
529                            Box::new(expr),
530                        ))
531                    }
532                }
533            }
534            _ => {
535                if self.current_token == Token::Semicolon {
536                    self.advance();
537                }
538                if is_array {
539                    Ok(Node::ArrayDeclaration {
540                        name,
541                        size: array_size,
542                        initializer: None,
543                    })
544                } else {
545                    Ok(Node::Var(name))
546                }
547            }
548        }
549    }
550
551    fn parse_array_literal_from_brace(&mut self) -> Result<Node, ParserError> {
552        self.advance(); // consume '{'
553        let mut elements = Vec::new();
554        while self.current_token != Token::RBrace && self.current_token != Token::Eof {
555            let start_expr = self.parse_expression(Precedence::None)?;
556            if self.current_token == Token::Colon {
557                self.advance();
558                let step_expr = self.parse_expression(Precedence::None)?;
559                let end_expr = if self.current_token == Token::Colon {
560                    self.advance();
561                    Some(self.parse_expression(Precedence::None)?)
562                } else {
563                    None
564                };
565                elements.push(Node::RangeLiteral {
566                    start: Box::new(start_expr),
567                    step: Box::new(step_expr),
568                    end: end_expr.map(Box::new),
569                });
570            } else {
571                elements.push(start_expr);
572            }
573            if self.current_token == Token::Comma {
574                self.advance();
575            } else {
576                break;
577            }
578        }
579        if self.current_token != Token::RBrace {
580            return Err(ParserError::MismatchedParentheses);
581        }
582        self.advance();
583        Ok(Node::ArrayLiteral(elements))
584    }
585
586    fn parse_block(&mut self) -> Result<Node, ParserError> {
587        self.advance(); // consume '{'
588        let mut statements = Vec::new();
589        while self.current_token != Token::RBrace && self.current_token != Token::Eof {
590            if self.current_token == Token::Semicolon {
591                self.advance();
592                continue;
593            }
594            statements.push(self.parse_statement()?);
595        }
596        if self.current_token == Token::RBrace {
597            self.advance(); // consume '}'
598        } else {
599            return Err(ParserError::MismatchedParentheses);
600        }
601        Ok(Node::Block(statements))
602    }
603
604    fn parse_expression(&mut self, precedence: Precedence) -> Result<Node, ParserError> {
605        let mut left = match self.current_token {
606            Token::Number(n) => {
607                self.advance();
608                Ok(Node::Number(n))
609            }
610            Token::StringLiteral(ref s) => {
611                let literal = s.clone();
612                self.advance();
613                Ok(Node::StringLiteral(literal))
614            }
615            Token::Switch => self.parse_switch_statement(),
616            Token::Symbol(ref s) => {
617                let name = s.clone();
618                self.advance();
619                if name == "true" {
620                    Ok(Node::Number(1.0))
621                } else if name == "false" {
622                    Ok(Node::Number(0.0))
623                } else if name == "null" {
624                    Ok(Node::Null)
625                } else if self.current_token == Token::LParen {
626                    self.advance();
627                    let mut args = Vec::new();
628                    if self.current_token != Token::RParen {
629                        loop {
630                            args.push(self.parse_expression(Precedence::None)?);
631                            if self.current_token == Token::Comma {
632                                self.advance();
633                            } else {
634                                break;
635                            }
636                        }
637                    }
638                    if self.current_token != Token::RParen {
639                        return Err(ParserError::MismatchedParentheses);
640                    }
641                    self.advance();
642                    Ok(Node::Function(name, args))
643                } else {
644                    Ok(Node::Variable(name))
645                }
646            }
647            Token::LBracket => {
648                self.advance();
649                // Check for [*] switch syntax
650                if self.current_token == Token::Asterisk {
651                    self.advance(); // consume *
652                    if self.current_token == Token::RBracket {
653                        self.advance(); // consume ]
654                        return self.parse_switch_body();
655                    }
656                    // Not [*], parse as bracket array starting with the expression after *
657                    // The * was already consumed, so treat it as a multiplication prefix error
658                    return Err(ParserError::InvalidExpression);
659                }
660                let mut elements = Vec::new();
661                let mut has_comma = false;
662                while self.current_token != Token::RBracket && self.current_token != Token::Eof {
663                    let start_expr = self.parse_expression(Precedence::None)?;
664                    if self.current_token == Token::Colon {
665                        self.advance();
666                        let step_expr = self.parse_expression(Precedence::None)?;
667                        let end_expr = if self.current_token == Token::Colon {
668                            self.advance();
669                            Some(self.parse_expression(Precedence::None)?)
670                        } else {
671                            None
672                        };
673                        elements.push(Node::RangeLiteral {
674                            start: Box::new(start_expr),
675                            step: Box::new(step_expr),
676                            end: end_expr.map(Box::new),
677                        });
678                    } else {
679                        elements.push(start_expr);
680                    }
681                    if self.current_token == Token::Comma {
682                        has_comma = true;
683                        self.advance();
684                    } else {
685                        break;
686                    }
687                }
688                if self.current_token != Token::RBracket {
689                    return Err(ParserError::MismatchedParentheses);
690                }
691                self.advance();
692                // Single expression without commas and not a range: treat as grouping
693                if elements.len() == 1
694                    && !has_comma
695                    && !matches!(elements[0], Node::RangeLiteral { .. })
696                {
697                    Ok(elements.into_iter().next().unwrap())
698                } else {
699                    Ok(Node::BracketArrayLiteral(elements))
700                }
701            }
702            Token::For => self.parse_for_loop(),
703            Token::LParen => {
704                self.advance();
705                let expr = self.parse_expression(Precedence::None)?;
706                if self.current_token != Token::RParen {
707                    return Err(ParserError::MismatchedParentheses);
708                }
709                self.advance();
710                Ok(expr)
711            }
712            Token::LBrace => self.parse_block(),
713            Token::Minus => {
714                self.advance();
715                let expr = self.parse_expression(Precedence::Exponent)?;
716                Ok(Node::UnaryOp(Op::Subtract, Box::new(expr)))
717            }
718            Token::Plus => {
719                self.advance();
720                self.parse_expression(Precedence::Exponent)
721            }
722            Token::Tilde => {
723                self.advance();
724                if self.current_token == Token::LBrace {
725                    self.parse_block()
726                } else {
727                    Err(ParserError::InvalidExpression)
728                }
729            }
730            Token::If => Ok(self.parse_if_expression()?),
731            _ => Err(ParserError::InvalidExpression),
732        }?;
733
734        while {
735            let token_prec = get_precedence(&self.current_token);
736            let right_assoc = matches!(self.current_token, Token::Caret);
737            precedence < token_prec
738                || (right_assoc && precedence == token_prec)
739                || matches!(self.current_token, Token::LBracket)
740                || (implicit_mul_token(&self.current_token) && is_value_node(&left))
741        } {
742            if precedence <= Precedence::Term
743                && implicit_mul_token(&self.current_token)
744                && is_value_node(&left)
745            {
746                let right = self.parse_expression(Precedence::Factor)?;
747                left = Node::BinaryOp(Box::new(left), Op::Multiply, Box::new(right));
748                continue;
749            }
750            left = match self.current_token {
751                Token::Assignment => {
752                    self.advance();
753                    let right = self.parse_expression(Precedence::Assignment)?;
754                    if matches!(
755                        left,
756                        Node::Variable(_) | Node::Index { .. } | Node::StringSlice { .. }
757                    ) {
758                        left = Node::Assignment(Box::new(left), Box::new(right));
759                        Ok(left)
760                    } else {
761                        left = Node::BinaryOp(Box::new(left), Op::Equal, Box::new(right));
762                        Ok(left)
763                    }
764                }
765                Token::PlusEqual => {
766                    self.advance();
767                    let right = self.parse_expression(Precedence::Assignment)?;
768                    if matches!(
769                        left,
770                        Node::Variable(_) | Node::Index { .. } | Node::StringSlice { .. }
771                    ) {
772                        let target = left.clone();
773                        let expr =
774                            Node::BinaryOp(Box::new(target.clone()), Op::Add, Box::new(right));
775                        left = Node::Assignment(Box::new(target), Box::new(expr));
776                        Ok(left)
777                    } else {
778                        Err(ParserError::InvalidExpression)
779                    }
780                }
781                Token::MinusEqual => {
782                    self.advance();
783                    let right = self.parse_expression(Precedence::Assignment)?;
784                    if matches!(
785                        left,
786                        Node::Variable(_) | Node::Index { .. } | Node::StringSlice { .. }
787                    ) {
788                        let target = left.clone();
789                        let expr =
790                            Node::BinaryOp(Box::new(target.clone()), Op::Subtract, Box::new(right));
791                        left = Node::Assignment(Box::new(target), Box::new(expr));
792                        Ok(left)
793                    } else {
794                        Err(ParserError::InvalidExpression)
795                    }
796                }
797                Token::AsteriskEqual => {
798                    self.advance();
799                    let right = self.parse_expression(Precedence::Assignment)?;
800                    if matches!(
801                        left,
802                        Node::Variable(_) | Node::Index { .. } | Node::StringSlice { .. }
803                    ) {
804                        let target = left.clone();
805                        let expr =
806                            Node::BinaryOp(Box::new(target.clone()), Op::Multiply, Box::new(right));
807                        left = Node::Assignment(Box::new(target), Box::new(expr));
808                        Ok(left)
809                    } else {
810                        Err(ParserError::InvalidExpression)
811                    }
812                }
813                Token::SlashEqual => {
814                    self.advance();
815                    let right = self.parse_expression(Precedence::Assignment)?;
816                    if matches!(
817                        left,
818                        Node::Variable(_) | Node::Index { .. } | Node::StringSlice { .. }
819                    ) {
820                        let target = left.clone();
821                        let expr =
822                            Node::BinaryOp(Box::new(target.clone()), Op::Divide, Box::new(right));
823                        left = Node::Assignment(Box::new(target), Box::new(expr));
824                        Ok(left)
825                    } else {
826                        Err(ParserError::InvalidExpression)
827                    }
828                }
829                Token::PercentEqual => {
830                    self.advance();
831                    let right = self.parse_expression(Precedence::Assignment)?;
832                    if matches!(
833                        left,
834                        Node::Variable(_) | Node::Index { .. } | Node::StringSlice { .. }
835                    ) {
836                        let target = left.clone();
837                        let expr =
838                            Node::BinaryOp(Box::new(target.clone()), Op::Modulo, Box::new(right));
839                        left = Node::Assignment(Box::new(target), Box::new(expr));
840                        Ok(left)
841                    } else {
842                        Err(ParserError::InvalidExpression)
843                    }
844                }
845                Token::Swap => {
846                    self.advance();
847                    let right = self.parse_expression(Precedence::Assignment)?;
848                    left = Node::Swap(Box::new(left), Box::new(right));
849                    Ok(left)
850                }
851                Token::LBracket => {
852                    self.advance();
853                    if self.current_token == Token::RBracket {
854                        self.advance();
855                        match left {
856                            Node::Variable(name) => {
857                                left = Node::ArraySize(name);
858                                Ok(left)
859                            }
860                            _ => {
861                                left = Node::Function("[]".into(), vec![left]);
862                                Ok(left)
863                            }
864                        }
865                    } else if self.current_token == Token::Colon {
866                        self.advance();
867                        let end = if self.current_token != Token::RBracket {
868                            Some(self.parse_expression(Precedence::None)?)
869                        } else {
870                            None
871                        };
872                        if self.current_token != Token::RBracket {
873                            return Err(ParserError::MismatchedParentheses);
874                        }
875                        self.advance();
876                        let target = left;
877                        left = Node::StringSlice {
878                            target: Box::new(target),
879                            start: Box::new(Node::Number(0.0)),
880                            end: end.map(Box::new),
881                        };
882                        Ok(left)
883                    } else {
884                        let start = self.parse_expression(Precedence::None)?;
885                        if self.current_token == Token::Colon {
886                            self.advance();
887                            let end = if self.current_token != Token::RBracket {
888                                Some(self.parse_expression(Precedence::None)?)
889                            } else {
890                                None
891                            };
892                            if self.current_token != Token::RBracket {
893                                return Err(ParserError::MismatchedParentheses);
894                            }
895                            self.advance();
896                            let target = left;
897                            left = Node::StringSlice {
898                                target: Box::new(target),
899                                start: Box::new(start),
900                                end: end.map(Box::new),
901                            };
902                            Ok(left)
903                        } else {
904                            let inner = start;
905                            if self.current_token != Token::RBracket {
906                                return Err(ParserError::MismatchedParentheses);
907                            }
908                            self.advance();
909                            if matches!(
910                                left,
911                                Node::Variable(_) | Node::Index { .. } | Node::StringSlice { .. }
912                            ) {
913                                left = Node::Index {
914                                    target: Box::new(left),
915                                    index: Box::new(inner),
916                                };
917                            } else {
918                                left =
919                                    Node::BinaryOp(Box::new(left), Op::Multiply, Box::new(inner));
920                            }
921                            Ok(left)
922                        }
923                    }
924                }
925                Token::Equal => {
926                    self.advance();
927                    let right = self.parse_expression(Precedence::Equality)?;
928                    let node = Node::BinaryOp(Box::new(left), Op::Equal, Box::new(right));
929                    Ok(node)
930                }
931                Token::NotEqual => {
932                    self.advance();
933                    let right = self.parse_expression(Precedence::Equality)?;
934                    let node = Node::BinaryOp(Box::new(left), Op::NotEqual, Box::new(right));
935                    Ok(node)
936                }
937                Token::LessThan => {
938                    self.advance();
939                    let right = self.parse_expression(Precedence::Comparison)?;
940                    let node = Node::BinaryOp(Box::new(left), Op::LessThan, Box::new(right));
941                    Ok(node)
942                }
943                Token::LessThanOrEqual => {
944                    self.advance();
945                    let right = self.parse_expression(Precedence::Comparison)?;
946                    let node = Node::BinaryOp(Box::new(left), Op::LessThanOrEqual, Box::new(right));
947                    Ok(node)
948                }
949                Token::GreaterThan => {
950                    self.advance();
951                    let right = self.parse_expression(Precedence::Comparison)?;
952                    let node = Node::BinaryOp(Box::new(left), Op::GreaterThan, Box::new(right));
953                    Ok(node)
954                }
955                Token::GreaterThanOrEqual => {
956                    self.advance();
957                    let right = self.parse_expression(Precedence::Comparison)?;
958                    let node =
959                        Node::BinaryOp(Box::new(left), Op::GreaterThanOrEqual, Box::new(right));
960                    Ok(node)
961                }
962                Token::In => {
963                    self.advance();
964                    let right = self.parse_expression(Precedence::Comparison)?;
965                    let node = Node::BinaryOp(Box::new(left), Op::In, Box::new(right));
966                    Ok(node)
967                }
968                Token::Like => {
969                    self.advance();
970                    let right = self.parse_expression(Precedence::Comparison)?;
971                    let node = Node::BinaryOp(Box::new(left), Op::Like, Box::new(right));
972                    Ok(node)
973                }
974                Token::Ilike => {
975                    self.advance();
976                    let right = self.parse_expression(Precedence::Comparison)?;
977                    let node = Node::BinaryOp(Box::new(left), Op::Ilike, Box::new(right));
978                    Ok(node)
979                }
980                Token::And => {
981                    self.advance();
982                    let right = self.parse_expression(Precedence::And)?;
983                    let node = Node::BinaryOp(Box::new(left), Op::And, Box::new(right));
984                    Ok(node)
985                }
986                Token::Nand => {
987                    self.advance();
988                    let right = self.parse_expression(Precedence::And)?;
989                    let node = Node::BinaryOp(Box::new(left), Op::Nand, Box::new(right));
990                    Ok(node)
991                }
992                Token::Or => {
993                    self.advance();
994                    let right = self.parse_expression(Precedence::Or)?;
995                    let node = Node::BinaryOp(Box::new(left), Op::Or, Box::new(right));
996                    Ok(node)
997                }
998                Token::Nor => {
999                    self.advance();
1000                    let right = self.parse_expression(Precedence::Or)?;
1001                    let node = Node::BinaryOp(Box::new(left), Op::Nor, Box::new(right));
1002                    Ok(node)
1003                }
1004                Token::Xor => {
1005                    self.advance();
1006                    let right = self.parse_expression(Precedence::Or)?;
1007                    let node = Node::BinaryOp(Box::new(left), Op::Xor, Box::new(right));
1008                    Ok(node)
1009                }
1010                Token::Xnor => {
1011                    self.advance();
1012                    let right = self.parse_expression(Precedence::Or)?;
1013                    let node = Node::BinaryOp(Box::new(left), Op::Xnor, Box::new(right));
1014                    Ok(node)
1015                }
1016                Token::Ampersand => {
1017                    self.advance();
1018                    let right = self.parse_expression(Precedence::And)?;
1019                    let node = Node::BinaryOp(Box::new(left), Op::BitAnd, Box::new(right));
1020                    Ok(node)
1021                }
1022                Token::Pipe => {
1023                    self.advance();
1024                    let right = self.parse_expression(Precedence::Or)?;
1025                    let node = Node::BinaryOp(Box::new(left), Op::BitOr, Box::new(right));
1026                    Ok(node)
1027                }
1028                Token::Caret => {
1029                    self.advance();
1030                    let right = self.parse_expression(Precedence::Exponent)?;
1031                    let node = Node::BinaryOp(Box::new(left), Op::Power, Box::new(right));
1032                    Ok(node)
1033                }
1034                Token::Plus => {
1035                    self.advance();
1036                    let right = self.parse_expression(Precedence::Term)?;
1037                    let node = Node::BinaryOp(Box::new(left), Op::Add, Box::new(right));
1038                    Ok(node)
1039                }
1040                Token::Minus => {
1041                    self.advance();
1042                    let right = self.parse_expression(Precedence::Term)?;
1043                    let node = Node::BinaryOp(Box::new(left), Op::Subtract, Box::new(right));
1044                    Ok(node)
1045                }
1046                Token::Asterisk => {
1047                    self.advance();
1048                    let right = self.parse_expression(Precedence::Factor)?;
1049                    let node = Node::BinaryOp(Box::new(left), Op::Multiply, Box::new(right));
1050                    Ok(node)
1051                }
1052                Token::Slash => {
1053                    self.advance();
1054                    let right = self.parse_expression(Precedence::Factor)?;
1055                    let node = Node::BinaryOp(Box::new(left), Op::Divide, Box::new(right));
1056                    Ok(node)
1057                }
1058                Token::Percent => {
1059                    self.advance();
1060                    let right = self.parse_expression(Precedence::Factor)?;
1061                    let node = Node::BinaryOp(Box::new(left), Op::Modulo, Box::new(right));
1062                    Ok(node)
1063                }
1064                _ => return Ok(left),
1065            }?;
1066        }
1067
1068        if precedence <= Precedence::Assignment && self.current_token == Token::Question {
1069            self.advance();
1070            let then_expr = self.parse_expression(Precedence::Assignment)?;
1071            if self.current_token != Token::Colon {
1072                return Err(ParserError::InvalidExpression);
1073            }
1074            self.advance();
1075            let else_expr = self.parse_expression(Precedence::Assignment)?;
1076            left = Node::Ternary {
1077                condition: Box::new(left),
1078                then_expr: Box::new(then_expr),
1079                else_expr: Box::new(else_expr),
1080            };
1081        }
1082
1083        Ok(left)
1084    }
1085}
1086
1087#[cfg(test)]
1088mod tests {
1089    use super::{Node, Op, Parser};
1090
1091    #[test]
1092    fn test_parser_simple() {
1093        let expression = "1 + 2";
1094        let mut parser = Parser::<f64>::new(expression);
1095        let ast = parser.parse();
1096        assert_eq!(
1097            ast.unwrap(),
1098            Node::BinaryOp(
1099                Box::new(Node::Number(1.0)),
1100                Op::Add,
1101                Box::new(Node::Number(2.0))
1102            )
1103        );
1104    }
1105
1106    #[test]
1107    fn test_parser_precedence() {
1108        let expression = "1 + 2 * 3";
1109        let mut parser = Parser::<f64>::new(expression);
1110        let ast = parser.parse();
1111        assert_eq!(
1112            ast.unwrap(),
1113            Node::BinaryOp(
1114                Box::new(Node::Number(1.0)),
1115                Op::Add,
1116                Box::new(Node::BinaryOp(
1117                    Box::new(Node::Number(2.0)),
1118                    Op::Multiply,
1119                    Box::new(Node::Number(3.0))
1120                ))
1121            )
1122        );
1123    }
1124
1125    #[test]
1126    fn test_parser_parentheses() {
1127        let expression = "(1 + 2) * 3";
1128        let mut parser = Parser::<f64>::new(expression);
1129        let ast = parser.parse();
1130        assert_eq!(
1131            ast.unwrap(),
1132            Node::BinaryOp(
1133                Box::new(Node::BinaryOp(
1134                    Box::new(Node::Number(1.0)),
1135                    Op::Add,
1136                    Box::new(Node::Number(2.0))
1137                )),
1138                Op::Multiply,
1139                Box::new(Node::Number(3.0))
1140            )
1141        );
1142    }
1143
1144    #[test]
1145    fn test_parser_unary() {
1146        let expression = "-1";
1147        let mut parser = Parser::<f64>::new(expression);
1148        let ast = parser.parse();
1149        assert_eq!(
1150            ast.unwrap(),
1151            Node::UnaryOp(Op::Subtract, Box::new(Node::Number(1.0)))
1152        );
1153    }
1154
1155    #[test]
1156    fn test_parser_variable() {
1157        let expression = "x + y";
1158        let mut parser = Parser::<f64>::new(expression);
1159        let ast = parser.parse();
1160        assert_eq!(
1161            ast.unwrap(),
1162            Node::BinaryOp(
1163                Box::new(Node::Variable("x".to_string())),
1164                Op::Add,
1165                Box::new(Node::Variable("y".to_string()))
1166            )
1167        );
1168    }
1169
1170    #[test]
1171    fn test_parser_function() {
1172        let expression = "foo(1, 2)";
1173        let mut parser = Parser::<f64>::new(expression);
1174        let ast = parser.parse();
1175        assert_eq!(
1176            ast.unwrap(),
1177            Node::Function(
1178                "foo".to_string(),
1179                vec![Node::Number(1.0), Node::Number(2.0)]
1180            )
1181        );
1182    }
1183}