diff --git a/src/jit/engine.rs b/src/jit/engine.rs index d31b929..0c9c130 100644 --- a/src/jit/engine.rs +++ b/src/jit/engine.rs @@ -76,19 +76,29 @@ mod tests { } } + fn jit_fn(source: &str) -> fn(I) -> O { + let code_ptr = jit_compile(source); + unsafe { std::mem::transmute::<_, fn(I) -> O>(code_ptr) } + } + #[test] fn simple_math() { let source = "simple_math() i64 { (1 + 2) * ((4 + 5) / 3) }"; - let code_ptr = jit_compile(source); - let code_fn = unsafe { std::mem::transmute::<_, fn() -> i64>(code_ptr) }; - assert_eq!(code_fn(), 9); + let code_fn = jit_fn::<(), i64>(source); + assert_eq!(code_fn(()), 9); } #[test] fn simple_args() { let source = "simple_args(i64 a, i64 b) i64 { a * (a + b) }"; - let code_ptr = jit_compile(source); - let code_fn = unsafe { std::mem::transmute::<_, fn(i64, i64) -> i64>(code_ptr) }; - assert_eq!(code_fn(2, 3), 10); + let code_fn = jit_fn::<(i64, i64), i64>(source); + assert_eq!(code_fn((2, 3)), 10); + } + + #[test] + fn let_statement() { + let source = "let_stmt(i64 a, i64 b) i64 { let c = a + b; b * c }"; + let code_fn = jit_fn::<(i64, i64), i64>(source); + assert_eq!(code_fn((2, 3)), 15); } } diff --git a/src/jit/translate.rs b/src/jit/translate.rs index 1835b50..7e42128 100644 --- a/src/jit/translate.rs +++ b/src/jit/translate.rs @@ -66,8 +66,8 @@ impl<'a> FunctionTranslator<'a> { } } - if fn_impl.body.statements.len() > 0 { - unimplemented!("Function body statements are unimplemented"); + for stmt in fn_impl.body.statements.iter() { + self.translate_statement(stmt); } if let Some((tail_expr, _)) = return_info { @@ -79,6 +79,24 @@ impl<'a> FunctionTranslator<'a> { self.builder.finalize(); } + pub fn translate_statement(&mut self, stmt: &ast::Statement) { + use ast::Statement::*; + match stmt { + Expr(expr) => { + self.translate_expr(expr); + } + Let { var, mutable, expr } => { + if *mutable { + unimplemented!("Mutable variables") + } + + let val = self.translate_expr(expr); + self.locals.push((var.to_string(), val)); + } + _ => unimplemented!(), + } + } + pub fn translate_expr(&mut self, expr: &ast::Expr) -> Value { use ast::Expr::*; match expr {