/// <summary> /// Build the node Connections List from a Rung /// </summary> /// <param name="list">List of node NodeExpression</param> /// <param name="rung">Rung to be analysed</param> /// <returns></returns> public static List <NodeExpression> RunAnalysis(this List <NodeExpression> list, Rung rung) { foreach (ComponentBase component in rung.Components) { NodeExpression NodeA = new NodeExpression(component.LeftLide); NodeExpression NodeB = new NodeExpression(component.RightLide); if (!list.Contains(NodeA)) { list.Add(NodeA); NodeA.OutComponents.Add(component); } else { int pos = list.IndexOf(NodeA); list[pos].OutComponents.Add(component); } if (!list.Contains(NodeB)) { list.Add(NodeB); NodeB.InComponents.Add(component); } else { int pos = list.IndexOf(NodeB); list[pos].InComponents.Add(component); } } return(list); }
/// <summary> /// Return closer parallel connection in list /// </summary> /// <param name="list">List of node NodeExpression</param> /// <param name="node">Start node</param> /// <returns></returns> public static NodeExpression GetLastParallel(this List <NodeExpression> list, NodeExpression node) { int index = list.IndexOf(node); while (list[index].InComponents.Count == 1) { string exp = list[index].Expression; int markerPos = exp.IndexOf(DiagramCompiler.NODE_NUMBER_MARKER); if (markerPos == -1) { break; } int numberLeght = 1; while (char.IsDigit(exp[markerPos + numberLeght]) && (markerPos + numberLeght <= exp.Length)) { numberLeght++; } index = Int16.Parse(exp.Substring(markerPos + 1, numberLeght - 1)); } return(list[index]); }
/// <summary> /// Compile the diagram's rung collection /// </summary> /// <param name="rungs"></param> /// <param name="codeBuffer"></param> internal static void CompileRungs(IEnumerable <Rung> rungs, CompilerBuffer codeBuffer) { foreach (Rung rung in rungs) { #region Buffers List <string> tempStatements = new List <string>(); List <NodeExpression> nodes = new List <NodeExpression>().RunAnalysis(rung); List <NodeOutputs> outputs = new List <NodeOutputs>(); #endregion #region Analysis Loop foreach (ComponentBase component in rung.Components) { NodeExpression NodeA = nodes.GetNodeConnections(component.LeftLide); NodeExpression NodeB = nodes.GetNodeConnections(component.RightLide); if (component.GetCompilerClass() == ComponentCompilerClass.Input) { if (!string.IsNullOrEmpty(NodeA.Expression)) { NodeB += string.Format(NODE_NUMBER_MARKER + "{0} && {1}", nodes.IndexOf(NodeA), CompileInputComponent(component)); } else { NodeB += CompileInputComponent(component); } } else { NodeExpression lastParallel = nodes.GetLastParallel(NodeA); if (!string.IsNullOrEmpty(NodeA.Expression) && !lastParallel.IsTempValue) { tempStatements.Add(string.Format(RATD + "[{0}]" + " = {1};", tempStatements.Count, lastParallel.Expression)); lastParallel.Expression = string.Format(RATD + "[{0}]", tempStatements.Count - 1); lastParallel.IsTempValue = true; } if (component.GetCompilerClass() == ComponentCompilerClass.InputFunction) { if (!string.IsNullOrEmpty(NodeA.Expression)) { NodeB += CompileInputFunctionComponent(component, NODE_NUMBER_MARKER + nodes.IndexOf(NodeA), codeBuffer); } else { NodeB += CompileInputFunctionComponent(component, TRUE, codeBuffer); } } else { outputs.AddOutputs(NodeA.Node, CompileOutputComponent(component, codeBuffer)); } } } #endregion if (codeBuffer.BoolTempCount < tempStatements.Count) { codeBuffer.BoolTempCount = tempStatements.Count; } List <string> sRung = BuildRung(tempStatements, nodes, outputs); if (!string.IsNullOrEmpty(rung.Comment)) { sRung.Insert(0, "/*" + rung.Comment + "*/"); } codeBuffer.Rungs.Add(sRung); } }