private PsudoInstruction CompileCase(PsudoMethod method, string variable, int start, out int endLine) { int nextStart = codeLines.ToList().FindIndex(start + 1, item => item.Contains(":") || Regex.IsMatch(item, @"^[\s]*\b(endcase)\b[\s]*", RegexOptions.IgnoreCase) ); if (nextStart < 0) { throw new Exception("CASE found with no ENDCASE"); } string[] parts = codeLines[start].Split(':'); string lineBackup = codeLines[start]; // Do this to help the compiler codeLines[start] = parts[1].Trim(); if (parts[0].Trim().ToLower().Contains("other")) { BlockInstruction ins = new BlockInstruction(start, method); ins.Instructions = CompileBlock(method, start, nextStart - 1); endLine = nextStart; codeLines[start] = lineBackup; return(ins); } else { string decision = variable + "==" + parts[0].Trim(); DecisionInstruction ins = new DecisionInstruction(start, method, decision); ins.Instructions = CompileBlock(method, start, nextStart - 1); if (codeLines[nextStart].ToLower().Contains("endcase")) { endLine = nextStart; ins.FalseInstruction = new NoOpInstruction(endLine, method); } else { ins.FalseInstruction = CompileCase(method, variable, nextStart, out endLine); } ins.EndInstruction = new NoOpInstruction(endLine, method); codeLines[start] = lineBackup; return(ins); } }
private void CreateChildren(List <PsudoInstruction> instructions, FlowChartItemControl parent) { FlowChartItemControl tempParent = parent; FlowChartItemControl item = null; foreach (PsudoInstruction inst in instructions) { item = new FlowChartItemControl(inst); this.drawingPanel.Controls.Add(item); if (inst is BlockInstruction) { tempParent.AddChild(item); CreateChildren(((BlockInstruction)inst).Instructions, item); } else if (inst is DecisionInstruction) { tempParent.AddChild(item); DecisionInstruction decision = (DecisionInstruction)inst; if (decision.FalseInstruction is BlockInstruction || decision.FalseInstruction is NoOpInstruction) { FlowChartItemControl trueBlock = new FlowChartItemControl("TRUE"); FlowChartItemControl falseBlock = new FlowChartItemControl("FALSE"); trueBlock.IsLabelNode = true; falseBlock.IsLabelNode = true; item.AddChild(trueBlock); item.AddChild(falseBlock); this.drawingPanel.Controls.Add(trueBlock); this.drawingPanel.Controls.Add(falseBlock); CreateChildren(decision.CodeBlock.Instructions, trueBlock); if (decision.FalseInstruction is BlockInstruction) { CreateChildren(((BlockInstruction)decision.FalseInstruction).Instructions, falseBlock); } } else { CreateChildren(decision.CodeBlock.Instructions, item); while (decision.FalseInstruction is DecisionInstruction) { decision = (DecisionInstruction)decision.FalseInstruction; CreateChildren(decision.CodeBlock.Instructions, item); } } FlowChartItemControl end = new FlowChartItemControl("End"); this.drawingPanel.Controls.Add(end); foreach (FlowChartItemControl child in item.Children) { AddToEndofChildren(child, end); } item = end; } else if (inst is DoLoopInstruction) { DoLoopInstruction loop = (DoLoopInstruction)inst; FlowChartItemControl doNode = new FlowChartItemControl("DO"); this.drawingPanel.Controls.Add(doNode); tempParent.AddChild(doNode); CreateChildren(loop.Instructions, doNode); AddToEndofChildren(tempParent, item); item.LoopBack = doNode; } else if (inst is ForLoopInstruction) { ForLoopInstruction loop = (ForLoopInstruction)inst; FlowChartItemControl initNode = new FlowChartItemControl(loop.InitInstruction); this.drawingPanel.Controls.Add(initNode); tempParent.AddChild(initNode); initNode.AddChild(item); CreateChildren(loop.Instructions, item); FlowChartItemControl updateNode = new FlowChartItemControl(loop.UpdateInstruction); this.drawingPanel.Controls.Add(updateNode); AddToEndofChildren(item, updateNode); updateNode.LoopBack = item; } else if (inst is WhileLoopInstruction) { tempParent.AddChild(item); WhileLoopInstruction loop = (WhileLoopInstruction)inst; CreateChildren(loop.Instructions, item); FlowChartItemControl temp = item.Children[0]; while (temp.Children.Count > 0) { temp = temp.Children[0]; } temp.LoopBack = item; } else { tempParent.AddChild(item); } tempParent = item; } }
protected PsudoInstruction CompileDecision(PsudoMethod method, int line, out int endLine) { if (Regex.IsMatch(codeLines[line], @"^[\s]*\b(if|elseif)\b[\s]*", RegexOptions.IgnoreCase)) { string decision = codeLines[line].Trim(); if (decision.ToLower().Contains("elseif")) { decision = decision.Substring(6); } else { decision = decision.Substring(2); } while (!decision.ToLower().Contains("then")) { if (line + 1 == codeLines.Length || Regex.IsMatch(codeLines[line + 1], @"^[\s]*\b(else|elseif|endif)\b[\s]*", RegexOptions.IgnoreCase) ) { throw new Exception("IF found without THEN"); } decision += " " + codeLines[line + 1]; line += 1; } decision = decision.Trim(); decision = decision.Substring(0, decision.Length - 4).Trim(); DecisionInstruction ins = new DecisionInstruction(line, method, decision); int next = -1; int end = -1; int nested = 0; for (int num = line + 1; num < codeLines.Length; num++) { string item = codeLines[num]; if (Regex.IsMatch(item, @"^[\s]*\b(if)\b[\s]*", RegexOptions.IgnoreCase)) { nested++; } if (Regex.IsMatch(item, @"^[\s]*\b(endif)\b[\s]*", RegexOptions.IgnoreCase)) { if (nested == 0) { if (next < 0) { next = num; } end = num; } else { nested--; } } if (nested == 0 && next < 0) { if (Regex.IsMatch(item, @"^[\s]*\b(elseif|else)\b[\s]*", RegexOptions.IgnoreCase)) { next = num; } } } if (end < 0) { throw new Exception("IF found with no ENDIF"); } ins.Instructions = CompileBlock(method, line + 1, next - 1); int temp; ins.FalseInstruction = CompileDecision(method, next, out temp); ins.EndInstruction = CompileDecision(method, end, out temp); endLine = end; return(ins); } else if (Regex.IsMatch(codeLines[line], @"^[\s]*\b(else)\b[\s]*", RegexOptions.IgnoreCase)) { BlockInstruction ins = new BlockInstruction(line, method); int next = codeLines.ToList().FindIndex(line, item => Regex.IsMatch(item, @"^[\s]*\b(endif)\b[\s]*", RegexOptions.IgnoreCase)); ins.Instructions = CompileBlock(method, line + 1, next - 1); endLine = next; return(ins); } else if (Regex.IsMatch(codeLines[line], @"^[\s]*\b(endif)\b[\s]*", RegexOptions.IgnoreCase)) { endLine = line; return(new NoOpInstruction(line, method)); } else if (Regex.IsMatch(codeLines[line], @"^[\s]*\b(case of|case)\b[\s]*", RegexOptions.IgnoreCase)) { // Trim of case/case of string variable = Regex.Replace(codeLines[line], @"\b(case of|case)\b", "").Trim(); int start = codeLines.ToList().FindIndex(line + 1, item => item.Contains(":")); if (start < 0) { throw new Exception("CASE Statement contains no options or options are formmed incorrectly"); } return(CompileCase(method, variable, start, out endLine)); } endLine = line; return(null); }