#![cfg(any(
not(any(
feature = "parser_tests",
feature = "analyzer_tests",
feature = "codegen_tests",
feature = "interpreter_tests",
feature = "conformance_tests",
feature = "integration_tests",
)),
feature = "analyzer_tests",
))]
use windjammer::*;
#[test]
fn test_multiple_float_literals_without_locations_get_unique_ids() {
let source = r#"
pub fn func1() -> f32 {
1.0
}
pub fn func2() -> f32 {
2.0
}
pub fn func3() -> f64 {
3.0
}
"#;
let mut lexer = lexer::Lexer::new(source);
let tokens = lexer.tokenize_with_locations();
let mut parser = parser::Parser::new(tokens);
let program = parser.parse().expect("Failed to parse");
let mut float_inference = type_inference::FloatInference::new();
float_inference.infer_program(&program);
if !float_inference.errors.is_empty() {
panic!("Float inference errors: {:?}", float_inference.errors);
}
let mut analyzer = analyzer::Analyzer::new();
let (analyzed, _signatures, _trait_methods) = analyzer
.analyze_program(&program)
.expect("Failed to analyze");
let registry = analyzer::SignatureRegistry::new();
let mut generator = codegen::CodeGenerator::new(registry, CompilationTarget::Rust);
generator.set_float_inference(float_inference);
let rust_code = generator.generate_program(&program, &analyzed);
eprintln!("Generated code:\n{}", rust_code);
let func1_has_f32 = rust_code.contains("pub fn func1() -> f32")
&& (rust_code.contains("1.0_f32") || rust_code.contains("1.0f32"));
let func2_has_f32 = rust_code.contains("pub fn func2() -> f32")
&& (rust_code.contains("2.0_f32") || rust_code.contains("2.0f32"));
let func3_has_f64 = rust_code.contains("pub fn func3() -> f64")
&& (rust_code.contains("3.0_f64") || rust_code.contains("3.0f64"));
assert!(
func1_has_f32,
"func1 should use f32 literals.\nGenerated:\n{}",
rust_code
);
assert!(
func2_has_f32,
"func2 should use f32 literals.\nGenerated:\n{}",
rust_code
);
assert!(
func3_has_f64,
"func3 should use f64 literals.\nGenerated:\n{}",
rust_code
);
assert!(
!rust_code.contains("1.0_f64"),
"func1 should not generate f64"
);
assert!(
!rust_code.contains("2.0_f64"),
"func2 should not generate f64"
);
}
#[test]
fn test_if_else_branches_distinct_float_types() {
let source = r#"
pub fn get_value(flag: bool) -> f32 {
if flag {
1.5
} else {
2.5
}
}
pub fn get_other(flag: bool) -> f64 {
if flag {
3.5
} else {
4.5
}
}
"#;
let mut lexer = lexer::Lexer::new(source);
let tokens = lexer.tokenize_with_locations();
let mut parser = parser::Parser::new(tokens);
let program = parser.parse().expect("Failed to parse");
let mut float_inference = type_inference::FloatInference::new();
float_inference.infer_program(&program);
if !float_inference.errors.is_empty() {
panic!("Float inference errors: {:?}", float_inference.errors);
}
let mut analyzer = analyzer::Analyzer::new();
let (analyzed, _signatures, _trait_methods) = analyzer
.analyze_program(&program)
.expect("Failed to analyze");
let registry = analyzer::SignatureRegistry::new();
let mut generator = codegen::CodeGenerator::new(registry, CompilationTarget::Rust);
generator.set_float_inference(float_inference);
let rust_code = generator.generate_program(&program, &analyzed);
eprintln!("Generated if-else code:\n{}", rust_code);
assert!(
rust_code.contains("1.5_f32") || rust_code.contains("1.5f32"),
"get_value if branch should use f32.\nGenerated:\n{}",
rust_code
);
assert!(
rust_code.contains("2.5_f32") || rust_code.contains("2.5f32"),
"get_value else branch should use f32.\nGenerated:\n{}",
rust_code
);
assert!(
rust_code.contains("3.5_f64") || rust_code.contains("3.5f64"),
"get_other if branch should use f64.\nGenerated:\n{}",
rust_code
);
assert!(
rust_code.contains("4.5_f64") || rust_code.contains("4.5f64"),
"get_other else branch should use f64.\nGenerated:\n{}",
rust_code
);
}