fddl/tests/parser_tests.rs
2025-05-29 22:34:57 -04:00

149 lines
4.9 KiB
Rust

use fddl::lexer::Lexer;
use fddl::parser::Parser;
use fddl::parser::ast::{Statement, Expression, Literal, Operator};
#[test]
fn test_simple_print_statement_number() {
let source = String::from("print 123;");
let mut lexer = Lexer::new(source);
let tokens = lexer.scan_tokens();
let mut parser = Parser::new(tokens);
let program_ast = parser.parse_program();
let expected_ast = vec![
Statement::PrintStatement(
Expression::Literal(Literal::Number(123.0))
)
];
assert_eq!(program_ast, expected_ast, "AST for 'print 123;' did not match.");
}
#[test]
fn test_variable_declaration_with_initializer() {
let source = String::from("let x = 10;");
let mut lexer = Lexer::new(source);
let tokens = lexer.scan_tokens();
let mut parser = Parser::new(tokens);
let program_ast = parser.parse_program();
let expected_ast = vec![
Statement::VariableDeclaration(
"x".to_string(),
Some(Expression::Literal(Literal::Number(10.0)))
)
];
assert_eq!(program_ast, expected_ast, "AST for 'let x = 10;' did not match.");
}
#[test]
fn test_unary_not_expression() {
let source = String::from("print not true;");
let mut lexer = Lexer::new(source);
let tokens = lexer.scan_tokens();
let mut parser = Parser::new(tokens);
let program_ast = parser.parse_program();
let expected_ast = vec![
Statement::PrintStatement(
Expression::Unary(
Operator::Not, // Assuming Operator::Not exists from previous steps
Box::new(Expression::Literal(Literal::Boolean(true)))
)
)
];
assert_eq!(program_ast, expected_ast, "AST for 'print not true;' did not match.");
}
#[test]
fn test_binary_precedence() {
let source = String::from("print 1 + 2 * 3;");
let mut lexer = Lexer::new(source);
let tokens = lexer.scan_tokens();
let mut parser = Parser::new(tokens);
let program_ast = parser.parse_program();
let expected_ast = vec![
Statement::PrintStatement(
Expression::Binary(
Box::new(Expression::Literal(Literal::Number(1.0))),
Operator::Plus,
Box::new(Expression::Binary(
Box::new(Expression::Literal(Literal::Number(2.0))),
Operator::Multiply,
Box::new(Expression::Literal(Literal::Number(3.0)))
))
)
)
];
assert_eq!(program_ast, expected_ast, "AST for 'print 1 + 2 * 3;' did not match.");
}
#[test]
fn test_simple_function_call_statement() {
let source = String::from("my_func();"); // As an expression statement
let mut lexer = Lexer::new(source);
let tokens = lexer.scan_tokens();
let mut parser = Parser::new(tokens);
let program_ast = parser.parse_program();
let expected_ast = vec![
Statement::ExpressionStatement(
Expression::FunctionCall(
Box::new(Expression::Variable("my_func".to_string())),
Vec::new() // No arguments
)
)
];
assert_eq!(program_ast, expected_ast, "AST for 'my_func();' did not match.");
}
#[test]
fn test_assignment_statement() {
let source = String::from("count = count + 1;");
let mut lexer = Lexer::new(source);
let tokens = lexer.scan_tokens();
let mut parser = Parser::new(tokens);
let program_ast = parser.parse_program();
let expected_ast = vec![
Statement::Assignment { // Assuming you added this variant to Statement
target_name: "count".to_string(),
value: Expression::Binary(
Box::new(Expression::Variable("count".to_string())),
Operator::Plus,
Box::new(Expression::Literal(Literal::Number(1.0)))
)
}
];
assert_eq!(program_ast, expected_ast, "AST for 'count = count + 1;' did not match.");
}
#[test]
fn test_if_else_statement_with_blocks() {
let source = String::from("if (x < 10) { print \"small\"; } else { print \"large\"; }");
let mut lexer = Lexer::new(source);
let tokens = lexer.scan_tokens();
let mut parser = Parser::new(tokens);
let program_ast = parser.parse_program();
let expected_ast = vec![
Statement::IfStatement(
Expression::Binary( // Condition: x < 10
Box::new(Expression::Variable("x".to_string())),
Operator::Less,
Box::new(Expression::Literal(Literal::Number(10.0)))
),
Box::new(Statement::Block(vec![ // Then branch
Statement::PrintStatement(Expression::Literal(Literal::String("small".to_string())))
])),
Some(Box::new(Statement::Block(vec![ // Else branch
Statement::PrintStatement(Expression::Literal(Literal::String("large".to_string())))
])))
)
];
assert_eq!(program_ast, expected_ast, "AST for if-else statement did not match.");
}