use core::mem;
use zkc::jit;
fn main() -> Result<(), String> {
let mut jit = jit::JIT::default();
println!("the answer is: {}", run_foo(&mut jit)?);
println!(
"recursive_fib(10) = {}",
run_recursive_fib_code(&mut jit, 10)?
);
println!(
"iterative_fib(10) = {}",
run_iterative_fib_code(&mut jit, 10)?
);
run_hello(&mut jit)?;
Ok(())
}
fn run_foo(jit: &mut jit::JIT) -> Result<isize, String> {
unsafe { run_code(jit, FOO_CODE, (1, 0)) }
}
fn run_recursive_fib_code(jit: &mut jit::JIT, input: isize) -> Result<isize, String> {
unsafe { run_code(jit, RECURSIVE_FIB_CODE, input) }
}
fn run_iterative_fib_code(jit: &mut jit::JIT, input: isize) -> Result<isize, String> {
unsafe { run_code(jit, ITERATIVE_FIB_CODE, input) }
}
fn run_hello(jit: &mut jit::JIT) -> Result<isize, String> {
jit.create_data("hello_string", "hello world!\0".as_bytes().to_vec())?;
unsafe { run_code(jit, HELLO_CODE, ()) }
}
unsafe fn run_code<I, O>(jit: &mut jit::JIT, code: &str, input: I) -> Result<O, String> {
let code_ptr = jit.compile(code)?;
let code_fn = mem::transmute::<_, fn(I) -> O>(code_ptr);
Ok(code_fn(input))
}
const FOO_CODE: &str = r#"
fn foo(a, b) -> (c) {
c = if a {
if b {
30
} else {
40
}
} else {
50
}
c = c + 2
}
"#;
const RECURSIVE_FIB_CODE: &str = r#"
fn recursive_fib(n) -> (r) {
r = if n == 0 {
0
} else {
if n == 1 {
1
} else {
recursive_fib(n - 1) + recursive_fib(n - 2)
}
}
}
"#;
const ITERATIVE_FIB_CODE: &str = r#"
fn iterative_fib(n) -> (r) {
if n == 0 {
r = 0
} else {
n = n - 1
a = 0
r = 1
while n != 0 {
t = r
r = r + a
a = t
n = n - 1
}
}
}
"#;
const HELLO_CODE: &str = r#"
fn hello() -> (r) {
puts(&hello_string)
}
"#;