use crate::executor::JITExecutor;
use shape_runtime::engine::{ProgramExecutor, ShapeEngine};
use shape_runtime::initialize_shared_runtime;
use shape_wire::WireValue;
fn jit_eval(source: &str) -> WireValue {
let _ = initialize_shared_runtime();
let mut engine = ShapeEngine::new().expect("engine creation failed");
let program = shape_ast::parse_program(source).expect("parse failed");
let result = JITExecutor::new()
.execute_program(&mut engine, &program)
.expect("JIT execution failed");
result.wire_value
}
fn jit_eval_err(source: &str) -> String {
let _ = initialize_shared_runtime();
let mut engine = ShapeEngine::new().expect("engine creation failed");
let program = shape_ast::parse_program(source).expect("parse failed");
match JITExecutor::new().execute_program(&mut engine, &program) {
Ok(r) => panic!("expected runtime error, got Ok({:?})", r.wire_value),
Err(e) => format!("{:?}", e),
}
}
fn jit_expect_int(source: &str, expected: i64) {
match jit_eval(source) {
WireValue::Integer(n) => {
assert_eq!(n, expected, "Expected integer {}, got {}", expected, n);
}
WireValue::Number(n) => {
assert!(
(n - expected as f64).abs() < 1e-9,
"Expected integer {} (got Number {})",
expected,
n
);
}
other => panic!("Expected Integer({}), got {:?}", expected, other),
}
}
#[test]
fn jit_unannotated_array_param_index_in_bounds() {
jit_expect_int(
r#"
fn get(xs, i) { xs[i] }
let data = [1, 2, 3]
let mut r = 0
for n in 0..500 { r = get(data, 1) }
r
"#,
2,
);
}
#[test]
fn jit_unannotated_single_array_param_index() {
jit_expect_int(
r#"
fn get(xs) { xs[0] }
let data = [7, 8, 9]
let mut r = 0
for n in 0..500 { r = get(data) }
r
"#,
7,
);
}
#[test]
fn jit_annotated_array_param_index_in_bounds() {
jit_expect_int(
r#"
fn get(xs: Array<int>, i: int) -> int { xs[i] }
let data = [1, 2, 3]
let mut r = 0
for n in 0..500 { r = get(data, 1) }
r
"#,
2,
);
}
#[test]
fn jit_unannotated_array_param_index_out_of_bounds_raises() {
let err = jit_eval_err(
r#"
fn get(xs, i) { xs[i] }
let data = [1, 2, 3]
let mut r = 0
for n in 0..500 { r = get(data, 10) }
r
"#,
);
assert!(
err.to_lowercase().contains("out of bounds")
|| err.to_lowercase().contains("index"),
"expected an out-of-bounds runtime error, got: {}",
err
);
}
#[test]
fn jit_unannotated_number_array_param_index() {
match jit_eval(
r#"
fn get(xs, i) { xs[i] }
let data = [1.5, 2.5, 3.5]
let mut r = 0.0
for n in 0..500 { r = get(data, 2) }
r
"#,
) {
WireValue::Number(n) => {
assert!((n - 3.5).abs() < 1e-9, "expected 3.5, got {}", n);
}
other => panic!("expected Number(3.5), got {:?}", other),
}
}