Esempio n. 1
0
        private Dictionary<int, INode> buildPartialMultiOut(IEnumerable<string> portNames, List<Tuple<string, INode>> connections, List<string> partials)
        {
            return OutPortData.Select((d, i) => new { Index = i, Data = d }).ToDictionary(
                data => data.Index,
                data =>
                {
                    var node = Compile(portNames);

                    foreach (var partial in partials)
                        node.ConnectInput(partial, new SymbolNode(partial));

                    var accessor = new ExternalFunctionNode(FScheme.Get, new[] { "idx", "list" });
                    accessor.ConnectInput("list", node);
                    accessor.ConnectInput("idx", new NumberNode(data.Index));

                    var outerNode = new AnonymousFunctionNode(partials, accessor);
                    if (connections.Any())
                    {
                        outerNode = new AnonymousFunctionNode(connections.Select(x => x.Item1), outerNode);
                        foreach (var connection in connections)
                        {
                            node.ConnectInput(connection.Item1, new SymbolNode(connection.Item1));
                            outerNode.ConnectInput(connection.Item1, connection.Item2);
                        }
                    }

                    return outerNode as INode;
                });
        }
Esempio n. 2
0
        private Dictionary<int, INode> buildPartialSingleOut(IEnumerable<string> portNames, List<Tuple<string, INode>> connections, List<string> partials)
        {
            InputNode node = Compile(portNames);

            foreach (var partial in partials)
            {
                node.ConnectInput(partial, new SymbolNode(partial));
            }

            var outerNode = new AnonymousFunctionNode(partials, node);
            if (connections.Any())
            {
                outerNode = new AnonymousFunctionNode(connections.Select(x => x.Item1), outerNode);
                foreach (var connection in connections)
                {
                    node.ConnectInput(connection.Item1, new SymbolNode(connection.Item1));
                    outerNode.ConnectInput(connection.Item1, connection.Item2);
                }
            }

            return new Dictionary<int, INode> { { 0, outerNode } };
        }
Esempio n. 3
0
        //TODO: do all of this as the Ui is modified, simply return this?
        /// <summary>
        /// Builds an INode out of this Element. Override this or Compile() if you want complete control over this Element's
        /// execution.
        /// </summary>
        /// <returns>The INode representation of this Element.</returns>
        protected internal virtual INode Build(Dictionary<dynNodeModel, Dictionary<int, INode>> preBuilt, int outPort)
        {
            //Debug.WriteLine("Building node...");

            Dictionary<int, INode> result;
            if (preBuilt.TryGetValue(this, out result))
                return result[outPort];

            //Fetch the names of input ports.
            var portNames = InPortData.Zip(Enumerable.Range(0, InPortData.Count), (x, i) => x.NickName + i).ToList();

            //Compile the procedure for this node.
            InputNode node = Compile(portNames);

            //Is this a partial application?
            var partial = false;

            var connections = new List<Tuple<string, INode>>();
            var partialSymList = new List<string>();

            //For each index in InPortData
            //for (int i = 0; i < InPortData.Count; i++)
            foreach (var data in Enumerable.Range(0, InPortData.Count).Zip(portNames, (data, name) => new { Index = data, Name = name }))
            {
                //Fetch the corresponding port
                //var port = InPorts[i];

                Tuple<int, dynNodeModel> input;

                //If this port has connectors...
                //if (port.Connectors.Any())
                if (TryGetInput(data.Index, out input))
                {
                    //Debug.WriteLine(string.Format("Connecting input {0}", data.Name));

                    //Compile input and connect it
                    connections.Add(Tuple.Create(data.Name, input.Item2.Build(preBuilt, input.Item1)));
                }
                else //othwise, remember that this is a partial application
                {
                    partial = true;
                    node.ConnectInput(data.Name, new SymbolNode(data.Name));
                    partialSymList.Add(data.Name);
                }
            }

            var nodes = new Dictionary<int, INode>();

            if (OutPortData.Count > 1)
            {
                if (partial)
                {
                    foreach (var connection in connections)
                    {
                        node.ConnectInput(connection.Item1, new SymbolNode(connection.Item1));
                    }
                }
                else
                {
                    foreach (var connection in connections)
                    {
                        node.ConnectInput(connection.Item1, connection.Item2);
                    }
                }

                InputNode prev = node;
                int prevIndex = 0;

                foreach (var data in OutPortData.Select((d, i) => new { Index = i, Data = d }))
                {
                    if (HasOutput(data.Index))
                    {
                        if (data.Index > 0)
                        {
                            var diff = data.Index - prevIndex;
                            InputNode restNode;
                            if (diff > 1)
                            {
                                restNode = new ExternalFunctionNode(FScheme.Drop, new[] { "amt", "list" });
                                restNode.ConnectInput("amt", new NumberNode(diff));
                                restNode.ConnectInput("list", prev);
                            }
                            else
                            {
                                restNode = new ExternalFunctionNode(FScheme.Cdr, new[] { "list" });
                                restNode.ConnectInput("list", prev);
                            }
                            prev = restNode;
                            prevIndex = data.Index;
                        }

                        var firstNode = new ExternalFunctionNode(FScheme.Car, new[] { "list" }) as InputNode;
                        firstNode.ConnectInput("list", prev);

                        if (partial)
                        {
                            var outerNode = new AnonymousFunctionNode(partialSymList, firstNode);
                            if (connections.Any())
                            {
                                outerNode = new AnonymousFunctionNode(
                                    connections.Select(x => x.Item1),
                                    outerNode);
                                foreach (var connection in connections)
                                {
                                    outerNode.ConnectInput(connection.Item1, connection.Item2);
                                }
                            }
                            firstNode = outerNode;
                        }

                        nodes[data.Index] = firstNode;
                    }
                    else
                        nodes[data.Index] = new NumberNode(0);
                }
            }
            else
            {
                if (partial)
                {
                    var outerNode = new AnonymousFunctionNode(partialSymList, node);
                    if (connections.Any())
                    {
                        outerNode = new AnonymousFunctionNode(
                            connections.Select(x => x.Item1),
                            outerNode);
                        foreach (var connection in connections)
                        {
                            node.ConnectInput(connection.Item1, new SymbolNode(connection.Item1));
                            outerNode.ConnectInput(connection.Item1, connection.Item2);
                        }
                    }
                    node = outerNode;
                }
                else
                {
                    foreach (var connection in connections)
                    {
                        node.ConnectInput(connection.Item1, connection.Item2);
                    }
                }
                nodes[outPort] = node;
            }

            //If this is a partial application, then remember not to re-eval.
            if (partial)
            {
                OldValue = Value.NewFunction(null); // cache an old value for display to the user
                RequiresRecalc = false;
            }

            preBuilt[this] = nodes;

            //And we're done
            return nodes[outPort];
        }