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; }
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(); }
/// <summary> /// Generate graph sync data based on the input Dynamo nodes. Return /// false if all nodes are clean. /// </summary> /// <param name="nodes"></param> /// <returns></returns> public bool GenerateGraphSyncData(IEnumerable <NodeModel> nodes) { var activeNodes = nodes.Where(n => n.State != ElementState.Error); if (activeNodes.Any()) { astBuilder.CompileToAstNodes(activeNodes, true); } return(VerifyGraphSyncData()); }
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; }
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; }
/// <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); }