Пример #1
0
        private Expression GetControlExpression(int node, Dictionary <int, bool> visited)
        {
            if (visited.ContainsKey(node) && visited[node])
            {
                throw new InvalidGraphException("Infinite flow loop");
            }

            visited[node] = true;

            var currentNode = GetNode(node);

            var inputDataExpressions  = new Expression[currentNode.Inputs.Length];
            var outputFlowExpressions = new Expression[currentNode.Outputs.Length];

            // ASSUMPTION: first input socket is a flow socket, the rest are data sockets
            for (int i = 1; i < currentNode.Inputs.Length; i++)
            {
                var connection = currentNode.Inputs[i][0];
                if (connection == null)
                {
                    inputDataExpressions[i] = GetDefaultValueOfEmptyInput(currentNode.Type, i, currentNode.Data.Value);
                }
                else
                {
                    inputDataExpressions[i] = GetDataExpression(node, i);
                }
            }

            for (int i = 0; i < currentNode.Outputs.Length; i++)
            {
                var connection = currentNode.Outputs[i][0];
                if (connection != null && !FunctionsFacade.IsPureFunction(GetNode(connection.Node).Type))
                {
                    outputFlowExpressions[i] = GetControlExpression(connection.Node, visited);
                }
                else
                {
                    outputFlowExpressions[i] = Expression.Empty();
                }
            }

            visited[node] = false;

            switch (currentNode.Type)
            {
            case FunctionNames.If:
                return(Expression.IfThenElse(
                           Expression.Convert(inputDataExpressions.ElementAtOrDefault(1), typeof(bool)),
                           outputFlowExpressions.ElementAtOrDefault(0),
                           outputFlowExpressions.ElementAtOrDefault(1)
                           ));

            case FunctionNames.ForEach:
                return(Expression.Block(
                           ExpressionUtils.ForEach(
                               inputDataExpressions.ElementAtOrDefault(1),
                               LoopVars[Tuple.Create(node, 1)],
                               outputFlowExpressions.ElementAtOrDefault(0)
                               ),
                           outputFlowExpressions.ElementAtOrDefault(3)
                           ));

            case FunctionNames.For:
                throw new NotImplementedException();

            case FunctionNames.While:
                throw new NotImplementedException();

            case FunctionNames.Return:
                return(Expression.Return(ReturnTarget, inputDataExpressions.ElementAtOrDefault(1)));

            case FunctionNames.Set:
                return(Expression.Block(
                           Expression.Assign(LocalVars[currentNode.Data.Value], inputDataExpressions.ElementAtOrDefault(1)),
                           outputFlowExpressions[0]
                           ));

            default:
                throw new InvalidGraphException("Not a control function or is entry");
            }
        }