Nearly finished the bjit2jit compiler.
This commit is contained in:
parent
41b0b3b7fc
commit
4d5a4ef865
6 changed files with 305 additions and 216 deletions
|
@ -96,7 +96,7 @@ enum BlkASTNode {
|
||||||
},
|
},
|
||||||
Literal {
|
Literal {
|
||||||
value: f64,
|
value: f64,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BlkASTNode {
|
impl BlkASTNode {
|
||||||
|
@ -169,13 +169,7 @@ impl BlkASTNode {
|
||||||
lbl: &str,
|
lbl: &str,
|
||||||
childs: Vec<(Option<String>, BlkASTRef)>,
|
childs: Vec<(Option<String>, BlkASTRef)>,
|
||||||
) -> BlkASTRef {
|
) -> BlkASTRef {
|
||||||
Rc::new(BlkASTNode::Node {
|
Rc::new(BlkASTNode::Node { id, out, typ: typ.to_string(), lbl: lbl.to_string(), childs })
|
||||||
id,
|
|
||||||
out,
|
|
||||||
typ: typ.to_string(),
|
|
||||||
lbl: lbl.to_string(),
|
|
||||||
childs,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,6 +181,9 @@ pub enum BlkJITCompileError {
|
||||||
ASTMissingOutputLabel(usize),
|
ASTMissingOutputLabel(usize),
|
||||||
NoTmpVarForOutput(usize, String),
|
NoTmpVarForOutput(usize, String),
|
||||||
BadLiteralNumber(String),
|
BadLiteralNumber(String),
|
||||||
|
NodeWithoutID(String),
|
||||||
|
UnknownType(String),
|
||||||
|
TooManyInputs(String, usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Block2JITCompiler {
|
pub struct Block2JITCompiler {
|
||||||
|
@ -260,9 +257,7 @@ impl Block2JITCompiler {
|
||||||
Err(BlkJITCompileError::BadTree(node.clone()))
|
Err(BlkJITCompileError::BadTree(node.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"value" => {
|
"value" => Ok(BlkASTNode::new_literal(&node.0.borrow().lbl)?),
|
||||||
Ok(BlkASTNode::new_literal(&node.0.borrow().lbl)?)
|
|
||||||
}
|
|
||||||
"set" => {
|
"set" => {
|
||||||
if let Some((_in, out, first)) = node.first_child() {
|
if let Some((_in, out, first)) = node.first_child() {
|
||||||
let out = if out.len() > 0 { Some(out) } else { None };
|
let out = if out.len() > 0 { Some(out) } else { None };
|
||||||
|
@ -283,7 +278,6 @@ impl Block2JITCompiler {
|
||||||
area.push(BlkASTNode::new_get(0, &tmp_var));
|
area.push(BlkASTNode::new_get(0, &tmp_var));
|
||||||
self.store_idout_var(id, "", &tmp_var);
|
self.store_idout_var(id, "", &tmp_var);
|
||||||
Ok(BlkASTNode::new_area(area))
|
Ok(BlkASTNode::new_area(area))
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Err(BlkJITCompileError::BadTree(node.clone()))
|
Err(BlkJITCompileError::BadTree(node.clone()))
|
||||||
}
|
}
|
||||||
|
@ -327,11 +321,7 @@ impl Block2JITCompiler {
|
||||||
&tmp_var,
|
&tmp_var,
|
||||||
BlkASTNode::new_get(0, &format!("%{}", i)),
|
BlkASTNode::new_get(0, &format!("%{}", i)),
|
||||||
));
|
));
|
||||||
self.store_idout_var(
|
self.store_idout_var(id, &oname, &tmp_var);
|
||||||
id,
|
|
||||||
&oname,
|
|
||||||
&tmp_var,
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
return Err(BlkJITCompileError::NoOutputAtIdx(optype.to_string(), i));
|
return Err(BlkJITCompileError::NoOutputAtIdx(optype.to_string(), i));
|
||||||
}
|
}
|
||||||
|
@ -371,20 +361,44 @@ impl Block2JITCompiler {
|
||||||
stmt.push(self.bjit2jit(&c)?);
|
stmt.push(self.bjit2jit(&c)?);
|
||||||
}
|
}
|
||||||
Ok(stmts(&stmt[..]))
|
Ok(stmts(&stmt[..]))
|
||||||
},
|
}
|
||||||
BlkASTNode::Set { var, expr } => {
|
BlkASTNode::Set { var, expr } => {
|
||||||
let e = self.bjit2jit(&expr)?;
|
let e = self.bjit2jit(&expr)?;
|
||||||
Ok(assign(var, e))
|
Ok(assign(var, e))
|
||||||
}
|
}
|
||||||
BlkASTNode::Get { id, var: varname } => {
|
BlkASTNode::Get { id, var: varname } => Ok(var(varname)),
|
||||||
Ok(var(varname))
|
BlkASTNode::Node { id, out, typ, lbl, childs } => match &typ[..] {
|
||||||
|
"if" => Err(BlkJITCompileError::UnknownError),
|
||||||
|
"zero" => Ok(literal(0.0)),
|
||||||
|
node => {
|
||||||
|
if *id == 0 {
|
||||||
|
return Err(BlkJITCompileError::NodeWithoutID(typ.to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
let lang = self.lang.clone();
|
||||||
|
|
||||||
|
let mut args = vec![];
|
||||||
|
|
||||||
|
if let Some(inputs) = lang.borrow().get_type_inputs(typ) {
|
||||||
|
if childs.len() > inputs.len() {
|
||||||
|
return Err(BlkJITCompileError::TooManyInputs(typ.to_string(), *id));
|
||||||
|
}
|
||||||
|
|
||||||
|
for input_name in inputs.iter() {
|
||||||
|
for (inp, c) in childs.iter() {
|
||||||
|
if inp == input_name {
|
||||||
|
args.push(self.bjit2jit(&c)?);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err(BlkJITCompileError::UnknownType(typ.to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(call(typ, *id as u64, &args[..]))
|
||||||
|
}
|
||||||
},
|
},
|
||||||
BlkASTNode::Node { id, out, typ, lbl, childs } => {
|
BlkASTNode::Literal { value } => Ok(literal(*value)),
|
||||||
Err(BlkJITCompileError::UnknownError)
|
|
||||||
}
|
|
||||||
BlkASTNode::Literal { value } => {
|
|
||||||
Ok(literal(*value))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,21 +430,23 @@ mod test {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
use synfx_dsp_jit::{get_standard_library, DSPNodeContext, JIT, ASTFun, DSPFunction};
|
use synfx_dsp_jit::{get_standard_library, ASTFun, DSPFunction, DSPNodeContext, JIT};
|
||||||
|
|
||||||
fn new_jit_fun<F: FnMut(&mut BlockFun)>(mut f: F) -> (Rc<RefCell<DSPNodeContext>>, Box<DSPFunction>) {
|
fn new_jit_fun<F: FnMut(&mut BlockFun)>(
|
||||||
|
mut f: F,
|
||||||
|
) -> (Rc<RefCell<DSPNodeContext>>, Box<DSPFunction>) {
|
||||||
use crate::block_compiler::{BlkJITCompileError, Block2JITCompiler};
|
use crate::block_compiler::{BlkJITCompileError, Block2JITCompiler};
|
||||||
use crate::blocklang::BlockFun;
|
use crate::blocklang::BlockFun;
|
||||||
use crate::blocklang_def;
|
use crate::blocklang_def;
|
||||||
|
|
||||||
let lang = blocklang_def::setup_hxdsp_block_language();
|
let lib = get_standard_library();
|
||||||
|
let lang = blocklang_def::setup_hxdsp_block_language(lib.clone());
|
||||||
let mut bf = BlockFun::new(lang.clone());
|
let mut bf = BlockFun::new(lang.clone());
|
||||||
|
|
||||||
f(&mut bf);
|
f(&mut bf);
|
||||||
|
|
||||||
let mut compiler = Block2JITCompiler::new(bf.block_language());
|
let mut compiler = Block2JITCompiler::new(bf.block_language());
|
||||||
let ast = compiler.compile(&bf).expect("blk2jit compiles");
|
let ast = compiler.compile(&bf).expect("blk2jit compiles");
|
||||||
let lib = get_standard_library();
|
|
||||||
let ctx = DSPNodeContext::new_ref();
|
let ctx = DSPNodeContext::new_ref();
|
||||||
let jit = JIT::new(lib, ctx.clone());
|
let jit = JIT::new(lib, ctx.clone());
|
||||||
let mut fun = jit.compile(ASTFun::new(ast)).expect("jit compiles");
|
let mut fun = jit.compile(ASTFun::new(ast)).expect("jit compiles");
|
||||||
|
@ -440,7 +456,6 @@ mod test {
|
||||||
(ctx, fun)
|
(ctx, fun)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn check_blocklang_sig1() {
|
fn check_blocklang_sig1() {
|
||||||
let (ctx, mut fun) = new_jit_fun(|bf| {
|
let (ctx, mut fun) = new_jit_fun(|bf| {
|
||||||
|
@ -460,4 +475,36 @@ mod test {
|
||||||
ctx.borrow_mut().free();
|
ctx.borrow_mut().free();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_blocklang_accum_shift() {
|
||||||
|
let (ctx, mut fun) = new_jit_fun(|bf| {
|
||||||
|
bf.instanciate_at(0, 1, 1, "accum", None);
|
||||||
|
bf.shift_port(0, 1, 1, 1, false);
|
||||||
|
bf.instanciate_at(0, 0, 2, "value", Some("0.01".to_string()));
|
||||||
|
bf.instanciate_at(0, 0, 1, "get", Some("*reset".to_string()));
|
||||||
|
});
|
||||||
|
|
||||||
|
fun.exec_2in_2out(0.0, 0.0);
|
||||||
|
fun.exec_2in_2out(0.0, 0.0);
|
||||||
|
fun.exec_2in_2out(0.0, 0.0);
|
||||||
|
let (s1, s2, ret) = fun.exec_2in_2out(0.0, 0.0);
|
||||||
|
assert_float_eq!(ret, 0.04);
|
||||||
|
|
||||||
|
let reset_idx = ctx.borrow().get_persistent_variable_index_by_name("*reset").unwrap();
|
||||||
|
fun.access_persistent_var(reset_idx).map(|reset| *reset = 1.0);
|
||||||
|
|
||||||
|
let (s1, s2, ret) = fun.exec_2in_2out(0.0, 0.0);
|
||||||
|
assert_float_eq!(ret, 0.0);
|
||||||
|
|
||||||
|
fun.access_persistent_var(reset_idx).map(|reset| *reset = 0.0);
|
||||||
|
|
||||||
|
let (s1, s2, ret) = fun.exec_2in_2out(0.0, 0.0);
|
||||||
|
let (s1, s2, ret) = fun.exec_2in_2out(0.0, 0.0);
|
||||||
|
let (s1, s2, ret) = fun.exec_2in_2out(0.0, 0.0);
|
||||||
|
let (s1, s2, ret) = fun.exec_2in_2out(0.0, 0.0);
|
||||||
|
let (s1, s2, ret) = fun.exec_2in_2out(0.0, 0.0);
|
||||||
|
assert_float_eq!(ret, 0.05);
|
||||||
|
|
||||||
|
ctx.borrow_mut().free();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -907,8 +907,13 @@ impl BlockLanguage {
|
||||||
Some(&typ.outputs)
|
Some(&typ.outputs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_type_inputs(&self, typ: &str) -> Option<&[Option<String>]> {
|
||||||
|
let typ = self.types.get(typ)?;
|
||||||
|
Some(&typ.inputs)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_output_name_at_index(&self, typ: &str, idx: usize) -> Option<String> {
|
pub fn get_output_name_at_index(&self, typ: &str, idx: usize) -> Option<String> {
|
||||||
let outs = self.get_type_outputs(typ)?;
|
if let Some(outs) = self.get_type_outputs(typ) {
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
for o in outs.iter() {
|
for o in outs.iter() {
|
||||||
if let Some(outname) = o {
|
if let Some(outname) = o {
|
||||||
|
@ -918,6 +923,7 @@ impl BlockLanguage {
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,14 @@
|
||||||
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
||||||
// See README.md and COPYING for details.
|
// See README.md and COPYING for details.
|
||||||
|
|
||||||
use crate::blocklang::{BlockLanguage, BlockUserInput, BlockType};
|
use crate::blocklang::{BlockLanguage, BlockType, BlockUserInput};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use synfx_dsp_jit::DSPNodeTypeLibrary;
|
||||||
|
|
||||||
pub fn setup_hxdsp_block_language() -> Rc<RefCell<BlockLanguage>> {
|
pub fn setup_hxdsp_block_language(
|
||||||
|
dsp_lib: Rc<RefCell<DSPNodeTypeLibrary>>,
|
||||||
|
) -> Rc<RefCell<BlockLanguage>> {
|
||||||
let mut lang = BlockLanguage::new();
|
let mut lang = BlockLanguage::new();
|
||||||
|
|
||||||
lang.define(BlockType {
|
lang.define(BlockType {
|
||||||
|
@ -17,7 +20,9 @@ pub fn setup_hxdsp_block_language() -> Rc<RefCell<BlockLanguage>> {
|
||||||
outputs: vec![Some("".to_string())],
|
outputs: vec![Some("".to_string())],
|
||||||
area_count: 0,
|
area_count: 0,
|
||||||
user_input: BlockUserInput::None,
|
user_input: BlockUserInput::None,
|
||||||
description: "A phasor, returns a saw tooth wave to scan through things or use as modulator.".to_string(),
|
description:
|
||||||
|
"A phasor, returns a saw tooth wave to scan through things or use as modulator."
|
||||||
|
.to_string(),
|
||||||
color: 2,
|
color: 2,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -57,18 +62,6 @@ pub fn setup_hxdsp_block_language() -> Rc<RefCell<BlockLanguage>> {
|
||||||
color: 1,
|
color: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
lang.define(BlockType {
|
|
||||||
category: "literals".to_string(),
|
|
||||||
name: "SR".to_string(),
|
|
||||||
rows: 1,
|
|
||||||
inputs: vec![],
|
|
||||||
outputs: vec![Some("".to_string())],
|
|
||||||
area_count: 0,
|
|
||||||
user_input: BlockUserInput::None,
|
|
||||||
description: "The sample rate".to_string(),
|
|
||||||
color: 1,
|
|
||||||
});
|
|
||||||
|
|
||||||
lang.define(BlockType {
|
lang.define(BlockType {
|
||||||
category: "literals".to_string(),
|
category: "literals".to_string(),
|
||||||
name: "value".to_string(),
|
name: "value".to_string(),
|
||||||
|
@ -101,7 +94,8 @@ pub fn setup_hxdsp_block_language() -> Rc<RefCell<BlockLanguage>> {
|
||||||
outputs: vec![Some("".to_string()), Some("".to_string())],
|
outputs: vec![Some("".to_string()), Some("".to_string())],
|
||||||
area_count: 0,
|
area_count: 0,
|
||||||
user_input: BlockUserInput::None,
|
user_input: BlockUserInput::None,
|
||||||
description: "Forwards the value one block and sends it to multiple destinations".to_string(),
|
description: "Forwards the value one block and sends it to multiple destinations"
|
||||||
|
.to_string(),
|
||||||
color: 6,
|
color: 6,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -113,7 +107,8 @@ pub fn setup_hxdsp_block_language() -> Rc<RefCell<BlockLanguage>> {
|
||||||
outputs: vec![Some("".to_string()), Some("".to_string()), Some("".to_string())],
|
outputs: vec![Some("".to_string()), Some("".to_string()), Some("".to_string())],
|
||||||
area_count: 0,
|
area_count: 0,
|
||||||
user_input: BlockUserInput::None,
|
user_input: BlockUserInput::None,
|
||||||
description: "Forwards the value one block and sends it to multiple destinations".to_string(),
|
description: "Forwards the value one block and sends it to multiple destinations"
|
||||||
|
.to_string(),
|
||||||
color: 6,
|
color: 6,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -150,57 +145,58 @@ pub fn setup_hxdsp_block_language() -> Rc<RefCell<BlockLanguage>> {
|
||||||
area_count: 2,
|
area_count: 2,
|
||||||
user_input: BlockUserInput::None,
|
user_input: BlockUserInput::None,
|
||||||
description: "Divides the controlflow based on a true (>= 0.5) \
|
description: "Divides the controlflow based on a true (>= 0.5) \
|
||||||
or false (< 0.5) input value.".to_string(),
|
or false (< 0.5) input value."
|
||||||
|
.to_string(),
|
||||||
color: 0,
|
color: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
lang.define(BlockType {
|
// lang.define(BlockType {
|
||||||
category: "nodes".to_string(),
|
// category: "nodes".to_string(),
|
||||||
name: "1pole".to_string(),
|
// name: "1pole".to_string(),
|
||||||
rows: 2,
|
// rows: 2,
|
||||||
inputs: vec![Some("in".to_string()), Some("f".to_string())],
|
// inputs: vec![Some("in".to_string()), Some("f".to_string())],
|
||||||
outputs: vec![Some("lp".to_string()), Some("hp".to_string())],
|
// outputs: vec![Some("lp".to_string()), Some("hp".to_string())],
|
||||||
area_count: 0,
|
// area_count: 0,
|
||||||
user_input: BlockUserInput::None,
|
// user_input: BlockUserInput::None,
|
||||||
description: "Runs a simple one pole filter on the input".to_string(),
|
// description: "Runs a simple one pole filter on the input".to_string(),
|
||||||
color: 8,
|
// color: 8,
|
||||||
});
|
// });
|
||||||
|
//
|
||||||
lang.define(BlockType {
|
// lang.define(BlockType {
|
||||||
category: "nodes".to_string(),
|
// category: "nodes".to_string(),
|
||||||
name: "svf".to_string(),
|
// name: "svf".to_string(),
|
||||||
rows: 3,
|
// rows: 3,
|
||||||
inputs: vec![Some("in".to_string()), Some("f".to_string()), Some("r".to_string())],
|
// inputs: vec![Some("in".to_string()), Some("f".to_string()), Some("r".to_string())],
|
||||||
outputs: vec![Some("lp".to_string()), Some("bp".to_string()), Some("hp".to_string())],
|
// outputs: vec![Some("lp".to_string()), Some("bp".to_string()), Some("hp".to_string())],
|
||||||
area_count: 0,
|
// area_count: 0,
|
||||||
user_input: BlockUserInput::None,
|
// user_input: BlockUserInput::None,
|
||||||
description: "Runs a state variable filter on the input".to_string(),
|
// description: "Runs a state variable filter on the input".to_string(),
|
||||||
color: 8,
|
// color: 8,
|
||||||
});
|
// });
|
||||||
|
//
|
||||||
lang.define(BlockType {
|
// lang.define(BlockType {
|
||||||
category: "functions".to_string(),
|
// category: "functions".to_string(),
|
||||||
name: "sin".to_string(),
|
// name: "sin".to_string(),
|
||||||
rows: 1,
|
// rows: 1,
|
||||||
inputs: vec![Some("".to_string())],
|
// inputs: vec![Some("".to_string())],
|
||||||
outputs: vec![Some("".to_string())],
|
// outputs: vec![Some("".to_string())],
|
||||||
area_count: 0,
|
// area_count: 0,
|
||||||
user_input: BlockUserInput::None,
|
// user_input: BlockUserInput::None,
|
||||||
description: "Calculates the sine of the input".to_string(),
|
// description: "Calculates the sine of the input".to_string(),
|
||||||
color: 16,
|
// color: 16,
|
||||||
});
|
// });
|
||||||
|
//
|
||||||
lang.define(BlockType {
|
// lang.define(BlockType {
|
||||||
category: "nodes".to_string(),
|
// category: "nodes".to_string(),
|
||||||
name: "delay".to_string(),
|
// name: "delay".to_string(),
|
||||||
rows: 2,
|
// rows: 2,
|
||||||
inputs: vec![Some("in".to_string()), Some("t".to_string())],
|
// inputs: vec![Some("in".to_string()), Some("t".to_string())],
|
||||||
outputs: vec![Some("".to_string())],
|
// outputs: vec![Some("".to_string())],
|
||||||
area_count: 0,
|
// area_count: 0,
|
||||||
user_input: BlockUserInput::None,
|
// user_input: BlockUserInput::None,
|
||||||
description: "Runs a linearly interpolated delay on the input".to_string(),
|
// description: "Runs a linearly interpolated delay on the input".to_string(),
|
||||||
color: 8,
|
// color: 8,
|
||||||
});
|
// });
|
||||||
|
|
||||||
lang.define(BlockType {
|
lang.define(BlockType {
|
||||||
category: "arithmetics".to_string(),
|
category: "arithmetics".to_string(),
|
||||||
|
@ -219,8 +215,7 @@ pub fn setup_hxdsp_block_language() -> Rc<RefCell<BlockLanguage>> {
|
||||||
category: "arithmetics".to_string(),
|
category: "arithmetics".to_string(),
|
||||||
name: fun_name.to_string(),
|
name: fun_name.to_string(),
|
||||||
rows: 2,
|
rows: 2,
|
||||||
inputs:
|
inputs: if fun_name == &"-" || fun_name == &"/" {
|
||||||
if fun_name == &"-" || fun_name == &"/" {
|
|
||||||
vec![Some("a".to_string()), Some("b".to_string())]
|
vec![Some("a".to_string()), Some("b".to_string())]
|
||||||
} else {
|
} else {
|
||||||
vec![Some("".to_string()), Some("".to_string())]
|
vec![Some("".to_string()), Some("".to_string())]
|
||||||
|
@ -233,6 +228,40 @@ pub fn setup_hxdsp_block_language() -> Rc<RefCell<BlockLanguage>> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dsp_lib.borrow().for_each(|node_type| -> Result<(), ()> {
|
||||||
|
let max_ports = node_type.input_count().max(node_type.output_count());
|
||||||
|
let is_stateful = node_type.is_stateful();
|
||||||
|
|
||||||
|
let mut inputs = vec![];
|
||||||
|
let mut outputs = vec![];
|
||||||
|
|
||||||
|
let mut i = 0;
|
||||||
|
while let Some(name) = node_type.input_names(i) {
|
||||||
|
inputs.push(Some(name[0..(name.len().min(2))].to_string()));
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut i = 0;
|
||||||
|
while let Some(name) = node_type.output_names(i) {
|
||||||
|
outputs.push(Some(name[0..(name.len().min(2))].to_string()));
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lang.define(BlockType {
|
||||||
|
category: if is_stateful { "nodes".to_string() } else { "functions".to_string() },
|
||||||
|
name: node_type.name().to_string(),
|
||||||
|
rows: max_ports,
|
||||||
|
area_count: 0,
|
||||||
|
user_input: BlockUserInput::None,
|
||||||
|
description: node_type.documentation().to_string(),
|
||||||
|
color: if is_stateful { 8 } else { 16 },
|
||||||
|
inputs,
|
||||||
|
outputs,
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}).expect("seriously no error here");
|
||||||
|
|
||||||
lang.define_identifier("in1");
|
lang.define_identifier("in1");
|
||||||
lang.define_identifier("in2");
|
lang.define_identifier("in2");
|
||||||
lang.define_identifier("israte");
|
lang.define_identifier("israte");
|
||||||
|
|
|
@ -281,7 +281,9 @@ impl NodeConfigurator {
|
||||||
let mut scopes = vec![];
|
let mut scopes = vec![];
|
||||||
scopes.resize_with(MAX_SCOPES, || ScopeHandle::new_shared());
|
scopes.resize_with(MAX_SCOPES, || ScopeHandle::new_shared());
|
||||||
|
|
||||||
let lang = blocklang_def::setup_hxdsp_block_language();
|
let code_engines = vec![CodeEngine::new(); MAX_AVAIL_CODE_ENGINES];
|
||||||
|
|
||||||
|
let lang = blocklang_def::setup_hxdsp_block_language(code_engines[0].get_lib());
|
||||||
let mut block_functions = vec![];
|
let mut block_functions = vec![];
|
||||||
block_functions.resize_with(MAX_AVAIL_CODE_ENGINES, || {
|
block_functions.resize_with(MAX_AVAIL_CODE_ENGINES, || {
|
||||||
(0, Arc::new(Mutex::new(BlockFun::new(lang.clone()))))
|
(0, Arc::new(Mutex::new(BlockFun::new(lang.clone()))))
|
||||||
|
@ -304,7 +306,7 @@ impl NodeConfigurator {
|
||||||
node2idx: HashMap::new(),
|
node2idx: HashMap::new(),
|
||||||
trackers: vec![Tracker::new(); MAX_AVAIL_TRACKERS],
|
trackers: vec![Tracker::new(); MAX_AVAIL_TRACKERS],
|
||||||
#[cfg(feature = "synfx-dsp-jit")]
|
#[cfg(feature = "synfx-dsp-jit")]
|
||||||
code_engines: vec![CodeEngine::new(); MAX_AVAIL_CODE_ENGINES],
|
code_engines,
|
||||||
block_functions,
|
block_functions,
|
||||||
scopes,
|
scopes,
|
||||||
},
|
},
|
||||||
|
|
|
@ -45,6 +45,10 @@ impl CodeEngine {
|
||||||
Self { lib, dsp_ctx: DSPNodeContext::new_ref(), update_prod, return_cons }
|
Self { lib, dsp_ctx: DSPNodeContext::new_ref(), update_prod, return_cons }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_lib(&self) -> Rc<RefCell<DSPNodeTypeLibrary>> {
|
||||||
|
self.lib.clone()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn upload(&mut self, ast: Box<ASTNode>) -> Result<(), JITCompileError> {
|
pub fn upload(&mut self, ast: Box<ASTNode>) -> Result<(), JITCompileError> {
|
||||||
let jit = JIT::new(self.lib.clone(), self.dsp_ctx.clone());
|
let jit = JIT::new(self.lib.clone(), self.dsp_ctx.clone());
|
||||||
let fun = jit.compile(ASTFun::new(ast))?;
|
let fun = jit.compile(ASTFun::new(ast))?;
|
||||||
|
|
|
@ -38,3 +38,4 @@ fn check_node_code_1() {
|
||||||
let res = run_for_ms(&mut node_exec, 25.0);
|
let res = run_for_ms(&mut node_exec, 25.0);
|
||||||
assert_decimated_feq!(res.0, 50, vec![0.3; 10]);
|
assert_decimated_feq!(res.0, 50, vec![0.3; 10]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue