Skip to main content

kronk_core/
parser.rs

1//! Parser definition
2
3use std::{error::Error, fmt::Display};
4
5use crate::tokenizer::{Keyword, Token, TokenTag};
6
7/// A parser holding context
8pub struct Parser<'a> {
9    /// The token stream being parsed
10    tokens: &'a [Token<'a>],
11    /// Current index into the token stream
12    idx: usize,
13}
14
15/// An error that occurs whilst parsing
16#[derive(Clone, PartialEq, Debug, Default)]
17pub struct ParseError {
18    /// The error message
19    pub message: String,
20    /// Line of the error
21    pub line: usize,
22    /// Column of the error
23    pub col: usize,
24    /// Length of the error
25    pub len: usize,
26}
27
28impl From<(TokenTag<'_>, Token<'_>)> for ParseError {
29    fn from(value: (TokenTag<'_>, Token<'_>)) -> Self {
30        let (
31            want,
32            Token {
33                line,
34                col,
35                len,
36                tag,
37            },
38        ) = value;
39        Self {
40            message: format!("Expected `{want}` after `{tag}`"),
41            line,
42            col,
43            len,
44        }
45    }
46}
47
48impl Display for ParseError {
49    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50        write!(f, "parser error: {}", self.message)
51    }
52}
53
54impl Error for ParseError {}
55
56impl<'a> Parser<'a> {
57    /// Constructs a new parser by wrapping over some tokens
58    pub fn with_tokens(tokens: &'a [Token<'a>]) -> Self {
59        Self { tokens, idx: 0 }
60    }
61
62    /// Peeks at the current token, does not advance the index
63    #[inline]
64    fn peek(&self) -> Token<'a> {
65        self.tokens[self.idx]
66    }
67
68    /// Peeks at the previous token, does not advance the index
69    #[inline]
70    fn peek_back(&self) -> Token<'a> {
71        self.tokens[self.idx - 1]
72    }
73
74    /// Peeks the current token plus some `n`
75    fn peek_n(&self, n: usize) -> Option<TokenTag<'a>> {
76        if self.idx + n >= self.tokens.len() {
77            None
78        } else {
79            Some(self.tokens[self.idx + n].tag)
80        }
81    }
82
83    /// Consumes the current token assuming it's the provided Token, failing if not
84    fn consume(&mut self, token: &TokenTag<'_>) -> Result<(), ParseError> {
85        if &self.peek().tag == token {
86            self.idx += 1;
87            Ok(())
88        } else {
89            Err((*token, self.peek_back()).into())
90        }
91    }
92
93    /// Checks if stream is finished
94    fn at_end(&self) -> bool {
95        self.peek().tag == TokenTag::EOF
96    }
97
98    /// Advances forward and returns the token we hop after
99    fn advance(&mut self) -> Token<'a> {
100        if !self.at_end() {
101            self.idx += 1
102        }
103
104        if self.idx == 0 {
105            self.tokens[0]
106        } else {
107            self.tokens[self.idx - 1]
108        }
109    }
110
111    /// Parses a token stream into a sequence of statements
112    pub fn parse_many(&mut self) -> Result<Vec<Expr<'a>>, ParseError> {
113        let mut expressions = vec![];
114
115        while !self.at_end() {
116            let expr = self.parse()?;
117            expressions.push(expr);
118        }
119
120        Ok(expressions)
121    }
122
123    /// Parses the current token stream
124    pub fn parse(&mut self) -> Result<Expr<'a>, ParseError> {
125        let expr = self.statement()?;
126        Ok(expr)
127    }
128
129    /// A statement is either `print `expression` | `expression` | `while` | `if` | { block } | `for` ;
130    fn statement(&mut self) -> Result<Expr<'a>, ParseError> {
131        match self.peek().tag {
132            TokenTag::Keyword(Keyword::Roar) => {
133                self.advance();
134                let next = self.expression()?;
135                self.consume(&TokenTag::Bang)?;
136
137                Ok(Expr::Roar(Box::new(next)))
138            }
139            TokenTag::Keyword(Keyword::Print) => {
140                self.advance();
141                let next = self.expression()?;
142                self.consume(&TokenTag::Semicolon)?;
143
144                Ok(Expr::Print(Box::new(next)))
145            }
146            TokenTag::OpenBrace => self.block(),
147            TokenTag::Keyword(Keyword::For) => self.for_statement(),
148            TokenTag::Keyword(Keyword::If) => self.if_statement(),
149            TokenTag::Keyword(Keyword::While) => self.while_statement(),
150            _ => {
151                let res = self.expression()?;
152                self.consume(&TokenTag::Semicolon)?;
153                Ok(res)
154            }
155        }
156    }
157
158    /// A while statement is `while ( `equality` ) `expression``
159    fn while_statement(&mut self) -> Result<Expr<'a>, ParseError> {
160        self.consume(&TokenTag::Keyword(Keyword::While))?;
161        self.consume(&TokenTag::OpenParen)?;
162
163        let condition = Box::new(self.equality()?);
164
165        self.consume(&TokenTag::CloseParen)?;
166
167        let exec = Box::new(self.statement()?);
168
169        Ok(Expr::WhileLoop { condition, exec })
170    }
171
172    /// A for loop is `for (`expression`, `equality`, `expression`) `expression``
173    fn for_statement(&mut self) -> Result<Expr<'a>, ParseError> {
174        self.consume(&TokenTag::Keyword(Keyword::For))?;
175        self.consume(&TokenTag::OpenParen)?;
176
177        let init = Box::new(self.expression()?);
178        self.consume(&TokenTag::Semicolon)?;
179
180        let check = Box::new(self.equality()?);
181        self.consume(&TokenTag::Semicolon)?;
182
183        let update = Box::new(self.expression()?);
184        self.consume(&TokenTag::CloseParen)?;
185
186        let exec = Box::new(self.statement()?);
187
188        Ok(Expr::ForLoop {
189            init,
190            check,
191            update,
192            exec,
193        })
194    }
195
196    /// A block is `{ (expression)* }`
197    fn block(&mut self) -> Result<Expr<'a>, ParseError> {
198        self.consume(&TokenTag::OpenBrace)?;
199        let mut block_items = vec![];
200
201        while self.peek().tag != TokenTag::CloseBrace {
202            let expr = self.statement()?;
203            block_items.push(expr);
204        }
205
206        self.consume(&TokenTag::CloseBrace)?;
207
208        Ok(Expr::Block(block_items))
209    }
210
211    /// An If statement is:
212    /// `if ( equality ) { `block` } ( else { `block` })?`
213    fn if_statement(&mut self) -> Result<Expr<'a>, ParseError> {
214        self.consume(&TokenTag::Keyword(Keyword::If))?;
215        self.consume(&TokenTag::OpenParen)?;
216        let check = self.equality()?;
217        self.consume(&TokenTag::CloseParen)?;
218        let block = self.block()?;
219
220        let mut else_branch = None;
221
222        if self.peek().tag == TokenTag::Keyword(Keyword::Else) {
223            self.advance();
224            else_branch = Some(Box::new(self.statement()?));
225        }
226
227        Ok(Expr::Conditional {
228            condition: Box::new(check),
229            true_branch: Box::new(block),
230            else_branch,
231        })
232    }
233
234    /// -> equality  | var ident = equality | ident = equality | ident++ | ident += equality
235    fn expression(&mut self) -> Result<Expr<'a>, ParseError> {
236        match (self.peek().tag, self.peek_n(1)) {
237            (TokenTag::Keyword(Keyword::Var), _) => {
238                self.advance();
239                let advance = self.advance();
240                if let TokenTag::Identifier(name) = advance.tag {
241                    self.consume(&TokenTag::Equal)?;
242                    let val = self.equality()?;
243                    Ok(Expr::Assignment {
244                        name,
245                        val: Box::new(val),
246                    })
247                } else {
248                    Err(ParseError {
249                        message: format!("Expected Expression, found `{}`", advance.tag),
250                        line: advance.line,
251                        col: advance.col,
252                        len: advance.len,
253                    })
254                }
255            }
256
257            (TokenTag::Identifier(name), Some(TokenTag::Equal)) => {
258                self.advance();
259                self.advance();
260                let assignment = self.equality()?;
261
262                Ok(Expr::Reassignment {
263                    name,
264                    val: Box::new(assignment),
265                })
266            }
267
268            (TokenTag::Identifier(name), Some(TokenTag::PlusEq)) => {
269                self.advance();
270                self.advance();
271                let add = Box::new(self.equality()?);
272
273                Ok(Expr::AddAssign { name, add })
274            }
275
276            (TokenTag::Identifier(ident), Some(TokenTag::PlusPlus)) => {
277                self.advance();
278                self.advance();
279
280                Ok(Expr::Inc(ident, true))
281            }
282
283            (TokenTag::PlusPlus, Some(TokenTag::Identifier(ident))) => {
284                self.advance();
285                self.advance();
286
287                Ok(Expr::Inc(ident, false))
288            }
289
290            _ => self.equality(),
291        }
292    }
293
294    /// -> comparison ( ( "!=" | "==" ) comparison )* ;
295    fn equality(&mut self) -> Result<Expr<'a>, ParseError> {
296        let mut expr = self.comparison()?;
297
298        while matches!(self.peek().tag, TokenTag::BangEqual | TokenTag::EqualEqual) {
299            let op = match self.advance().tag {
300                TokenTag::BangEqual => BinaryOperator::Neq,
301                TokenTag::EqualEqual => BinaryOperator::Eq,
302                _ => unreachable!(),
303            };
304
305            let right = self.comparison()?;
306
307            expr = Expr::Binary {
308                op,
309                left: Box::new(expr),
310                right: Box::new(right),
311            }
312        }
313
314        Ok(expr)
315    }
316
317    /// -> term ( ( ">" | ">=" | "<" | "<=" ) term )* ;
318    fn comparison(&mut self) -> Result<Expr<'a>, ParseError> {
319        let mut expr = self.term()?;
320
321        while matches!(
322            self.peek().tag,
323            TokenTag::Greater | TokenTag::GreaterEqual | TokenTag::Less | TokenTag::LessEqual
324        ) {
325            let op = match self.advance().tag {
326                TokenTag::GreaterEqual => BinaryOperator::Gte,
327                TokenTag::Greater => BinaryOperator::Gt,
328                TokenTag::LessEqual => BinaryOperator::Lte,
329                TokenTag::Less => BinaryOperator::Lt,
330                _ => unreachable!(),
331            };
332
333            let right = self.term()?;
334            expr = Expr::Binary {
335                op,
336                left: Box::new(expr),
337                right: Box::new(right),
338            }
339        }
340
341        Ok(expr)
342    }
343
344    /// -> factor ( ( "-" | "+" ) factor )* ;
345    fn term(&mut self) -> Result<Expr<'a>, ParseError> {
346        let mut expr = self.factor()?;
347
348        while matches!(self.peek().tag, TokenTag::Plus | TokenTag::Minus) {
349            let op = match self.advance().tag {
350                TokenTag::Minus => BinaryOperator::Sub,
351                TokenTag::Plus => BinaryOperator::Add,
352                _ => unreachable!(),
353            };
354
355            let right = self.factor()?;
356            expr = Expr::Binary {
357                op,
358                left: Box::new(expr),
359                right: Box::new(right),
360            }
361        }
362
363        Ok(expr)
364    }
365
366    /// ->  unary ( ( "/" | "*" ) unary )* ;
367    fn factor(&mut self) -> Result<Expr<'a>, ParseError> {
368        let mut expr = self.unary()?;
369
370        while matches!(self.peek().tag, TokenTag::Slash | TokenTag::Star) {
371            let op = match self.advance().tag {
372                TokenTag::Slash => BinaryOperator::Div,
373                TokenTag::Star => BinaryOperator::Mul,
374                _ => unreachable!(),
375            };
376
377            let right = self.unary()?;
378            expr = Expr::Binary {
379                op,
380                left: Box::new(expr),
381                right: Box::new(right),
382            }
383        }
384
385        Ok(expr)
386    }
387
388    /// -> ( "!" | "-" ) unary | primary ;
389    fn unary(&mut self) -> Result<Expr<'a>, ParseError> {
390        if matches!(self.peek().tag, TokenTag::Bang | TokenTag::Minus) {
391            let op = match self.advance().tag {
392                TokenTag::Bang => UnaryOperator::Not,
393                TokenTag::Minus => UnaryOperator::Neg,
394                _ => unreachable!(),
395            };
396
397            let unary = self.unary()?;
398
399            Ok(Expr::Unary {
400                op,
401                node: Box::new(unary),
402            })
403        } else {
404            self.primary()
405        }
406    }
407
408    /// Variable | NUMBER | STRING | "true" | "false" | "nil" | "(" expression ")" ;
409    fn primary(&mut self) -> Result<Expr<'a>, ParseError> {
410        let advance = self.advance();
411        let mut prim = match advance.tag {
412            TokenTag::Number(n) => Expr::Literal(Literal::Number(n)),
413            TokenTag::Keyword(Keyword::True) => Expr::Literal(Literal::True),
414            TokenTag::Keyword(Keyword::False) => Expr::Literal(Literal::False),
415            TokenTag::Keyword(Keyword::Nil) => Expr::Literal(Literal::Nil),
416            TokenTag::Identifier(ident) => Expr::Variable(ident),
417            TokenTag::String(s) => Expr::Literal(Literal::String(s)),
418            TokenTag::OpenBracket => self.list()?,
419            TokenTag::OpenParen => {
420                let expr = self.expression()?;
421                self.consume(&TokenTag::CloseParen)?;
422
423                Expr::Grouping(Box::new(expr))
424            }
425            _ => {
426                return Err(ParseError {
427                    message: format!("Unexpected token: `{}`", advance.tag),
428                    line: advance.line,
429                    col: advance.col,
430                    len: advance.len,
431                });
432            }
433        };
434
435        while self.peek().tag == TokenTag::OpenBracket {
436            // Attempted literal indexing
437            self.advance();
438            let index = Box::new(self.primary()?);
439            self.consume(&TokenTag::CloseBracket)?;
440            prim = Expr::Index {
441                item: Box::new(prim),
442                index,
443            };
444        }
445
446        Ok(prim)
447    }
448
449    /// A list is `[(primary)*]`
450    fn list(&mut self) -> Result<Expr<'a>, ParseError> {
451        let mut items = vec![];
452
453        while self.peek().tag != TokenTag::CloseBracket {
454            items.push(self.equality()?);
455            if self.peek().tag != TokenTag::CloseBracket {
456                self.consume(&TokenTag::Comma)?;
457            }
458        }
459
460        self.consume(&TokenTag::CloseBracket)?;
461
462        Ok(Expr::List(items))
463    }
464}
465
466/// An expression node in the AST
467#[derive(Debug, PartialEq, Clone)]
468pub enum Expr<'a> {
469    /// Indexing into a literal
470    Index {
471        /// The item we're indexing in
472        item: Box<Expr<'a>>,
473        /// The index into that item
474        index: Box<Expr<'a>>,
475    },
476    /// A for style loop that performs some initialization and repeatedly checks a certain equality
477    /// statement until it is true
478    ForLoop {
479        /// Loop initialization
480        init: Box<Expr<'a>>,
481        /// What is checked on each run
482        check: Box<Expr<'a>>,
483        /// What is run to update
484        update: Box<Expr<'a>>,
485        /// What is executed upon each iteration
486        exec: Box<Expr<'a>>,
487    },
488    /// A while style loop that will repeat until the inner condition is false
489    WhileLoop {
490        /// Condition being checked
491        condition: Box<Expr<'a>>,
492        /// Body being executed until then
493        exec: Box<Expr<'a>>,
494    },
495    /// A conditional executor
496    Conditional {
497        /// The condition being checked
498        condition: Box<Expr<'a>>,
499        /// What is executed if the condition is true
500        true_branch: Box<Expr<'a>>,
501        /// What is optionally executed if else
502        else_branch: Option<Box<Expr<'a>>>,
503    },
504    /// A block to be executed
505    Block(Vec<Expr<'a>>),
506    /// A literal
507    Literal(Literal<'a>),
508    /// A list of expressions that boils down to a list of literals
509    List(Vec<Expr<'a>>),
510    /// A variable
511    Variable(&'a str),
512    /// Unary operation
513    Unary {
514        /// Operator
515        op: UnaryOperator,
516        /// Expression Node
517        node: Box<Expr<'a>>,
518    },
519    /// Roar the expressions result to stdout
520    Roar(Box<Expr<'a>>),
521    /// Print the expressions result to stdout
522    Print(Box<Expr<'a>>),
523    /// Assignment operator for an existing variable, fails if variable does not exist
524    Reassignment {
525        /// The variable name
526        name: &'a str,
527        /// The variable value
528        val: Box<Expr<'a>>,
529    },
530    /// Increment a variable, true if return before and false if return after inc
531    Inc(&'a str, bool),
532    /// Add a value to a variable
533    AddAssign {
534        /// Name of the variable
535        name: &'a str,
536        /// What is added to the existing variable
537        add: Box<Expr<'a>>,
538    },
539    /// Assignment operator
540    Assignment {
541        /// The variable name
542        name: &'a str,
543        /// The variable value
544        val: Box<Expr<'a>>,
545    },
546    /// Binary operation
547    Binary {
548        /// Operator
549        op: BinaryOperator,
550        /// Left expression node
551        left: Box<Expr<'a>>,
552        /// Right expression node
553        right: Box<Expr<'a>>,
554    },
555    /// A grouping ()
556    Grouping(Box<Expr<'a>>),
557}
558
559/// A literal value
560#[derive(PartialEq, Debug, Clone)]
561pub enum Literal<'a> {
562    /// A number
563    Number(f64),
564    /// A string
565    String(&'a str),
566    /// Concatenated strings
567    Concat(Box<Literal<'a>>, Box<Literal<'a>>),
568    /// Boolean true
569    True,
570    /// Boolean false
571    False,
572    /// NULL
573    Nil,
574    /// A void return
575    Void,
576    /// A list of expressions
577    List(Vec<Literal<'a>>),
578}
579
580impl Display for Literal<'_> {
581    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
582        match self {
583            Self::Number(n) => write!(f, "{n}"),
584            Self::String(s) => write!(f, "{s}"),
585            Self::True => write!(f, "true"),
586            Self::False => write!(f, "false"),
587            Self::Nil => write!(f, "nil"),
588            Self::Concat(a, b) => write!(f, "{a}{b}"),
589            Self::Void => write!(f, ""),
590            Self::List(vals) => write!(f, "{vals:?}"),
591        }
592    }
593}
594
595/// An unary operator
596#[derive(Debug, PartialEq, Clone, Copy)]
597pub enum UnaryOperator {
598    /// Negation
599    Neg,
600    /// Not
601    Not,
602}
603
604/// A binary operator
605#[derive(Debug, PartialEq, Clone, Copy)]
606pub enum BinaryOperator {
607    /// Equality
608    Eq,
609    /// Inequality
610    Neq,
611    /// Greater than
612    Gt,
613    /// Greater than or equal
614    Gte,
615    /// Less than
616    Lt,
617    /// Less than or equal
618    Lte,
619    /// Addition
620    Add,
621    /// Subtraction
622    Sub,
623    /// Multiplication
624    Mul,
625    /// Division
626    Div,
627}
628
629#[cfg(test)]
630mod tests {
631    use crate::{
632        parser::{BinaryOperator, Expr, Literal, Parser, UnaryOperator},
633        tokenizer::Tokenizable,
634    };
635
636    #[test]
637    fn assignment() {
638        let tokens = "var foo = 100;".tokenize().expect("Tokenize");
639        let mut parser = Parser::with_tokens(&tokens);
640
641        let ast = parser.parse().expect("Failed to parse");
642
643        assert_eq!(
644            ast,
645            Expr::Assignment {
646                name: "foo",
647                val: Box::new(Expr::Literal(Literal::Number(100.0)))
648            }
649        )
650    }
651
652    #[test]
653    fn basic_ast_generated() {
654        let tokens = "100 + 100;".tokenize().expect("Tokenize");
655        let mut parser = Parser::with_tokens(&tokens);
656
657        let ast = parser.parse().expect("Failed to parse");
658
659        assert_eq!(
660            ast,
661            Expr::Binary {
662                op: BinaryOperator::Add,
663                left: Box::new(Expr::Literal(Literal::Number(100.0))),
664                right: Box::new(Expr::Literal(Literal::Number(100.0)))
665            }
666        )
667    }
668
669    #[test]
670    fn while_loop_structure() {
671        let tokens = "while (true) {}".tokenize().expect("Tokenize");
672        let mut parser = Parser::with_tokens(&tokens);
673
674        let ast = parser.parse().expect("Failed to parse");
675
676        assert_eq!(
677            ast,
678            Expr::WhileLoop {
679                condition: Box::new(Expr::Literal(Literal::True)),
680                exec: Box::new(Expr::Block(vec![]))
681            }
682        )
683    }
684
685    #[test]
686    fn list_with_expressions() {
687        let tokens = "[false, 2 + 4];".tokenize().expect("Tokenize");
688        let mut parser = Parser::with_tokens(&tokens);
689
690        let ast = parser.parse().expect("Failed to parse");
691
692        assert_eq!(
693            ast,
694            Expr::List(vec![
695                Expr::Literal(Literal::False),
696                Expr::Binary {
697                    op: BinaryOperator::Add,
698                    left: Box::new(Expr::Literal(Literal::Number(2.0))),
699                    right: Box::new(Expr::Literal(Literal::Number(4.0)))
700                }
701            ])
702        );
703    }
704
705    #[test]
706    fn list() {
707        let tokens = "[1, 2.4];".tokenize().expect("Tokenize");
708        let mut parser = Parser::with_tokens(&tokens);
709
710        let ast = parser.parse().expect("Failed to parse");
711
712        assert_eq!(
713            ast,
714            Expr::List(vec![
715                Expr::Literal(Literal::Number(1.0)),
716                Expr::Literal(Literal::Number(2.4))
717            ])
718        );
719    }
720
721    #[test]
722    fn simple_list_construction() {
723        let tokens = "[];".tokenize().expect("Tokenize");
724        let mut parser = Parser::with_tokens(&tokens);
725
726        let ast = parser.parse().expect("Failed to parse");
727
728        assert_eq!(ast, Expr::List(vec![]));
729    }
730
731    #[test]
732    fn test_literal_number() {
733        let tokens = "42;".tokenize().expect("Tokenize");
734        let mut parser = Parser::with_tokens(&tokens);
735
736        let ast = parser.parse().expect("Failed to parse");
737
738        assert_eq!(ast, Expr::Literal(Literal::Number(42.0)));
739    }
740
741    #[test]
742    fn test_literal_string() {
743        let tokens = "\"hello\";".tokenize().expect("Tokenize");
744        let mut parser = Parser::with_tokens(&tokens);
745
746        let ast = parser.parse().expect("Failed to parse");
747
748        assert_eq!(ast, Expr::Literal(Literal::String("hello")));
749    }
750
751    #[test]
752    fn test_literal_true() {
753        let tokens = "true;".tokenize().expect("Tokenize");
754        let mut parser = Parser::with_tokens(&tokens);
755
756        let ast = parser.parse().expect("Failed to parse");
757
758        assert_eq!(ast, Expr::Literal(Literal::True));
759    }
760
761    #[test]
762    fn empty_block() {
763        let tokens = "{};".tokenize().expect("Tokenize");
764        let mut parser = Parser::with_tokens(&tokens);
765
766        let ast = parser.parse().expect("Failed to parse");
767
768        assert_eq!(ast, Expr::Block(vec![]));
769    }
770
771    #[test]
772    fn if_block_simple() {
773        let tokens = r#"
774            if (true) {
775                print "Hello!";
776            }
777        "#
778        .tokenize()
779        .expect("Tokenize");
780        let mut parser = Parser::with_tokens(&tokens);
781
782        let ast = parser.parse().expect("Failed to parse");
783
784        assert_eq!(
785            ast,
786            Expr::Conditional {
787                condition: Box::new(Expr::Literal(Literal::True)),
788                true_branch: Box::new(Expr::Block(vec![Expr::Print(Box::new(Expr::Literal(
789                    Literal::String("Hello!")
790                )))])),
791                else_branch: None,
792            }
793        );
794    }
795
796    #[test]
797    fn block_with_stuff() {
798        let tokens = r#"
799        {
800            var foo = 10;
801            print foo;
802        }"#
803        .tokenize()
804        .expect("Tokenize");
805        let mut parser = Parser::with_tokens(&tokens);
806
807        let ast = parser.parse().expect("Failed to parse");
808
809        assert_eq!(
810            ast,
811            Expr::Block(vec![
812                Expr::Assignment {
813                    name: "foo",
814                    val: Box::new(Expr::Literal(Literal::Number(10.0)))
815                },
816                Expr::Print(Box::new(Expr::Variable("foo")))
817            ])
818        );
819    }
820
821    #[test]
822    fn test_literal_false() {
823        let tokens = "false;".tokenize().expect("Tokenize");
824        let mut parser = Parser::with_tokens(&tokens);
825
826        let ast = parser.parse().expect("Failed to parse");
827
828        assert_eq!(ast, Expr::Literal(Literal::False));
829    }
830
831    #[test]
832    fn test_literal_nil() {
833        let tokens = "nil;".tokenize().expect("Tokenize");
834        let mut parser = Parser::with_tokens(&tokens);
835
836        let ast = parser.parse().expect("Failed to parse");
837
838        assert_eq!(ast, Expr::Literal(Literal::Nil));
839    }
840
841    #[test]
842    fn test_unary_negation() {
843        let tokens = "-42;".tokenize().expect("Tokenize");
844        let mut parser = Parser::with_tokens(&tokens);
845
846        let ast = parser.parse().expect("Failed to parse");
847
848        assert_eq!(
849            ast,
850            Expr::Unary {
851                op: UnaryOperator::Neg,
852                node: Box::new(Expr::Literal(Literal::Number(42.0))),
853            }
854        );
855    }
856
857    #[test]
858    fn test_unary_not() {
859        let tokens = "!true;".tokenize().expect("Tokenize");
860        let mut parser = Parser::with_tokens(&tokens);
861
862        let ast = parser.parse().expect("Failed to parse");
863
864        assert_eq!(
865            ast,
866            Expr::Unary {
867                op: UnaryOperator::Not,
868                node: Box::new(Expr::Literal(Literal::True)),
869            }
870        );
871    }
872
873    #[test]
874    fn test_binary_addition() {
875        let tokens = "100 + 200;".tokenize().expect("Tokenize");
876        let mut parser = Parser::with_tokens(&tokens);
877
878        let ast = parser.parse().expect("Failed to parse");
879
880        assert_eq!(
881            ast,
882            Expr::Binary {
883                op: BinaryOperator::Add,
884                left: Box::new(Expr::Literal(Literal::Number(100.0))),
885                right: Box::new(Expr::Literal(Literal::Number(200.0))),
886            }
887        );
888    }
889
890    #[test]
891    fn test_binary_multiplication() {
892        let tokens = "3 * 4;".tokenize().expect("Tokenize");
893        let mut parser = Parser::with_tokens(&tokens);
894
895        let ast = parser.parse().expect("Failed to parse");
896
897        assert_eq!(
898            ast,
899            Expr::Binary {
900                op: BinaryOperator::Mul,
901                left: Box::new(Expr::Literal(Literal::Number(3.0))),
902                right: Box::new(Expr::Literal(Literal::Number(4.0))),
903            }
904        );
905    }
906
907    #[test]
908    fn test_binary_equality() {
909        let tokens = "true == false;".tokenize().expect("Tokenize");
910        let mut parser = Parser::with_tokens(&tokens);
911
912        let ast = parser.parse().expect("Failed to parse");
913
914        assert_eq!(
915            ast,
916            Expr::Binary {
917                op: BinaryOperator::Eq,
918                left: Box::new(Expr::Literal(Literal::True)),
919                right: Box::new(Expr::Literal(Literal::False)),
920            }
921        );
922    }
923
924    #[test]
925    fn test_binary_inequality() {
926        let tokens = "true != false;".tokenize().expect("Tokenize");
927        let mut parser = Parser::with_tokens(&tokens);
928
929        let ast = parser.parse().expect("Failed to parse");
930
931        assert_eq!(
932            ast,
933            Expr::Binary {
934                op: BinaryOperator::Neq,
935                left: Box::new(Expr::Literal(Literal::True)),
936                right: Box::new(Expr::Literal(Literal::False)),
937            }
938        );
939    }
940
941    #[test]
942    fn test_grouping() {
943        let tokens = "(42 + 10) * 2;".tokenize().expect("Tokenize");
944        let mut parser = Parser::with_tokens(&tokens);
945
946        let ast = parser.parse().expect("Failed to parse");
947
948        assert_eq!(
949            ast,
950            Expr::Binary {
951                op: BinaryOperator::Mul,
952                left: Box::new(Expr::Grouping(Box::new(Expr::Binary {
953                    op: BinaryOperator::Add,
954                    left: Box::new(Expr::Literal(Literal::Number(42.0))),
955                    right: Box::new(Expr::Literal(Literal::Number(10.0))),
956                }))),
957                right: Box::new(Expr::Literal(Literal::Number(2.0))),
958            }
959        );
960    }
961
962    #[test]
963    fn test_complex_expression() {
964        let tokens = "(3 + 5) * (10 - 2) / 4;".tokenize().expect("Tokenize");
965        let mut parser = Parser::with_tokens(&tokens);
966
967        let ast = parser.parse().expect("Failed to parse");
968
969        assert_eq!(
970            ast,
971            Expr::Binary {
972                op: BinaryOperator::Div,
973                left: Box::new(Expr::Binary {
974                    op: BinaryOperator::Mul,
975                    left: Box::new(Expr::Grouping(Box::new(Expr::Binary {
976                        op: BinaryOperator::Add,
977                        left: Box::new(Expr::Literal(Literal::Number(3.0))),
978                        right: Box::new(Expr::Literal(Literal::Number(5.0))),
979                    }))),
980                    right: Box::new(Expr::Grouping(Box::new(Expr::Binary {
981                        op: BinaryOperator::Sub,
982                        left: Box::new(Expr::Literal(Literal::Number(10.0))),
983                        right: Box::new(Expr::Literal(Literal::Number(2.0))),
984                    }))),
985                }),
986                right: Box::new(Expr::Literal(Literal::Number(4.0))),
987            }
988        );
989    }
990
991    #[test]
992    fn test_invalid_expression() {
993        let tokens = "42 +;".tokenize().expect("Tokenize");
994        let mut parser = Parser::with_tokens(&tokens);
995
996        let result = parser.parse();
997
998        assert!(result.is_err());
999    }
1000
1001    #[test]
1002    fn test_unexpected_token() {
1003        let tokens = "+ 42;".tokenize().expect("Tokenize");
1004        let mut parser = Parser::with_tokens(&tokens);
1005
1006        let result = parser.parse();
1007
1008        assert!(result.is_err());
1009    }
1010
1011    #[test]
1012    fn test_empty_input() {
1013        let tokens = "".tokenize().expect("Tokenize");
1014        let mut parser = Parser::with_tokens(&tokens);
1015
1016        let result = parser.parse();
1017
1018        assert!(result.is_err());
1019    }
1020}