Add test for parser
This commit is contained in:
parent
541d905551
commit
ef4dee98dc
@ -111,6 +111,6 @@ mod tests {
|
|||||||
];
|
];
|
||||||
|
|
||||||
let actual = lex(code);
|
let actual = lex(code);
|
||||||
assert_eq!(&expected, &actual);
|
assert_eq!(expected, actual);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,8 @@ use std::iter::Peekable;
|
|||||||
|
|
||||||
use crate::lexer::Token;
|
use crate::lexer::Token;
|
||||||
|
|
||||||
#[derive(Debug)]
|
/// Types for binary operators
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum BinOpType {
|
pub enum BinOpType {
|
||||||
/// Addition
|
/// Addition
|
||||||
Add,
|
Add,
|
||||||
@ -11,7 +12,7 @@ pub enum BinOpType {
|
|||||||
Mul,
|
Mul,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum Ast {
|
pub enum Ast {
|
||||||
/// Integer literal (64-bit)
|
/// Integer literal (64-bit)
|
||||||
I64(i64),
|
I64(i64),
|
||||||
@ -39,13 +40,14 @@ impl<T: Iterator<Item = Token>> Parser<T> {
|
|||||||
self.parse_expr_precedence(lhs, 0)
|
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 {
|
fn parse_expr_precedence(&mut self, mut lhs: Ast, min_prec: u8) -> Ast {
|
||||||
while let Some(binop) = &self.peek().try_to_binop() {
|
while let Some(binop) = &self.peek().try_to_binop() {
|
||||||
if !(binop.precedence() >= min_prec) {
|
if !(binop.precedence() >= min_prec) {
|
||||||
break;
|
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
|
// valid
|
||||||
let binop = self.next().try_to_binop().unwrap();
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user