diff options
Diffstat (limited to 'src/library.rs')
| -rw-r--r-- | src/library.rs | 99 |
1 files changed, 69 insertions, 30 deletions
diff --git a/src/library.rs b/src/library.rs index a45ff24..cd3b36c 100644 --- a/src/library.rs +++ b/src/library.rs @@ -108,11 +108,16 @@ impl<T: FixedNode> ConcreteNode for T { fn compile( &self, signature: TypeSignature, - inputs: Vec<String>, + inputs: Vec<Option<String>>, outputs: Vec<String>, f: &mut dyn fmt::Write, ) -> fmt::Result { - self.compile(signature, inputs, outputs, f) + let inputs: Option<Vec<String>> = inputs.into_iter().collect(); + if let Some(inputs) = inputs { + self.compile(signature, inputs, outputs, f) + } else { + Err(fmt::Error) + } } } @@ -152,7 +157,7 @@ impl<T: OutputOnlyNode> ConcreteNode for T { fn compile( &self, signature: TypeSignature, - inputs: Vec<String>, + inputs: Vec<Option<String>>, outputs: Vec<String>, f: &mut dyn fmt::Write, ) -> fmt::Result { @@ -170,43 +175,77 @@ pub enum BinArithmetic { Divide, } -impl FixedNode for BinArithmetic { - fn all_signatures(&self) -> Box<dyn Iterator<Item = TypeSignature>> { - // @TODO: matrix and matrix/vector operations - // componentwise and vector-scalar operations - Box::new( - [GEN_F_TYPES, GEN_D_TYPES, GEN_I_TYPES, GEN_U_TYPES] - .into_iter() - .flatten() - .flat_map(|t| { - [ - TypeSignature::new([t, t], [t]), - TypeSignature::new([t, t.scalar().into()], [t]), - TypeSignature::new([t.scalar().into(), t], [t]), - ] - }) - .dedup(), - ) +fn check_gentype(inputs: &[Option<Type>]) -> Result<Option<Type>, ()> { + let mut seen: Option<Type> = None; + + for input in inputs { + seen = match (seen, input) { + (a, None) => a, + (None, a) => *a, + (Some(a), Some(b)) => Some(Type::upcast_gentype(a, *b)?), + } + } + + Ok(seen) +} + +impl ConcreteNode for BinArithmetic { + fn max_inputs(&self) -> usize { + 10 + } + + fn num_inputs(&self, connected: &[Option<Type>]) -> usize { + connected + .iter() + .enumerate() + .filter(|(_, v)| v.is_some()) + .map(|(i, _)| i + 2) + .last() + .unwrap_or(2) + } + + fn signatures_matching(&self, connected: &[Option<Type>]) -> Vec<TypeSignature> { + if let Ok(out) = check_gentype(connected) { + let out = out.unwrap_or_default(); + + vec![TypeSignature { + inputs: connected.iter().map(|v| v.unwrap_or_default()).collect(), + outputs: Box::new([out]), + }] + } else { + vec![] + } + } + + fn signature(&self, connected: &[Option<Type>]) -> TypeSignature { + let out = check_gentype(connected) + .ok() + .flatten() + .unwrap_or(Scalar(Float(Single))); + + TypeSignature { + inputs: connected.iter().map(|v| v.unwrap_or(out)).collect(), + outputs: Box::new([out]), + } } fn compile( &self, signature: TypeSignature, - inputs: Vec<String>, + inputs: Vec<Option<String>>, outputs: Vec<String>, f: &mut dyn fmt::Write, ) -> fmt::Result { let out_typ = &signature.outputs[0]; let out_name = &outputs[0]; - let left = &inputs[0]; - let right = &inputs[1]; let sym = match self { - Self::Add => "+", - Self::Subtract => "-", - Self::Multiply => "*", - Self::Divide => "/", + Self::Add => " + ", + Self::Subtract => " - ", + Self::Multiply => " * ", + Self::Divide => " / ", }; - writeln!(f, "{out_typ} {out_name} = {left} {sym} {right};") + let expr = inputs.iter().filter_map(|s| s.as_ref()).join(sym); + writeln!(f, "{out_typ} {out_name} = {expr};") } } @@ -926,7 +965,7 @@ where fn compile( &self, _signature: TypeSignature, - _inputs: Vec<String>, + _inputs: Vec<Option<String>>, outputs: Vec<String>, f: &mut dyn fmt::Write, ) -> fmt::Result { @@ -1080,7 +1119,7 @@ impl ConcreteNode for Input { fn compile( &self, signature: TypeSignature, - _inputs: Vec<String>, + _inputs: Vec<Option<String>>, outputs: Vec<String>, f: &mut dyn fmt::Write, ) -> fmt::Result { |
