diff --git a/src/block_compiler.rs b/src/block_compiler.rs index 37cff2f..fbdd2c9 100644 --- a/src/block_compiler.rs +++ b/src/block_compiler.rs @@ -398,3 +398,66 @@ impl Block2JITCompiler { self.bjit2jit(&blkast) } } + +#[cfg(test)] +mod test { + use super::*; + + macro_rules! assert_float_eq { + ($a:expr, $b:expr) => { + if ($a - $b).abs() > 0.0001 { + panic!( + r#"assertion failed: `(left == right)` + left: `{:?}`, + right: `{:?}`"#, + $a, $b + ) + } + }; + } + + use synfx_dsp_jit::{get_standard_library, DSPNodeContext, JIT, ASTFun, DSPFunction}; + + fn new_jit_fun(mut f: F) -> (Rc>, Box) { + use crate::block_compiler::{BlkJITCompileError, Block2JITCompiler}; + use crate::blocklang::BlockFun; + use crate::blocklang_def; + + let lang = blocklang_def::setup_hxdsp_block_language(); + let mut bf = BlockFun::new(lang.clone()); + + f(&mut bf); + + let mut compiler = Block2JITCompiler::new(bf.block_language()); + let ast = compiler.compile(&bf).expect("blk2jit compiles"); + let lib = get_standard_library(); + let ctx = DSPNodeContext::new_ref(); + let jit = JIT::new(lib, ctx.clone()); + let mut fun = jit.compile(ASTFun::new(ast)).expect("jit compiles"); + + fun.init(44100.0, None); + + (ctx, fun) + } + + + #[test] + fn check_blocklang_sig1() { + let (ctx, mut fun) = new_jit_fun(|bf| { + bf.instanciate_at(0, 0, 1, "value", Some("0.3".to_string())).unwrap(); + bf.instanciate_at(0, 1, 1, "set", Some("&sig1".to_string())).unwrap(); + bf.instanciate_at(0, 0, 2, "value", Some("-0.3".to_string())).unwrap(); + bf.instanciate_at(0, 1, 2, "set", Some("&sig2".to_string())).unwrap(); + bf.instanciate_at(0, 0, 3, "value", Some("-1.3".to_string())).unwrap(); + }); + + let (s1, s2, ret) = fun.exec_2in_2out(0.0, 0.0); + + assert_float_eq!(s1, 0.3); + assert_float_eq!(s2, -0.3); + assert_float_eq!(ret, -1.3); + + ctx.borrow_mut().free(); + } + +} diff --git a/tests/blocklang.rs b/tests/blocklang.rs index 67924b4..6eda8cd 100644 --- a/tests/blocklang.rs +++ b/tests/blocklang.rs @@ -5,92 +5,82 @@ mod common; use common::*; -fn setup() -> (Matrix, NodeExecutor) { - let (node_conf, node_exec) = new_node_engine(); - let mut matrix = Matrix::new(node_conf, 3, 3); - - let mut chain = MatrixCellChain::new(CellDir::B); - chain - .node_out("code", "sig1") - .set_denorm("in1", 0.5) - .set_denorm("in2", -0.6) - .node_inp("out", "ch1") - .place(&mut matrix, 0, 0) - .unwrap(); - matrix.sync().unwrap(); - - (matrix, node_exec) -} - -#[test] -fn check_blocklang_1() { - let (mut matrix, mut node_exec) = setup(); - - let block_fun = matrix.get_block_function(0).expect("block fun exists"); - { - let mut block_fun = block_fun.lock().expect("matrix lock"); - block_fun.instanciate_at(0, 0, 1, "value", Some("0.3".to_string())); - block_fun.instanciate_at(0, 1, 1, "set", Some("&sig1".to_string())); - } - - matrix.check_block_function(0).expect("no compile error"); - - let res = run_for_ms(&mut node_exec, 25.0); - assert_decimated_feq!(res.0, 50, vec![0.3; 10]); -} - - -// XXX: Test case with 3 outputs, where the first output writes a value used -// by the computation after the first but before the third output. -/* - 0.3 ->3 set a - => -> + set b - get a - => -> - set a - get b - get a + - get b -*/ - -#[test] -fn check_blocklang_2() { - let (mut matrix, mut node_exec) = setup(); - - let block_fun = matrix.get_block_function(0).expect("block fun exists"); - { - let mut block_fun = block_fun.lock().expect("matrix lock"); - - block_fun.instanciate_at(0, 0, 0, "get", Some("in1".to_string())); - block_fun.instanciate_at(0, 0, 1, "value", Some("0.3".to_string())); - block_fun.instanciate_at(0, 1, 0, "+", None); - block_fun.instanciate_at(0, 2, 0, "set", Some("&sig1".to_string())); - - block_fun.instanciate_at(0, 3, 0, "get", Some("in1".to_string())); - block_fun.instanciate_at(0, 3, 1, "get", Some("in2".to_string())); - block_fun.instanciate_at(0, 4, 0, "-", None); - block_fun.instanciate_at(0, 5, 0, "->3", None); - - block_fun.instanciate_at(0, 3, 5, "get", Some("in1".to_string())); - block_fun.instanciate_at(0, 4, 5, "if", None); - block_fun.instanciate_at(1, 0, 0, "value", Some("0.5".to_string())); - block_fun.instanciate_at(2, 0, 0, "value", Some("-0.5".to_string())); - - block_fun.instanciate_at(0, 6, 1, "set", Some("*a".to_string())); - block_fun.instanciate_at(0, 6, 2, "set", Some("x".to_string())); - block_fun.instanciate_at(0, 6, 0, "->", None); - block_fun.instanciate_at(0, 7, 0, "->2", None); - - block_fun.instanciate_at(0, 0, 3, "get", Some("in1".to_string())); - block_fun.instanciate_at(0, 0, 4, "get", Some("in2".to_string())); - block_fun.instanciate_at(0, 1, 3, "/%", None); - block_fun.instanciate_at(0, 2, 3, "->", None); - block_fun.instanciate_at(0, 3, 3, "/%", None); - block_fun.instanciate_at(0, 4, 3, "set", Some("&sig2".to_string())); - block_fun.instanciate_at(0, 4, 4, "set", Some("*ap".to_string())); - } - - matrix.check_block_function(0).expect("no compile error"); - - let res = run_for_ms(&mut node_exec, 25.0); - assert_decimated_feq!(res.0, 50, vec![0.2; 100]); -} +//#[test] +//fn check_blocklang_dir_1() { +// use hexodsp::block_compiler::{BlkJITCompileError, Block2JITCompiler}; +// use hexodsp::blocklang::BlockFun; +// use hexodsp::blocklang_def; +// +// let lang = blocklang_def::setup_hxdsp_block_language(); +// let mut bf = BlockFun::new(lang.clone()); +// block_fun.instanciate_at(0, 0, 1, "value", Some("0.3".to_string())); +// block_fun.instanciate_at(0, 1, 1, "set", Some("&sig1".to_string())); +// +// let mut compiler = Block2JITCompiler::new(block_fun.block_language()); +// let ast = compiler.compile(&block_fun)?; +// let lib = synfx_dsp_jit::get_standard_library(); +// let ctx = synfx_dsp_jit::DSPNodeContext::new_ref(); +// let jit = JIT::new(lib, dsp_ctx.clone()); +// let fun = jit.compile(ASTFun::new(ast))?; +// +// fun.init(44100.0, None); +// +// let (s1, s2, ret) = fun.exec_2in_2out(0.0, 0.0); +// +// ctx.borrow_mut().free(); +//} +// +//// XXX: Test case with 3 outputs, where the first output writes a value used +//// by the computation after the first but before the third output. +// +// 0.3 ->3 set a +// => -> + set b +// get a +// => -> - set a +// get b +// get a + +// get b +//*/ +// +////#[test] +////fn check_blocklang_2() { +//// let (mut matrix, mut node_exec) = setup(); +//// +//// let block_fun = matrix.get_block_function(0).expect("block fun exists"); +//// { +//// let mut block_fun = block_fun.lock().expect("matrix lock"); +//// +//// block_fun.instanciate_at(0, 0, 0, "get", Some("in1".to_string())); +//// block_fun.instanciate_at(0, 0, 1, "value", Some("0.3".to_string())); +//// block_fun.instanciate_at(0, 1, 0, "+", None); +//// block_fun.instanciate_at(0, 2, 0, "set", Some("&sig1".to_string())); +//// +//// block_fun.instanciate_at(0, 3, 0, "get", Some("in1".to_string())); +//// block_fun.instanciate_at(0, 3, 1, "get", Some("in2".to_string())); +//// block_fun.instanciate_at(0, 4, 0, "-", None); +//// block_fun.instanciate_at(0, 5, 0, "->3", None); +//// +//// block_fun.instanciate_at(0, 3, 5, "get", Some("in1".to_string())); +//// block_fun.instanciate_at(0, 4, 5, "if", None); +//// block_fun.instanciate_at(1, 0, 0, "value", Some("0.5".to_string())); +//// block_fun.instanciate_at(2, 0, 0, "value", Some("-0.5".to_string())); +//// +//// block_fun.instanciate_at(0, 6, 1, "set", Some("*a".to_string())); +//// block_fun.instanciate_at(0, 6, 2, "set", Some("x".to_string())); +//// block_fun.instanciate_at(0, 6, 0, "->", None); +//// block_fun.instanciate_at(0, 7, 0, "->2", None); +//// +//// block_fun.instanciate_at(0, 0, 3, "get", Some("in1".to_string())); +//// block_fun.instanciate_at(0, 0, 4, "get", Some("in2".to_string())); +//// block_fun.instanciate_at(0, 1, 3, "/%", None); +//// block_fun.instanciate_at(0, 2, 3, "->", None); +//// block_fun.instanciate_at(0, 3, 3, "/%", None); +//// block_fun.instanciate_at(0, 4, 3, "set", Some("&sig2".to_string())); +//// block_fun.instanciate_at(0, 4, 4, "set", Some("*ap".to_string())); +//// } +//// +//// matrix.check_block_function(0).expect("no compile error"); +//// +//// let res = run_for_ms(&mut node_exec, 25.0); +//// assert_decimated_feq!(res.0, 50, vec![0.2; 100]); +////} diff --git a/tests/node_code.rs b/tests/node_code.rs new file mode 100644 index 0000000..25577a1 --- /dev/null +++ b/tests/node_code.rs @@ -0,0 +1,40 @@ +// Copyright (c) 2022 Weird Constructor +// This file is a part of HexoDSP. Released under GPL-3.0-or-later. +// See README.md and COPYING for details. + +mod common; +use common::*; + +fn setup() -> (Matrix, NodeExecutor) { + let (node_conf, node_exec) = new_node_engine(); + let mut matrix = Matrix::new(node_conf, 3, 3); + + let mut chain = MatrixCellChain::new(CellDir::B); + chain + .node_out("code", "sig1") + .set_denorm("in1", 0.5) + .set_denorm("in2", -0.6) + .node_inp("out", "ch1") + .place(&mut matrix, 0, 0) + .unwrap(); + matrix.sync().unwrap(); + + (matrix, node_exec) +} + +#[test] +fn check_node_code_1() { + let (mut matrix, mut node_exec) = setup(); + + let block_fun = matrix.get_block_function(0).expect("block fun exists"); + { + let mut block_fun = block_fun.lock().expect("matrix lock"); + block_fun.instanciate_at(0, 0, 1, "value", Some("0.3".to_string())); + block_fun.instanciate_at(0, 1, 1, "set", Some("&sig1".to_string())); + } + + matrix.check_block_function(0).expect("no compile error"); + + let res = run_for_ms(&mut node_exec, 25.0); + assert_decimated_feq!(res.0, 50, vec![0.3; 10]); +}