Example #1
0
        internal override IEnumerable<AssociativeNode> BuildAst(List<AssociativeNode> inputAstNodes, AstBuilder.CompilationContext context)
        {
            var rhs = AstFactory.BuildStringNode(Value);
            var assignment = AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), rhs);

            return new[] { assignment };
        }
Example #2
0
        public EngineController(DynamoModel dynamoModel, string geometryFactoryFileName)
        {
            this.dynamoModel = dynamoModel;

            // Create a core which is used for parsing code and loading libraries
            libraryCore = new ProtoCore.Core(new Options()
            {
                RootCustomPropertyFilterPathName = string.Empty
            });
            libraryCore.Executives.Add(Language.kAssociative,new ProtoAssociative.Executive(libraryCore));
            libraryCore.Executives.Add(Language.kImperative, new ProtoImperative.Executive(libraryCore));
            libraryCore.ParsingMode = ParseMode.AllowNonAssignment;

            libraryServices = new LibraryServices(libraryCore);
            libraryServices.LibraryLoading += this.LibraryLoading;
            libraryServices.LibraryLoadFailed += this.LibraryLoadFailed;
            libraryServices.LibraryLoaded += this.LibraryLoaded;

            liveRunnerServices = new LiveRunnerServices(dynamoModel, this, geometryFactoryFileName);
            liveRunnerServices.ReloadAllLibraries(libraryServices.ImportedLibraries);

            codeCompletionServices = new CodeCompletionServices(LiveRunnerCore);

            astBuilder = new AstBuilder(dynamoModel, this);
            syncDataManager = new SyncDataManager();

            dynamoModel.NodeDeleted += NodeDeleted;
        }
Example #3
0
        public static string ConvertNodesToCode(DynamoModel dynamoModel, IEnumerable<NodeModel> nodeList)
        {
            var astBuilder = new AstBuilder(dynamoModel, null);
            var astNodes = astBuilder.CompileToAstNodes(nodeList, false);

            var codeGen = new ProtoCore.CodeGenDS(astNodes);
            return codeGen.GenerateCode();
        }
Example #4
0
        public static string ConvertNodesToCode(IEnumerable<NodeModel> nodeList)
        {
            var astBuilder = new AstBuilder(null);
            var astNodes = astBuilder.CompileToAstNodes(nodeList, false);

            string code = GraphToDSCompiler.GraphUtilities.ASTListToCode(astNodes);
            return code;
        }
Example #5
0
        private List<AssociativeNode> GetAstsForBranch(int branch, List<AssociativeNode> inputAstNodes, bool verboseLogging, AstBuilder builder)
        {
            // Get all upstream nodes and then remove nodes that are not 
            var nodes = GetInScopeNodesForInport(branch, false).Where(n => !(n is Symbol));
            nodes = ScopedNodeModel.GetNodesInTopScope(nodes);

            // The second parameter, isDeltaExecution, is set to false so that
            // all AST nodes will be added to this IF graph node instead of 
            // adding to the corresponding graph node. 
            var allAstNodes = builder.CompileToAstNodes(nodes, Dynamo.DSEngine.AstBuilder.CompilationContext.None, verboseLogging);
            var astNodes = allAstNodes.SelectMany(t => t.Item2).ToList();
            astNodes.Add(AstFactory.BuildReturnStatement(inputAstNodes[branch]));
            return astNodes;
        }
Example #6
0
        private List<AssociativeNode> GetAstsForBranch(int branch, List<AssociativeNode> inputAstNodes)
        {
            AstBuilder astBuilder = new AstBuilder(null);

            // Get all upstream nodes and then remove nodes that are not 
            var nodes = GetInScopeNodesForInport(branch, false).Where(n => !(n is Symbol));
            nodes = ScopedNodeModel.GetNodesInTopScope(nodes);

            // The second parameter, isDeltaExecution, is set to false so that
            // all AST nodes will be added to this IF graph node instead of 
            // adding to the corresponding graph node. 
            var astNodes = astBuilder.CompileToAstNodes(nodes, false);
            astNodes.Add(AstFactory.BuildReturnStatement(inputAstNodes[branch]));
            return astNodes;
        }
Example #7
0
        public EngineController(DynamoController controller)
        {
            libraryServices = LibraryServices.GetInstance();
            libraryServices.LibraryLoading += this.LibraryLoading;
            libraryServices.LibraryLoadFailed += this.LibraryLoadFailed;
            libraryServices.LibraryLoaded += this.LibraryLoaded;

            liveRunnerServices = new LiveRunnerServices(this);
            liveRunnerServices.ReloadAllLibraries(libraryServices.Libraries.ToList());

            astBuilder = new AstBuilder(this);
            syncDataManager = new SyncDataManager();

            this.controller = controller;
            this.controller.DynamoModel.NodeDeleted += NodeDeleted;
        }
Example #8
0
        public EngineController(DynamoModel dynamoModel, string geometryFactoryFileName)
        {
            this.dynamoModel = dynamoModel;

            libraryServices = LibraryServices.GetInstance();
            libraryServices.LibraryLoading += this.LibraryLoading;
            libraryServices.LibraryLoadFailed += this.LibraryLoadFailed;
            libraryServices.LibraryLoaded += this.LibraryLoaded;

            liveRunnerServices = new LiveRunnerServices(dynamoModel, this, geometryFactoryFileName);
            liveRunnerServices.ReloadAllLibraries(libraryServices.Libraries.ToList());

            astBuilder = new AstBuilder(dynamoModel, this);
            syncDataManager = new SyncDataManager();

            dynamoModel.NodeDeleted += NodeDeleted;
        }
Example #9
0
        public EngineController(DynamoController controller)
        {
            libraryServices = LibraryServices.GetInstance();
            libraryServices.LibraryLoading    += this.LibraryLoading;
            libraryServices.LibraryLoadFailed += this.LibraryLoadFailed;
            libraryServices.LibraryLoaded     += this.LibraryLoaded;

            liveRunnerServices = new LiveRunnerServices(this);
            liveRunnerServices.ReloadAllLibraries(libraryServices.Libraries.ToList());

            astBuilder      = new AstBuilder(this);
            syncDataManager = new SyncDataManager();

            this.controller = controller;
            this.controller.DynamoModel.NodeDeleted += NodeDeleted;

            this.controller.CustomNodeManager.RecompileAllNodes(this);
        }
Example #10
0
        public EngineController(LibraryServices libraryServices, string geometryFactoryFileName, bool verboseLogging)
        {
            this.libraryServices           = libraryServices;
            libraryServices.LibraryLoaded += LibraryLoaded;
            CompilationServices            = new CompilationServices(libraryServices.LibraryManagementCore);

            liveRunnerServices = new LiveRunnerServices(this, geometryFactoryFileName);

            liveRunnerServices.ReloadAllLibraries(libraryServices.ImportedLibraries);
            libraryServices.SetLiveCore(LiveRunnerCore);

            codeCompletionServices = new CodeCompletionServices(LiveRunnerCore);

            astBuilder      = new AstBuilder(this);
            syncDataManager = new SyncDataManager();

            VerboseLogging = verboseLogging;
        }
Example #11
0
        /// <summary>
        /// Handler for the EngineController's AstBuilt event.
        /// Formats a string of AST for preview on the node.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void EngineController_AstBuilt(object sender, AstBuilder.ASTBuiltEventArgs e)
        {
            if (e.Node == nodeLogic)
            {
                var sb = new StringBuilder();
                sb.AppendLine(string.Format("{0} AST:", e.Node.GUID));

                foreach (var assocNode in e.AstNodes)
                {
                    var pretty = assocNode.ToString();

                    //shorten the guids
                    var strRegex = @"([0-9a-f-]{32}).*?";
                    var myRegex = new Regex(strRegex, RegexOptions.None);
                    string strTargetString = assocNode.ToString();

                    foreach (Match myMatch in myRegex.Matches(strTargetString))
                    {
                        if (myMatch.Success)
                        {
                            pretty = pretty.Replace(myMatch.Value, "..." + myMatch.Value.Substring(myMatch.Value.Length - 7));
                        }
                    }
                    sb.AppendLine(pretty);
                }

                ASTText = sb.ToString();
            }
        }
Example #12
0
        public AssociativeNode CompileToAstNode(AstBuilder builder)
        {
            if (!RequiresRecalc)
            {
                return this.AstIdentifier;
            }

            builder.ClearAstNodes(GUID);
            bool isPartiallyApplied = false;

            // Recursively compile its inputs to ast nodes and add intermediate
            // nodes to builder
            var inputAstNodes = new List<AssociativeNode>();
            for (int index = 0; index < InPortData.Count; ++index)
            {
                Tuple<int, NodeModel> input;
                if (!TryGetInput(index, out input))
                {
                    isPartiallyApplied = true;
                    inputAstNodes.Add(null);
                }
                else
                {
                    inputAstNodes.Add(input.Item2.CompileToAstNode(builder));
                }
            }

            // Build evaluatiion for this node. If the rhs is a partially
            // applied function, then a function defintion node will be created.
            // But in the end there is always an assignment:
            //
            //     AstIdentifier = ...;
            var rhs = BuildAstNode(builder, inputAstNodes)
                      ?? builder.BuildEvaluator(this, inputAstNodes);
            builder.BuildEvaluation(this, rhs, isPartiallyApplied);

            return AstIdentifier;
        }
Example #13
0
 /// <summary>
 /// Similar to NodeModel.BuildAst(). When compiled to AST, for 
 /// ScopedNodeModel this method will be called when all requirements
 /// are satisfied. 
 /// </summary>
 /// <param name="inputAstNodes"></param>
 /// <param name="verboseLogging"></param>
 /// <param name="builder"></param>
 /// <returns></returns>
 internal virtual IEnumerable<AssociativeNode> BuildAstInScope(List<AssociativeNode> inputAstNodes, bool verboseLogging, AstBuilder builder)
 {
     OnBuilt();
     var result = BuildOutputAstInScope(inputAstNodes, verboseLogging, builder);
     return result;
 }
Example #14
0
 /// <summary>
 /// Similar to NodeModel.BuildOutputAst(). When compiled to AST, for
 /// ScopedNodeModel this method will be called when all requirements are
 /// satisfied. The derived class needs to implement this method to 
 /// compile its children into some scopes.
 /// </summary>
 /// <param name="inputAstNodes"></param>
 /// <param name="verboseLogging"></param>
 /// <param name="builder"></param>
 /// <returns></returns>
 public virtual IEnumerable<AssociativeNode> BuildOutputAstInScope(List<AssociativeNode> inputAstNodes, bool verboseLogging, AstBuilder builder)
 {
     throw new NotImplementedException("BuildOutputAstInScope");
 }
Example #15
0
        internal override IEnumerable<AssociativeNode> BuildAst(List<AssociativeNode> inputAstNodes, AstBuilder.CompilationContext context)
        {
            var paramDict = InPortData.Select(x => x.NickName)
                   .Zip<string, AssociativeNode, Tuple<string, AssociativeNode>>(inputAstNodes, Tuple.Create)
                   .ToDictionary(x => x.Item1, x => x.Item2);

            AssociativeNode rhs;

            if (null == _parsed)
            {
                rhs = AstFactory.BuildNullNode();
            }
            else
            {
                List<AssociativeNode> newInputs = _parsed.Count == 1
                    ? new List<AssociativeNode> { _parsed[0].GetAstNode(paramDict) }
                    : _parsed.Select(x => x.GetAstNode(paramDict)).ToList();

                rhs = newInputs.Count == 1
                        ? newInputs[0]
                        : AstFactory.BuildExprList(newInputs);
            }

            var assignment = AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), rhs);

            return new[] { assignment };
        }
Example #16
0
        /// <summary>
        /// Wraps the publically overrideable `BuildOutputAst` method so that it works with Preview.
        /// </summary>
        /// <param name="inputAstNodes"></param>
        /// <param name="context">Compilation context</param>
        internal virtual IEnumerable<AssociativeNode> BuildAst(List<AssociativeNode> inputAstNodes, AstBuilder.CompilationContext context)
        {
            OnBuilt();

            IEnumerable<AssociativeNode> result = null;

            try
            {
                result = BuildOutputAst(inputAstNodes);
            }
            catch (Exception e)
            {
                // If any exception from BuildOutputAst(), we emit
                // a function call "var_guid = %nodeAstFailed(full.node.name)"
                // for this node, set the state of node to AstBuildBroken and
                // disply the corresponding error message. 
                // 
                // The return value of function %nodeAstFailed() is always 
                // null.
                var errorMsg = Properties.Resources.NodeProblemEncountered;
                var fullMsg = errorMsg + "\n\n" + e.Message;
                this.NotifyAstBuildBroken(fullMsg);

                var fullName = this.GetType().ToString();
                var astNodeFullName = AstFactory.BuildStringNode(fullName);
                var arguments = new List<AssociativeNode> { astNodeFullName };
                var func = AstFactory.BuildFunctionCall(Constants.kNodeAstFailed, arguments); 

                return new []
                {
                    AstFactory.BuildAssignment(AstIdentifierForPreview, func)
                };
            }

            if (OutPortData.Count == 1)
            {
                var firstOuputIdent = GetAstIdentifierForOutputIndex(0);
                if (!AstIdentifierForPreview.Equals(firstOuputIdent))
                {
                    result = result.Concat(
                    new[]
                    {
                        AstFactory.BuildAssignment(AstIdentifierForPreview, firstOuputIdent)
                    });
                }
                return result;
            }

            var emptyList = AstFactory.BuildExprList(new List<AssociativeNode>());
            var previewIdInit = AstFactory.BuildAssignment(AstIdentifierForPreview, emptyList);

            return
                result.Concat(new[] { previewIdInit })
                      .Concat(
                          OutPortData.Select(
                              (outNode, index) =>
                                  AstFactory.BuildAssignment(
                                      new IdentifierNode(AstIdentifierForPreview)
                                      {
                                          ArrayDimensions =
                                              new ArrayNode
                                              {
                                                  Expr = new StringNode { value = outNode.NickName }
                                              }
                                      },
                                      GetAstIdentifierForOutputIndex(index))));
        }
Example #17
0
        internal override IEnumerable<AssociativeNode> BuildAst(List<AssociativeNode> inputAstNodes, AstBuilder.CompilationContext context)
        {
            //Do not build if the node is in error.
            if (State == ElementState.Error)
            {
                return Enumerable.Empty<AssociativeNode>();
            }

            var resultNodes = new List<AssociativeNode>();

            // Define unbound variables if necessary
            if (inputIdentifiers != null &&
                inputAstNodes != null &&
                inputIdentifiers.Count == inputAstNodes.Count)
            {
                var initStatments = inputIdentifiers.Zip(inputAstNodes,
                    (ident, rhs) =>
                    {
                        var identNode = AstFactory.BuildIdentifier(ident);
                        if (context != AstBuilder.CompilationContext.NodeToCode)
                            MapIdentifiers(identNode);
                        return AstFactory.BuildAssignment(identNode, rhs);
                    });
                resultNodes.AddRange(initStatments);
            }

            foreach (var astNode in codeStatements.Select(stmnt => NodeUtils.Clone(stmnt.AstNode)))
            {
                if (context != AstBuilder.CompilationContext.NodeToCode)
                    MapIdentifiers(astNode);
                resultNodes.Add(astNode as AssociativeNode);
            }

            return resultNodes;
        }
Example #18
0
        public override IEnumerable<AssociativeNode> BuildOutputAstInScope(List<AssociativeNode> inputAstNodes, bool verboseLogging, AstBuilder builder)
        {
            // This function will compile IF node to the following format:
            //
            //     cond = ...;
            //     v = [Imperative]
            //     {
            //         if (cond) {
            //             return = [Associative] {
            //                 ...
            //             }
            //         }
            //         else {
            //             return = [Associative] {
            //                 ...
            //             }
            //         }
            //     }
            //

            var astsInTrueBranch = GetAstsForBranch(1, inputAstNodes, verboseLogging, builder);
            var astsInFalseBranch = GetAstsForBranch(2, inputAstNodes, verboseLogging, builder);

            // if (cond) {
            //     return = [Associative] {...}
            // }
            var ifBlock = new LanguageBlockNode
            {
                codeblock = new LanguageCodeBlock(Language.kAssociative),
                CodeBlockNode = new CodeBlockNode { Body = astsInTrueBranch }
            };
            var ifBranch = AstFactory.BuildReturnStatement(ifBlock).ToImperativeAST();

            // else {
            //     return = [Associative] { ... }
            // }
            var elseBlock = new LanguageBlockNode
            {
                codeblock = new LanguageCodeBlock(Language.kAssociative),
                CodeBlockNode = new CodeBlockNode { Body = astsInFalseBranch }
            };
            var elseBranch = AstFactory.BuildReturnStatement(elseBlock).ToImperativeAST();

            var ifelseStatement = new ProtoCore.AST.ImperativeAST.IfStmtNode()
            {
                IfExprNode = inputAstNodes[0].ToImperativeAST(),
                IfBody = new List<ProtoCore.AST.ImperativeAST.ImperativeNode> { ifBranch },
                ElseBody = new List<ProtoCore.AST.ImperativeAST.ImperativeNode> { elseBranch }
            };

            // thisVariable = [Imperative]
            // {
            //     ...
            // }
            var outerBlock = new LanguageBlockNode
            {
                codeblock = new LanguageCodeBlock(Language.kImperative),
                CodeBlockNode = new ProtoCore.AST.ImperativeAST.CodeBlockNode
                {
                    Body = new List<ProtoCore.AST.ImperativeAST.ImperativeNode> { ifelseStatement }
                }
            };

            var thisVariable = GetAstIdentifierForOutputIndex(0);
            var assignment = AstFactory.BuildAssignment(thisVariable, outerBlock);

            return new AssociativeNode[] 
            {
                assignment
            };
        }
Example #19
0
        /// <summary>
        /// Compile a set of nodes to ASTs.
        ///
        /// Note:
        /// 1. Nodes should be a clique with regarding to convertibility and
        ///    selection state. That is, these nodes can be safely to be
        ///    converted into a single code block node. It shouldn't have
        ///    unconvertible or unselected node on any path (if there is) that
        ///    connects any two of these nodes, otherwise there will be
        ///    circular references between unconvertible/unselected node and
        ///    code block node.
        ///
        ///    To split arbitary node set into cliques, use
        ///    NodeToCodeUtils.GetCliques().
        ///
        /// 2. WorkspaceNodes are all nodes in current workspace. We need the
        ///    whole graph so that each to-be-converted node will have correct
        ///    order in the final code block node.
        /// </summary>
        /// <param name="core">Library core</param>
        /// <param name="astBuilder">Ast builder</param>
        /// <param name="workspaceNodes">The whole workspace nodes</param>
        /// <param name="nodes">Selected node that can be converted to a single code block node</param>
        /// <returns></returns>
        public static NodeToCodeResult NodeToCode(
            ProtoCore.Core core,
            AstBuilder astBuilder,
            IEnumerable <NodeModel> workspaceNodes,
            IEnumerable <NodeModel> nodes)
        {
            // The basic worflow is:
            //   1. Compile each node to get its cde in AST format
            //
            //   2. Variable numbering to avoid confliction. For example, two
            //      code block nodes both have assignment "y = x", we need to
            //      rename "y" to "y1" and "y2" respectively.
            //
            //   3. Variable remapping. For example, code block node
            //      "x = 1" connects to "a = b", where the second code block
            //      node will have initialization "b = x_guid" where "x_guid"
            //      is because of variable mappining in the first code block
            //      node. We should restore it to its original name.
            //
            //      Note in step 2 we may rename "x" to "xn".
            //
            //   4. Generate short name for long name variables. Typically they
            //      are from output ports from other nodes.
            //
            //   5. Do constant progation to optimize the generated code.
            #region Step 1 AST compilation

            var sortedGraph = AstBuilder.TopologicalSortForGraph(workspaceNodes);
            var sortedNodes = sortedGraph.Where(nodes.Contains);

            var allAstNodes = astBuilder.CompileToAstNodes(sortedNodes, AstBuilder.CompilationContext.NodeToCode, false);

            #endregion

            #region Step 2 Varialbe numbering

            // External inputs will be in input map
            // Internal non-cbn will be input map & output map
            // Internal cbn will be in renaming map and output map

            // Map from mapped variable to its original name. These variables
            // are from code block nodes that in the selection.
            Dictionary <string, string> renamingMap = null;;

            // Input variable to renamed input variable map
            Dictionary <string, string> inputMap = null;

            // Output variable to renamed output variable map
            Dictionary <string, string> outputMap = null;

            // Collect all inputs/outputs/candidate renaming variables
            GetInputOutputMap(nodes, out inputMap, out outputMap, out renamingMap);

            // Variable numbering map. Value field indicates current current
            // numbering value of the variable. For example, there are variables
            // t1, t2, ... tn and the ID of variable t's NumberingState is n.
            var numberingMap = new Dictionary <string, NumberingState>();

            // In this step, we'll renumber all variables that going to be in
            // the same code block node. That is,
            //
            //     "x = 1; y = x;"   and
            //     "x = 2; y = x;"
            //
            // Will be renumbered to
            //
            //    "x1 = 1; y1 = x1;" and
            //    "x2 = 2; y2 = x2;"
            var mappedVariables = new HashSet <string>();
            foreach (var t in allAstNodes)
            {
                // Reset variable numbering map
                foreach (var p in numberingMap)
                {
                    p.Value.IsNewSession = true;
                }

                foreach (var astNode in t.Item2)
                {
                    VariableNumbering(core, astNode, t.Item1, numberingMap, renamingMap, inputMap, outputMap, mappedVariables);
                }
            }

            renamingMap = renamingMap.Where(p => !p.Key.Contains("%"))
                          .ToDictionary(p => p.Key, p => p.Value);
            #endregion

            #region Step 3 Variable remapping
            foreach (var ts in allAstNodes)
            {
                foreach (var astNode in ts.Item2)
                {
                    VariableRemapping(core, astNode, renamingMap, outputMap, mappedVariables);
                }
            }
            #endregion

            #region Step 4 Generate short name
            var nameGenerator = new ShortNameGenerator();

            // temporary variables are double mapped.
            foreach (var key in outputMap.Keys.ToList())
            {
                if (key.StartsWith(Constants.kTempVarForNonAssignment) &&
                    outputMap[key].StartsWith(Constants.kTempVarForNonAssignment))
                {
                    string shortName = nameGenerator.GetNextName();
                    while (mappedVariables.Contains(shortName))
                    {
                        shortName = nameGenerator.GetNextName();
                    }

                    var tempVar = outputMap[key];
                    outputMap[key]     = shortName;
                    outputMap[tempVar] = shortName;

                    mappedVariables.Add(shortName);
                }
            }

            foreach (var ts in allAstNodes)
            {
                foreach (var astNode in ts.Item2)
                {
                    ShortNameMapping(core, astNode, inputMap, nameGenerator, mappedVariables);
                    foreach (var kvp in inputMap)
                    {
                        if (kvp.Value != String.Empty && outputMap.ContainsKey(kvp.Key))
                        {
                            outputMap[kvp.Key] = kvp.Value;
                        }
                    }
                    ShortNameMapping(core, astNode, outputMap, nameGenerator, mappedVariables);
                }
            }
            #endregion

            var result = new NodeToCodeResult(allAstNodes.SelectMany(x => x.Item2), inputMap, outputMap);
            return(result);
        }
Example #20
0
        public EngineController(LibraryServices libraryServices, string geometryFactoryFileName, bool verboseLogging)
        {
            this.libraryServices = libraryServices;
            libraryServices.LibraryLoaded += LibraryLoaded;
            CompilationServices = new CompilationServices(libraryServices.LibraryManagementCore);

            liveRunnerServices = new LiveRunnerServices(this, geometryFactoryFileName);

            liveRunnerServices.ReloadAllLibraries(libraryServices.ImportedLibraries);
            libraryServices.SetLiveCore(LiveRunnerCore);

            codeCompletionServices = new CodeCompletionServices(LiveRunnerCore);

            astBuilder = new AstBuilder(this);
            syncDataManager = new SyncDataManager();

            VerboseLogging = verboseLogging;
        }