From ad26dc1baaf758a895ff8b17495777f1810db28c Mon Sep 17 00:00:00 2001 From: Georg Schmid Date: Mon, 8 Jun 2020 17:19:05 +0200 Subject: [PATCH] Move integration tests out (to depend on binary) and fix application arguments --- Cargo.toml | 4 ++++ src/bin/l3jit.rs | 8 ------- src/l3/codegen.rs | 48 ++++++++++-------------------------------- src/tests/run_tests.rs | 37 ++++++++++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 45 deletions(-) create mode 100644 src/tests/run_tests.rs diff --git a/Cargo.toml b/Cargo.toml index 7ee8240..6ee916f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,10 @@ path = "src/lib.rs" name = "l3jit" path = "src/bin/l3jit.rs" +[[test]] +name = "run_tests" +path = "src/tests/run_tests.rs" + [dependencies] l3_llvm_runtime = { path = "runtime" } pest = "2.1.3" diff --git a/src/bin/l3jit.rs b/src/bin/l3jit.rs index 0aa2743..b438355 100644 --- a/src/bin/l3jit.rs +++ b/src/bin/l3jit.rs @@ -6,14 +6,6 @@ fn run_str<'a>(example_str: &'a str) { l3::codegen::compile_and_run_program(&program) } -fn example_halt() { - run_str("(halt 3)"); -} - -fn example_if_basic() { - run_str("(let* ((c1 (cnt () (halt 1))) (c2 (cnt () (halt 2)))) (if (@< 2 1) c1 c2))"); -} - fn main() { use std::io::{self, Read}; let mut buffer = String::new(); diff --git a/src/l3/codegen.rs b/src/l3/codegen.rs index 53d6d1c..1216c6e 100644 --- a/src/l3/codegen.rs +++ b/src/l3/codegen.rs @@ -12,7 +12,7 @@ use inkwell::context::Context; use inkwell::module::Module; use inkwell::passes::PassManager; use inkwell::types::{BasicTypeEnum, IntType}; -use inkwell::values::{BasicValue, FunctionValue, IntValue, PointerValue}; +use inkwell::values::{BasicValue, BasicValueEnum, FunctionValue, IntValue, PointerValue}; use inkwell::{IntPredicate, OptimizationLevel}; type CgResult = Result; @@ -143,7 +143,8 @@ impl<'a, 'ctx> Codegen<'a, 'ctx> { impl<'a, 'ctx> State<'a, 'ctx> { fn add_var(&mut self, name: &Name<'a>) -> PointerValue<'ctx> { let ptr_value = self.builder.build_alloca(value_type(self.context), name.0); - self.vars.insert(*name, ptr_value).unwrap(); + let old_opt = self.vars.insert(*name, ptr_value); + assert!(old_opt.is_none()); ptr_value } @@ -211,15 +212,21 @@ impl<'a, 'ctx> Codegen<'a, 'ctx> { ret_cnt, args, } => { - // TODO: Handle args! let fun = self.program.get_function(fun_name); + assert_eq!(fun.params.len(), args.len()); let fn_value = get_fn_value(self.module, fun_name.0); - let result = self.builder.build_call(fn_value, &vec![], "call_fun"); + let args = args + .iter() + .map(|arg| self.arg_value(arg).into()) + .collect::>(); + + let result = self.builder.build_call(fn_value, &args, "call_fun"); let result = result .try_as_basic_value() .left() .expect("Failed to generate call") .into_int_value(); + if *ret_cnt == self.ret_cnt_name { self.emit_cnt_call_indirect(result); } else { @@ -401,36 +408,3 @@ pub fn compile_and_run_program(program: &Program) -> () { } } } - -#[cfg(test)] -mod tests { - extern crate assert_cmd; - use assert_cmd::Command; - - macro_rules! test_run { - ($name:ident, $example:expr, $output:expr, $exit:expr) => { - #[test] - fn $name() { - let mut cmd = Command::cargo_bin("l3jit").unwrap(); - let assert = cmd.write_stdin($example).assert().code($exit); - if let Some::<&'static str>(output) = $output { - assert.stdout(output); - } - } - }; - } - - test_run!(test_halt1, "(halt 0)", None, 0); - test_run!( - test_if_lt, - "(let* ((c1 (cnt () (halt 1))) (c2 (cnt () (halt 2)))) (if (@< 2 1) c1 c2))", - None, - 2 - ); - test_run!( - test_if_le, - "(let* ((c1 (cnt () (halt 1))) (c2 (cnt () (halt 2)))) (if (@<= 2 2) c1 c2))", - None, - 1 - ); -} diff --git a/src/tests/run_tests.rs b/src/tests/run_tests.rs new file mode 100644 index 0000000..ab69969 --- /dev/null +++ b/src/tests/run_tests.rs @@ -0,0 +1,37 @@ +extern crate l3_llvm_runtime; + +extern crate assert_cmd; +use assert_cmd::Command; + +macro_rules! test_run { + ($name:ident, $example:expr, $output:expr, $exit:expr) => { + #[test] + fn $name() { + let mut cmd = Command::cargo_bin("l3jit").unwrap(); + let assert = cmd.write_stdin($example).assert().code($exit); + if let Some::<&'static str>(output) = $output { + assert.stdout(output); + } + } + }; +} + +test_run!(test_halt1, "(halt 0)", None, 0); +test_run!( + test_if_lt, + "(let* ((c1 (cnt () (halt 1))) (c2 (cnt () (halt 2)))) (if (@< 2 1) c1 c2))", + None, + 2 +); +test_run!( + test_if_le, + "(let* ((c1 (cnt () (halt 1))) (c2 (cnt () (halt 2)))) (if (@<= 2 2) c1 c2))", + None, + 1 +); +test_run!( + test_app_second, + "(let* ((f (fun (r x y) (r y))) (c (cnt (z) (halt z)))) (f c 1 2))", + None, + 2 +);