private List <Node> GenerateNode(List <string> lines, Vector2 startPoint, ref int index, Transform parent, bool inBody) { index++; var nodes = new List <Node>(); var line = lines[index]; if (line == KeyWords.begin.ToString() || line == KeyWords.initialization.ToString()) { List <Node> newNodes; while ((newNodes = GenerateNode(lines, startPoint, ref index, parent, true)) != null) { nodes.AddRange(newNodes); if (newNodes.Any()) { startPoint = new Vector2(startPoint.x, newNodes.Last().GetBottom().y) + new Vector2(0, -g_Margin); } } } else if (line == KeyWords.end.ToString() || line == KeyWords.end + ".") { return(null); } else if (line.StartsWith("function ") || line.StartsWith("procedure ")) { var fNode = parent.AppendNew(Prefabs.FuncNode, startPoint - Prefabs.FuncNode.Offset); fNode.Index = index; line = line.TrimString("function").TrimString("procedure").Trim(); fNode.Name = line.Cut(0, line.IndexOf('(') - 1); fNode.Text = "Начало <" + fNode.Name + ">"; do { int sPos = lines[index].IndexOf("(") + 1; int ePos = lines[index].IndexOf(")"); fNode.Args.Add(lines[index].Cut(sPos, ePos == -1 ? lines[index].Length - 1 : ePos - 1)); }while (lines[index++].IndexOf(")") == -1); while (lines[index] != KeyWords.begin.ToString()) { fNode.Vars.Add(lines[index].TrimString("vars").Trim(')', '(', ' ')); index++; } index--; fNode.children.AddRange(GenerateNode(lines, (Vector2)fNode.transform.position + new Vector2(0, fNode.ExitPoint.y - g_Margin), ref index, fNode.transform, true)); var endNode = fNode.transform.AppendNew(Prefabs.BeginEndNode, fNode.GetBottom() - Prefabs.FuncNode.Offset); endNode.Text = "Конец"; fNode.children.Add(endNode); nodes.Add(fNode); } else if (line.StartsWithAny(KeyWords.@if)) { var IfNode = parent.AppendNew(Prefabs.IfNode, startPoint - Prefabs.IfNode.Offset); IfNode.Index = index; IfNode.Condition = line.Remove(0, 2).Trim(' '); IfNode.TrueNodes.AddRange(GenerateNode(lines, (Vector2)IfNode.transform.position + new Vector2(IfWidth / 2, IfNode.ExitPoint.y - g_Margin), ref index, parent, true)); if (lines[index + 1] == "else") { index++; IfNode.FalseNodes.AddRange(GenerateNode(lines, (Vector2)IfNode.transform.position + new Vector2(IfNode.TrueNodes.Any(x => x is IfNode) ? -IfWidth : -IfWidth / 2, IfNode.ExitPoint.y - g_Margin), ref index, parent, true)); if (IfNode.FalseNodes.Any(x => x is IfNode)) { IfNode.TrueNodes.ForEach(x => x.Translate(new Vector2(IfWidth / 2, 0))); } if (IfNode.TrueNodes.Any() && IfNode.FalseNodes.Any()) { var d = -IfNode.TrueNodes.Min(x => x.GetWidthLimits().x) + IfNode.FalseNodes.Max(x => x.GetWidthLimits().y); if (d > 0) { IfNode.TrueNodes.ForEach(x => x.Translate(new Vector2(d / 2 + UIController.MarginLineDistance, 0))); IfNode.FalseNodes.ForEach(x => x.Translate(new Vector2(-d / 2 - UIController.MarginLineDistance, 0))); } } } nodes.Add(IfNode); _lastCodeNode = null; } else if (line.StartsWithAny(KeyWords.@while)) { var WhileNode = parent.AppendNew(Prefabs.WhileNode, startPoint - Prefabs.WhileNode.Offset); WhileNode.Index = index; WhileNode.Condition = line.Remove(0, 5).Trim(' '); WhileNode.children.AddRange(GenerateNode(lines, (Vector2)WhileNode.transform.position + new Vector2(0, WhileNode.ExitPoint.y - g_Margin), ref index, parent, true)); nodes.Add(WhileNode); _lastCodeNode = null; } else if (line.StartsWith(KeyWords.repeat)) { var WhileNode = parent.AppendNew(Prefabs.RepeatNode, startPoint - Prefabs.WhileNode.Offset); WhileNode.Index = index; List <Node> newNodes; while ((newNodes = GenerateNode(lines, startPoint, ref index, parent, true)) != null) { WhileNode.children.AddRange(newNodes); if (newNodes.Any()) { startPoint = new Vector2(startPoint.x, newNodes.Last().GetBottom().y) + new Vector2(0, -g_Margin); } if (newNodes.LastOrDefault() is UntilNode) { break; } } nodes.Add(WhileNode); } else if (line.StartsWithAny(KeyWords.until)) { var untilNode = parent.AppendNew(Prefabs.UntilNode, startPoint - Prefabs.WhileNode.Offset); line = line.Remove(0, 5).Trim(); untilNode.Condition = line; nodes.Add(untilNode); _lastCodeNode = null; } else if (line.StartsWithAny(KeyWords.@for)) { var ForNode = parent.AppendNew(Prefabs.ForNode, startPoint - Prefabs.ForNode.Offset); ForNode.Index = index; ForNode.Condition = line.Remove(0, 3).Trim(' '); ForNode.children.AddRange(GenerateNode(lines, (Vector2)ForNode.transform.position + new Vector2(0, ForNode.ExitPoint.y - g_Margin), ref index, parent, true)); nodes.Add(ForNode); _lastCodeNode = null; } else if (line.StartsWith("write(") || line.StartsWith("read(") || line.StartsWith("writeln(") || line.StartsWith("readln(") || line == "writeln" || line == "write" || line == "read" || line == "readln") { if (_lastCodeNode != null && _lastCodeNode.EndIndex == index - 1 && _lastCodeNode.GetType() == typeof(IONode)) { _lastCodeNode.EndIndex = index; _lastCodeNode.Text += "\n" + line + ";"; if (_lastCodeNode.EndIndex - _lastCodeNode.Index > MaxNodeLinesCount) { _lastCodeNode = null; } } else { _lastCodeNode = parent.AppendNew(Prefabs.IONode, startPoint - Prefabs.CodeNode.Offset); _lastCodeNode.Index = index; _lastCodeNode.EndIndex = index; _lastCodeNode.Text = line + ";"; nodes.Add(_lastCodeNode); } } else if (line.StartsWithAny(KeyWords.var) && !inBody) { VarNode vNode = parent.AppendNew(Prefabs.VarNode, startPoint - Prefabs.VarNode.Offset); vNode.Index = index; vNode.EndIndex = index; vNode.AddVar(line.Remove(0, 3).Trim()); while (!lines[index + 1].StartsWithAny(KeyWords.begin, KeyWords.uses, KeyWords.function, KeyWords.procedure, KeyWords.type, KeyWords.@const)) //while (lines[index+1].ContainsAny("begin", "uses", "function", "procedure", "type") == null) { vNode.AddVar(lines[index + 1]); index++; } nodes.Add(vNode); } else if (line.StartsWithAny(KeyWords.except)) { var exceptNode = parent.AppendNew(Prefabs.IfNode, startPoint - Prefabs.WhileNode.Offset); exceptNode.Index = index; exceptNode.Condition = "{exception occured}"; List <Node> node; while ((node = GenerateNode(lines, (Vector2)exceptNode.transform.position + new Vector2(0, exceptNode.ExitPoint.y - g_Margin), ref index, parent, true)) != null) { exceptNode.TrueNodes.AddRange(node); } nodes.Add(exceptNode); _lastCodeNode = null; } else if (line.StartsWithAny(KeyWords.@const)) { ConstNode vNode = parent.AppendNew(Prefabs.ConstNode, startPoint - Prefabs.VarNode.Offset); vNode.Index = index; vNode.EndIndex = index; vNode.AddVar(line.Remove(0, 5).Trim()); while (!lines[index + 1].StartsWithAny()) //while (lines[index+1].ContainsAny("begin", "uses", "function", "procedure", "type") == null) { vNode.AddVar(lines[index + 1]); index++; } nodes.Add(vNode); } else if (line.StartsWithAny(KeyWords.uses)) { line = line.Remove(0, 4); try { foreach (var lib in line.Split(',').Select(x => x.Trim())) { int inChar = lib.IndexOf(" in "); string fileName = lib + ".pas"; if (inChar != -1) { int l1 = lib.IndexOf("@%"); int l2 = lib.IndexOf("%@"); if (l1 != -1 && l2 > l1) { fileName = Literals[int.Parse(lib.Cut(l1 + 2, l2 - 1))].Trim(' ', '.', '\'', '/', (char)92); } } print(fileName); if (System.IO.File.Exists(fileName)) { string code = System.IO.File.ReadAllText(fileName); string finCode = null; int implementation = code.IndexOf("implementation"); code = code.Remove(0, implementation + "implementation".Length); int finalization = code.IndexOf("finalization"); int codeLen = code.Length; if (finalization != -1) { finCode = code.Remove(0, finalization + "finalization".Length); code = code.Substring(0, finalization) + "end."; } //print(code); var parsed = ParseCode(code); var unit = GenerateUnit(parsed, ref startPoint, ref TopPoint, lib.Split()[0]); if (unit.Any()) { nodes.AddRange(unit); var joint = parent.AppendNew(Prefabs.JointNode, new Vector2(startPoint.x, unit.Last().GetBottom().y)); nodes.Add(joint); } } } } catch (Exception e) { UnityEngine.Debug.LogException(e); } } else if (line.StartsWithAny(KeyWords.type, KeyWords.program)) { } else { var function = Functions.Any() ? line.ContainsAny(Functions.Keys) : null; if (function != null) { FunctionCallNode node = parent.AppendNew(Prefabs.FunctionCallNode, startPoint - Prefabs.CodeNode.Offset); node.Index = index; node.Text = line + ";"; node.Function = Functions[function]; nodes.Add(node); } else { if (_lastCodeNode != null && _lastCodeNode.EndIndex == index - 1 && _lastCodeNode.GetType() == typeof(CodeNode)) { _lastCodeNode.EndIndex = index; _lastCodeNode.Text += "\r\n" + line + ";"; if (_lastCodeNode.EndIndex - _lastCodeNode.Index > MaxNodeLinesCount) { _lastCodeNode = null; } } else { _lastCodeNode = parent.AppendNew(Prefabs.CodeNode, startPoint - Prefabs.CodeNode.Offset); _lastCodeNode.Index = index; _lastCodeNode.EndIndex = index; _lastCodeNode.Text = line + ";"; nodes.Add(_lastCodeNode); } } } return(nodes); }