From 64a4665dfd998d674e18b9d221d89793b7d209e7 Mon Sep 17 00:00:00 2001 From: Edgar Luque Date: Fri, 16 Feb 2024 11:09:49 +0100 Subject: [PATCH] fix: fix a miscompilation --- lib/edlang_codegen_llvm/src/codegen.rs | 2 +- lib/edlang_driver/tests/programs.rs | 73 ++++++++++++++++++- lib/edlang_driver/tests/programs/factorial.ed | 4 +- lib/edlang_lowering/src/lib.rs | 1 + programs/factorial.ed | 2 +- 5 files changed, 77 insertions(+), 5 deletions(-) diff --git a/lib/edlang_codegen_llvm/src/codegen.rs b/lib/edlang_codegen_llvm/src/codegen.rs index 978bc018b..b2b9f69a9 100644 --- a/lib/edlang_codegen_llvm/src/codegen.rs +++ b/lib/edlang_codegen_llvm/src/codegen.rs @@ -570,7 +570,7 @@ fn compile_bin_op<'ctx>( .as_basic_value_enum() } else { ctx.builder - .build_int_add(lhs_value.into_int_value(), rhs_value.into_int_value(), "")? + .build_int_mul(lhs_value.into_int_value(), rhs_value.into_int_value(), "")? .as_basic_value_enum() }; (value, lhs_ty) diff --git a/lib/edlang_driver/tests/programs.rs b/lib/edlang_driver/tests/programs.rs index 9c88ce2fc..75080be9e 100644 --- a/lib/edlang_driver/tests/programs.rs +++ b/lib/edlang_driver/tests/programs.rs @@ -7,7 +7,16 @@ mod common; #[test_case(include_str!("programs/simple.ed"), "simple", false, 1, &["a", "b"] ; "simple.ed 3")] #[test_case(include_str!("programs/basic_ifs.ed"), "basic_ifs", false, 9, &[] ; "basic_ifs")] #[test_case(include_str!("programs/while.ed"), "while", false, 10, &[] ; "r#while")] -#[test_case(include_str!("programs/factorial.ed"), "factorial", false, 6, &[] ; "factorial")] +#[test_case(include_str!("programs/factorial.ed"), "factorial", false, 24, &[] ; "factorial")] +#[test_case(TEST_ADD, "TEST_ADD", false, 2, &[] ; "TEST_ADD")] +#[test_case(TEST_SUB, "TEST_SUB", false, 1, &[] ; "TEST_SUB")] +#[test_case(TEST_MUL, "TEST_MUL", false, 4, &[] ; "TEST_MUL")] +#[test_case(TEST_DIV, "TEST_DIV", false, 2, &[] ; "TEST_DIV")] +#[test_case(TEST_REM, "TEST_REM", false, 0, &[] ; "TEST_REM")] +#[test_case(TEST_IF_BOTH, "TEST_IF_BOTH", false, 1, &[] ; "TEST_IF_BOTH")] +#[test_case(TEST_IF_BOTH, "TEST_IF_BOTH", false, 2, &["a"] ; "TEST_IF_BOTH args")] +#[test_case(TEST_IF_NO_ELSE, "TEST_IF_NO_ELSE", false, 1, &[] ; "TEST_IF_NO_ELSE")] +#[test_case(TEST_IF_NO_ELSE, "TEST_IF_NO_ELSE", false, 2, &["a"] ; "TEST_IF_NO_ELSE args")] fn example_tests(source: &str, name: &str, is_library: bool, status_code: i32, args: &[&str]) { let program = compile_program(source, name, is_library).unwrap(); @@ -21,3 +30,65 @@ fn example_tests(source: &str, name: &str, is_library: bool, status_code: i32, a name ); } + +const TEST_ADD: &str = r#" +mod Main { + pub fn main() -> i32 { + let b: i32 = 1 + 1; + return b; + } +} +"#; +const TEST_SUB: &str = r#" +mod Main { + pub fn main() -> i32 { + let b: i32 = 2 - 1; + return b; + } +} +"#; +const TEST_MUL: &str = r#" +mod Main { + pub fn main() -> i32 { + let b: i32 = 2 * 2; + return b; + } +} +"#; +const TEST_DIV: &str = r#" +mod Main { + pub fn main() -> i32 { + let b: i32 = 4 / 2; + return b; + } +} +"#; +const TEST_REM: &str = r#" +mod Main { + pub fn main() -> i32 { + let b: i32 = 4 % 2; + return b; + } +} +"#; +const TEST_IF_BOTH: &str = r#" +mod Main { + pub fn main(argc: i32) -> i32 { + if argc == 1 { + return 1; + } else { + return 2; + } + } +} +"#; +const TEST_IF_NO_ELSE: &str = r#" +mod Main { + pub fn main(argc: i32) -> i32 { + if argc == 1 { + return 1; + } + return 2; + } +} +"#; diff --git a/lib/edlang_driver/tests/programs/factorial.ed b/lib/edlang_driver/tests/programs/factorial.ed index 60f6d6fad..28a8e6772 100644 --- a/lib/edlang_driver/tests/programs/factorial.ed +++ b/lib/edlang_driver/tests/programs/factorial.ed @@ -1,11 +1,11 @@ mod Main { pub fn main() -> i32 { - let b: i32 = factorial(3); + let b: i32 = factorial(4); return b; } fn factorial(n: i32) -> i32 { - if n == 1 { + if n == 0 { return n; } else { return n * factorial(n - 1); diff --git a/lib/edlang_lowering/src/lib.rs b/lib/edlang_lowering/src/lib.rs index 426d0195a..1d3be6ba3 100644 --- a/lib/edlang_lowering/src/lib.rs +++ b/lib/edlang_lowering/src/lib.rs @@ -459,6 +459,7 @@ fn lower_binary_expr( ) -> (ir::RValue, TypeKind) { trace!("lowering binary op: {:?}", op); + // todo: if lhs or rhs is a simple place, dont make another temporary? let (lhs, lhs_ty) = if type_hint.is_none() { let ty = find_expr_type(builder, lhs) .unwrap_or_else(|| find_expr_type(builder, rhs).expect("cant find type")); diff --git a/programs/factorial.ed b/programs/factorial.ed index c7d717845..7123369fb 100644 --- a/programs/factorial.ed +++ b/programs/factorial.ed @@ -1,6 +1,6 @@ mod Main { pub fn main() -> i32 { - let b: i32 = factorial(2); + let b: i32 = factorial(4); return b; }