Code/Nodes/Math/Operator/Add.cs
using Nodebox.Util.Math;

namespace Nodebox.Nodes {
    [Tag("Math", "Operator")]
    [Alias("+")]
    [UI.Panel(typeof(UI.VariadicInput<>))]
    public class Add : Node, Node.IVariadicInput<object> {
        public override (List<Pin>, List<Pin>) InitialPins => (
            [Pin.New<object>(), Pin.New<object>()],
            [Pin.New<object>()]
        );

        protected override void OnWiresChanged(bool added) {
            base.OnWiresChanged(added);
            PolymorphHelpers.Operator(this, typeof(Add), typeof(Add<>));
        }
    }

    [Collection.IsSpecializationOf(typeof(Add))]
    public class Add<T> : Add, Node.IVariadicInput<T> {
        public override bool AreValidGenerics => Util.Math.Add.Global.IsValid<T, T>();
        public override (List<Pin>, List<Pin>) InitialPins => (
            [Pin.New<T>(), Pin.New<T>()],
            [Pin.New<T>()]
        );
    }
}


namespace Nodebox.Execution {
    using Nodebox.Nodes;
    using static ExecutionContext;

    public class AddImplementation<T> : Implementation {
        public override bool IsValid => Node.GetAreValidGenerics(Target);
        public override Type Target => typeof(Add<T>);
        public override void Evaluate(ExecutionContext context, Node node) {
            var io = context.Store[node];

            var sum = io.GetInput<object>(0);
            foreach (var index in Enumerable.Range(1, node.InputPins.Count - 1)) {
                sum = Util.Math.Add.Global.Apply(sum, io.GetInput<object>(index));
            }

            io.SetOutput(0, sum);
        }
    }
}