From 89c554abdb23b21758d478dd7311196ce5187652 Mon Sep 17 00:00:00 2001 From: LunarAkai Date: Sat, 9 Aug 2025 14:50:24 +0200 Subject: [PATCH] added some tests --- justfile | 5 +- .../abstract_syntax_tree/ast.rs | 21 +++---- .../abstract_syntax_tree/definitions.rs | 2 +- .../abstract_syntax_tree/parser.rs | 57 +++++++++++++++---- src/main.rs | 2 +- 5 files changed, 58 insertions(+), 29 deletions(-) diff --git a/justfile b/justfile index 66f600f..a3bb6d6 100644 --- a/justfile +++ b/justfile @@ -1,2 +1,5 @@ run: - cargo run \ No newline at end of file + cargo run + +test: + cargo test --verbose \ No newline at end of file diff --git a/src/language_frontend/abstract_syntax_tree/ast.rs b/src/language_frontend/abstract_syntax_tree/ast.rs index 46d9571..1b3f312 100644 --- a/src/language_frontend/abstract_syntax_tree/ast.rs +++ b/src/language_frontend/abstract_syntax_tree/ast.rs @@ -1,5 +1,6 @@ use crate::language_frontend::abstract_syntax_tree::definitions::*; +// Option and Result -> define in Std #[derive(Clone, Debug, PartialEq)] pub enum Expr { Ident(String), @@ -14,25 +15,17 @@ pub enum Expr { CharLiteral(char), - Result, // todo + CalExpr(Call), - Option, // todo + UnaryExpr(Unary), - Ok, // todo + BinaryExpr(Binary), - Err, // todo + AssignmentExpr(Assignment), - Call(Call), + VarExpr(Var), - Unary(Unary), - - Binary(Binary), - - Assignment(Assignment), - - Var(Var), - - Function(Function), + FunctionExpr(Function), Error, } \ No newline at end of file diff --git a/src/language_frontend/abstract_syntax_tree/definitions.rs b/src/language_frontend/abstract_syntax_tree/definitions.rs index b8016bb..4794dd4 100644 --- a/src/language_frontend/abstract_syntax_tree/definitions.rs +++ b/src/language_frontend/abstract_syntax_tree/definitions.rs @@ -118,8 +118,8 @@ pub struct Var { /// Example: `x++` #[derive(Clone, Debug, PartialEq)] pub struct Unary { - pub operand: Box, pub operator: UnaryOp, + pub operand: Box, } /// Example: `x++` diff --git a/src/language_frontend/abstract_syntax_tree/parser.rs b/src/language_frontend/abstract_syntax_tree/parser.rs index 973313b..e058c94 100644 --- a/src/language_frontend/abstract_syntax_tree/parser.rs +++ b/src/language_frontend/abstract_syntax_tree/parser.rs @@ -7,8 +7,6 @@ use crate::language_frontend::{abstract_syntax_tree::{ast::Expr, definitions::*} // goal of parsing is to construct an abstract syntax tree -// todo: improve test-ability of parser - pub fn parse(source: &str) ->Result, Vec>> { let token_iter = Token::lexer(source).spanned().map(|(token, span)| (token.unwrap_or(Token::Error), span.into())); let end_of_input: SimpleSpan = (0..source.len()).into(); @@ -45,6 +43,7 @@ where } .or(expr.clone().delimited_by(just(Token::LParen), just(Token::RParen))); + let mul_div = atom.clone().foldl( choice(( just(Token::Multiply).to(BinaryOp::Multiply), @@ -53,7 +52,7 @@ where .then(atom) .then_ignore(just(Token::NewLine).or_not()) .repeated(), - |lhs, (op, rhs)| Expr::Binary ( Binary { + |lhs, (op, rhs)| Expr::BinaryExpr ( Binary { lhs: Box::new(lhs), operator: op, rhs: Box::new(rhs), @@ -68,7 +67,7 @@ where .then(mul_div) .then_ignore(just(Token::NewLine).or_not()) .repeated(), - |lhs, (op, rhs)| Expr::Binary ( Binary { + |lhs, (op, rhs)| Expr::BinaryExpr ( Binary { lhs: Box::new(lhs), operator: op, rhs: Box::new(rhs), @@ -82,8 +81,8 @@ where .ignore_then(ident) .then_ignore(just(Token::Assign)) .then(expr.clone()) - .then_ignore(just(Token::NewLine)) - .map(|(name, rhs)| Expr::Var ( Var { + .then_ignore(just(Token::NewLine).or_not()) + .map(|(name, rhs)| Expr::VarExpr ( Var { ty: None, ident: name, value: Box::new(rhs), @@ -108,14 +107,48 @@ where } -pub fn lex(source: &str) -> Vec { - Token::lexer(&source) - .filter_map(|t| t.ok()).collect() -} - #[cfg(test)] mod tests { use super::*; + + #[test] + fn test_unary_expr() { + let negate_two = parse("-2"); + assert!(negate_two.is_ok()); + assert_eq!( + negate_two.clone().unwrap(), + vec![Expr::UnaryExpr(Unary { + operator: UnaryOp::Minus, + operand: Box::new(Expr::IntLiteral(2)), + })] + ) + } - + #[test] + fn test_binary_expr() { + let sum = parse("1 + 2"); + assert!(sum.is_ok()); + assert_eq!( + sum.clone().unwrap(), + vec![Expr::BinaryExpr(Binary { + lhs: Box::new(Expr::IntLiteral(1)), + operator: BinaryOp::Add, + rhs: Box::new(Expr::IntLiteral(2)) + })] + ) + } + + #[test] + fn test_variable_decl() { + let var_without_expl_type = parse("var x = 12"); + assert!(var_without_expl_type.is_ok()); + assert_eq!( + var_without_expl_type.clone().unwrap(), + vec![Expr::VarExpr(Var { + ty: None, + ident: String::from("x"), + value: Box::new(Expr::IntLiteral(12)) + })] + ) + } } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index e9bbeff..a11075d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,7 @@ use logos::Logos; mod language_frontend; -use crate::language_frontend::abstract_syntax_tree::parser::lex; + use crate::{ language_frontend::lexer::tokens::Token, language_frontend::abstract_syntax_tree::parser::parse};