From ef4dee98dc815519124fdeded53a364cb110efe2 Mon Sep 17 00:00:00 2001 From: Daniel M Date: Sun, 2 Jan 2022 21:28:36 +0100 Subject: [PATCH] Add test for parser --- src/lexer.rs | 2 +- src/parser.rs | 43 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/lexer.rs b/src/lexer.rs index a2cb761..03f918b 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -111,6 +111,6 @@ mod tests { ]; let actual = lex(code); - assert_eq!(&expected, &actual); + assert_eq!(expected, actual); } } diff --git a/src/parser.rs b/src/parser.rs index 79c9986..bbe8756 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -2,7 +2,8 @@ use std::iter::Peekable; use crate::lexer::Token; -#[derive(Debug)] +/// Types for binary operators +#[derive(Debug, PartialEq, Eq)] pub enum BinOpType { /// Addition Add, @@ -11,7 +12,7 @@ pub enum BinOpType { Mul, } -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] pub enum Ast { /// Integer literal (64-bit) I64(i64), @@ -39,13 +40,14 @@ impl> Parser { self.parse_expr_precedence(lhs, 0) } + /// Parse binary expressions with a precedence equal to or higher than min_prec fn parse_expr_precedence(&mut self, mut lhs: Ast, min_prec: u8) -> Ast { while let Some(binop) = &self.peek().try_to_binop() { if !(binop.precedence() >= min_prec) { break; } - // The while condition already verified that this is some while peeking, so unwrap is + // The while condition already verified that this is some while peeking, so unwrap is // valid let binop = self.next().try_to_binop().unwrap(); @@ -100,3 +102,38 @@ impl BinOpType { } } } + +#[cfg(test)] +mod tests { + use super::{parse, Ast, BinOpType}; + use crate::lexer::Token; + + #[test] + fn test_parser() { + // Expression: 1 + 2 * 3 + 4 + // With precedence: (1 + (2 * 3)) + 4 + let tokens = [ + Token::I64(1), + Token::Add, + Token::I64(2), + Token::Mul, + Token::I64(3), + Token::Add, + Token::I64(4), + ]; + + let expected = Ast::BinOp( + BinOpType::Add, + Ast::BinOp( + BinOpType::Add, + Ast::I64(1).into(), + Ast::BinOp(BinOpType::Mul, Ast::I64(2).into(), Ast::I64(3).into()).into(), + ) + .into(), + Ast::I64(4).into(), + ); + + let actual = parse(tokens); + assert_eq!(expected, actual); + } +}