aboutsummaryrefslogtreecommitdiffstats
path: root/src/library.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/library.rs')
-rw-r--r--src/library.rs99
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 {