#![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_float_literal_in_struct_field_initialization() {
let source = r#"
pub struct AStarCell {
pub walkable: bool,
pub cost: f32,
}
pub fn create_cells() -> Vec<AStarCell> {
let mut cells = Vec::new()
cells.push(AStarCell { walkable: true, cost: 1.0 })
cells
}
"#;
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:\n{}", rust_code);
assert!(
rust_code.contains("cost: 1.0_f32") || rust_code.contains("cost: 1.0f32"),
"Struct field literal should match field type (f32).\nGenerated:\n{}",
rust_code
);
assert!(
!rust_code.contains("cost: 1.0_f64"),
"Should not generate f64 when field is f32.\nGenerated:\n{}",
rust_code
);
}
#[test]
fn test_float_literal_in_binary_op_with_f32() {
let source = r#"
pub fn calculate_diagonal_cost(cost: f32) -> f32 {
cost * 1.414
}
"#;
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 binary op:\n{}", rust_code);
assert!(
rust_code.contains("1.414_f32") || rust_code.contains("1.414f32"),
"Binary op literal should match operand type (f32).\nGenerated:\n{}",
rust_code
);
assert!(
!rust_code.contains("1.414_f64"),
"Should not generate f64 when operating on f32.\nGenerated:\n{}",
rust_code
);
}
#[test]
fn test_hashmap_insert_float_value_type() {
let source = r#"
use std::collections::HashMap
pub fn initialize_scores() -> HashMap<(i32, i32), f32> {
let mut scores = HashMap::new()
scores.insert((0, 0), 0.0)
scores
}
"#;
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 HashMap insert:\n{}", rust_code);
assert!(
rust_code.contains("0.0_f32") || rust_code.contains("0.0f32"),
"HashMap insert value should match value type (f32).\nGenerated:\n{}",
rust_code
);
}
#[test]
fn test_method_call_f32_params_same_module() {
let source = r#"
pub struct Voxelizer {}
impl Voxelizer {
pub fn voxelize(self, x: f32, y: f32, z: f32, size: f32, sx: i32, sy: i32, sz: i32) -> i32 {
0
}
}
pub fn test_voxelize() {
let v = Voxelizer {}
let grid = v.voxelize(0.0, 0.0, 0.0, 0.0625, 64, 64, 64)
}
"#;
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);
assert!(
rust_code.contains("0.0_f32") && rust_code.contains("0.0625_f32"),
"Method call float args should match param types (f32).\nGenerated:\n{}",
rust_code
);
assert!(
!rust_code.contains("0.0_f64") && !rust_code.contains("0.0625_f64"),
"Should not generate f64 when params are f32.\nGenerated:\n{}",
rust_code
);
}