public void Start() { //controller.ValidateCustom(RobotModel, "ValidateAll"); foreach (SubprogramNode element in RobotModel.SubprogramNode) { go(element, ""); } foreach (AbstractNode n in RobotModel.AbstractNode) { if (n is ParallelNode) { int cur = 0; var list = AbstractNodeReferencesTargetAbstractNode.GetLinksToTargetAbstractNode(n); for (int i = 0; i < list.Count; i++) { if (!list[i].Condition.Equals(AbstractNodeReferencesTargetAbstractNode.GetLinksToSourceAbstractNode(n)[0].Condition)) { writer.WriteLine("function " + n.ElemName + "_" + cur + "() {"); writer.PushIndent(" "); generate(n.TargetAbstractNode[i], "FinishNode", true, false, "", list[i].Condition); writer.PopIndent(); writer.WriteLine("}"); cur++; } } } } AbstractNode f = null; writer.WriteLine("function main() {"); writer.PushIndent(" "); foreach (AbstractNode ab in RobotModel.AbstractNode) { if (ab is StartNode) { f = ab; break; } } generate(f.TargetAbstractNode[0], "FinishNode", true, false, "", ""); writer.PopIndent(); writer.WriteLine("}"); }
AbstractNode generate(AbstractNode f, String end, bool flag, bool isCycle, String subName, String thread) { while (f != null && (isCycle || (flag ? !f.ElemName.StartsWith(end) : !f.ElemName.Equals(end)))) { if (!isCycle && !(f is FinishNode) && !(f is EndParallelNode)) { if (nodes.Contains(f.ElemName)) { context.LogError("Incorrect cycle found", "cycle"); return(null); } nodes.Add(f.ElemName); } if (!isCycle && !(f is FinishNode) && (f is IterationsNode && f.SourceAbstractNode.Count == 3 || (f is EndIfNode) && f.SourceAbstractNode.Count == 3 || !(f is IterationsNode) && !(f is EndIfNode) && !(f is EndParallelNode) && f.SourceAbstractNode.Count == 2)) { f = generate(f, f.ElemName, false, true, subName, thread); } else if (f is FinishNode) { break; } //Warning(f.GetType().ToString()); else if (f is IfNode) { AbstractNode g = null, g1 = null; for (int i = 0; i < f.TargetAbstractNode.Count; i++) { String cond = AbstractNodeReferencesTargetAbstractNode.GetLinksToTargetAbstractNode(f)[i].Condition; if (cond.Equals("out")) { continue; } else if (cond.Equals("true")) { g = generate(f.TargetAbstractNode[i], "EndIfNode", true, false, subName, thread); } else { g1 = generate(f.TargetAbstractNode[i], "EndIfNode", true, false, subName, thread); } } if (g1 == null) { f = g; } else if (g == null) { f = g1; } else if (f != g) { context.LogError("EndIF must be the same", "if", f); return(null); } } else if (f is SubprogramCallNode) { for (int i = 0; i < f.TargetAbstractNode.Count; i++) { String cond = AbstractNodeReferencesTargetAbstractNode.GetLinksToTargetAbstractNode(f)[i].Condition; if (cond.Equals("out")) { continue; } f = f.TargetAbstractNode[i]; } } else if (f is IterationsNode) { for (int i = 0; i < f.TargetAbstractNode.Count; i++) { String cond = AbstractNodeReferencesTargetAbstractNode.GetLinksToTargetAbstractNode(f)[i].Condition; if (cond.Equals("out")) { continue; } f = generate(f.TargetAbstractNode[i], f.ElemName, false, false, subName, thread); } } else if (f is EndParallelNode) { if (!AbstractNodeReferencesTargetAbstractNode.GetLinksToTargetAbstractNode(f)[0].Condition.Equals(thread)) { break; } else { var list = AbstractNodeReferencesTargetAbstractNode.GetLinksToSourceAbstractNode(f); f = f.TargetAbstractNode[0]; } } else if (f is ParallelNode) { var list = AbstractNodeReferencesTargetAbstractNode.GetLinksToTargetAbstractNode(f); AbstractNode g = null, g0 = null; int cur = 0; if (list.Count(obj => obj.Condition == thread) != 1) { context.LogError("Only one link must be the same thread", "thread", f); return(null); } for (int i = 0; i < list.Count; i++) { if (!thread.Equals(list[i].Condition)) { if (hs.Contains(list[i].Condition)) { context.LogError("Repeatable thread name", "thread", f); return(null); } hs.Add(list[i].Condition); AbstractNode g1 = generate(list[i].TargetAbstractNode, "FinishNode", true, false, "", list[i].Condition); if (g0 != null && g1 != g0) { context.LogError("EndParallel must be the same", "parallel", f); return(null); } else { g0 = g1; } cur++; } else { g = f.TargetAbstractNode[i]; } } f = g; } else if (f is BreakNode) { break; } else if (f is SwitchNode) { AbstractNode g, g0 = null; for (int i = 0; i < f.TargetAbstractNode.Count; i++) { String cond = AbstractNodeReferencesTargetAbstractNode.GetLinksToTargetAbstractNode(f)[i].Condition; if (cond.Equals("out")) { continue; } g = generate(f.TargetAbstractNode[i], "EndSwitch", true, false, subName, thread); if (g != null) { if (g0 != null && g != g0) { context.LogError("EndSwitch must be the same", "switch", f); return(null); } else { g0 = g; } } } f = g0; } else if (f is WaitSensorNode || f is DelayNode || f is MotorsNode || f is MotorsOffNode || f is WaitTouchNode) { f = AbstractNodeReferencesTargetAbstractNode.GetLinksToTargetAbstractNode(f).First(obj => obj.Condition != "out").TargetAbstractNode; } isCycle = false; } if (f != null) { nodes.Add(f.ElemName); } if (f == null) { return(null); } for (int i = 0; i < f.TargetAbstractNode.Count; i++) { String cond = AbstractNodeReferencesTargetAbstractNode.GetLinksToTargetAbstractNode(f)[i].Condition; if (cond.Equals("out")) { return(f.TargetAbstractNode[i]); } } return(f.TargetAbstractNode.Count > 0 ? f.TargetAbstractNode[f.TargetAbstractNode.Count - 1] : null); }
void ValidateSubprogram(Compound elem) { AbstractNode st = null; foreach (AbstractNode an in elem.AbstractNode) { if (an is StartNode) { if (st != null) { context.LogError("Start node must be one", "start", an); } st = an; if (an.SourceAbstractNode.Count != 0) { context.LogError("Incorrect source elements", "source", an); } if (an.TargetAbstractNode.Count != 1) { context.LogError("Incorrect target elements", "target", an); } } else if (an is FinishNode) { if (an.TargetAbstractNode.Count != 0) { context.LogError("Incorrect target elements", "target", an); } } else if (an is IfNode) { if (an.SourceAbstractNode.Count > 2 || an.SourceAbstractNode.Count == 0) { context.LogError("Incorrect source elements", "source", an); } if (an.TargetAbstractNode.Count != 2 && an.SourceAbstractNode.Count == 1 || an.TargetAbstractNode.Count != 3 && an.SourceAbstractNode.Count == 2) { context.LogError("Incorrect target elements", "target", an); } if (!AbstractNodeReferencesTargetAbstractNode.GetLinksToTargetAbstractNode(an).Any(obj => obj.Condition == "true")) { context.LogError("No true link", "true", an); } if (an.TargetAbstractNode.Count == 3 && !AbstractNodeReferencesTargetAbstractNode.GetLinksToTargetAbstractNode(an).Any(obj => obj.Condition == "out")) { context.LogError("No out for cycle", "out", an); } } else if (an is EndIfNode) { if (an.SourceAbstractNode.Count < 1 || an.SourceAbstractNode.Count > 2) { context.LogError("Incorrect source elements", "source", an); } if (an.TargetAbstractNode.Count != 1) { context.LogError("Incorrect target elements", "target", an); } } else if (an is IterationsNode) { if (an.SourceAbstractNode.Count != 2) { context.LogError("Incorrect source elements", "source", an); } if (an.TargetAbstractNode.Count != 2) { context.LogError("Incorrect target elements", "target", an); } } else if (an is SubprogramCallNode) { if (an.SourceAbstractNode.Count < 1 || an.SourceAbstractNode.Count > 2) { context.LogError("Incorrect source elements", "source", an); } if (an.TargetAbstractNode.Count != 1 && an.SourceAbstractNode.Count == 1 || an.TargetAbstractNode.Count != 2 && an.SourceAbstractNode.Count == 2) { context.LogError("Incorrect target elements", "target", an); } if (!SubprogramNode.Any(obj => obj.ElemName == (an as SubprogramCallNode).Subprogram)) { context.LogError("No subprogram with such name", "subprogram", an); } if (an.SourceAbstractNode.Count == 2 && !AbstractNodeReferencesTargetAbstractNode.GetLinksToTargetAbstractNode(an).Any(obj => obj.Condition == "out")) { context.LogError("No out for cycle", "out", an); } } else if (an is ParallelNode) { if (an.SourceAbstractNode.Count != 1) { context.LogError("Incorrect source elements", "source", an); } if (an.TargetAbstractNode.Count < 2) { context.LogError("Incorrect target elements", "target", an); } } else if (an is EndParallelNode) { if (an.SourceAbstractNode.Count < 2) { context.LogError("Incorrect source elements", "source", an); } if (an.TargetAbstractNode.Count != 1) { context.LogError("Incorrect target elements", "target", an); } } else if (an is BreakNode) { if (an.SourceAbstractNode.Count != 1) { context.LogError("Incorrect source elements", "source", an); } if (an.TargetAbstractNode.Count != 0) { context.LogError("Incorrect target elements", "target", an); } } else if (an is SwitchNode) { if (an.SourceAbstractNode.Count < 1 || an.SourceAbstractNode.Count > 2) { context.LogError("Incorrect source elements", "source", an); } if (an.TargetAbstractNode.Count < 1 && an.SourceAbstractNode.Count == 1 || an.TargetAbstractNode.Count < 2 && an.SourceAbstractNode.Count == 2) { context.LogError("Incorrect target elements", "target", an); } if (AbstractNodeReferencesTargetAbstractNode.GetLinksToTargetAbstractNode(an).Count(obj => obj.Condition == "") > 1) { context.LogError("Only one link must be default", "default", an); } if (an.SourceAbstractNode.Count == 2 && !AbstractNodeReferencesTargetAbstractNode.GetLinksToTargetAbstractNode(an).Any(obj => obj.Condition == "out")) { context.LogError("No out for cycle", "out", an); } } else if (an is EndSwitchNode) { if (an.SourceAbstractNode.Count < 1) { context.LogError("Incorrect source elements", "source", an); } if (an.TargetAbstractNode.Count != 1) { context.LogError("Incorrect target elements", "target", an); } } else if (an is WaitSensorNode || an is DelayNode || an is MotorsNode || an is MotorsOffNode || an is WaitTouchNode) { if (an.SourceAbstractNode.Count < 1 || an.SourceAbstractNode.Count > 2) { context.LogError("Incorrect source elements", "source", an); } if (an.TargetAbstractNode.Count != 1 && an.SourceAbstractNode.Count == 1 || an.TargetAbstractNode.Count != 2 && an.SourceAbstractNode.Count == 2) { context.LogError("Incorrect target elements", "target", an); } if (an.SourceAbstractNode.Count == 2 && !AbstractNodeReferencesTargetAbstractNode.GetLinksToTargetAbstractNode(an).Any(obj => obj.Condition == "out")) { context.LogError("No out for cycle", "out", an); } if (an is WaitSensorNode && (((WaitSensorNode)an).Port.Equals(String.Empty) || ((WaitSensorNode)an).ReceivedValue.Equals(String.Empty))) { context.LogError("Fields must be non-empty", "fields", an); } else if (an is MotorsNode && (((MotorsNode)an).Ports.Equals(String.Empty))) { context.LogError("Fields must be non-empty", "fields", an); } else if (an is MotorsOffNode && (((MotorsOffNode)an).Ports.Equals(String.Empty))) { context.LogError("Fields must be non-empty", "fields", an); } else if (an is WaitTouchNode && (((WaitTouchNode)an).Port.Equals(String.Empty))) { context.LogError("Fields must be non-empty", "fields", an); } } else { context.LogError("unknown", "unknown", an); } } if (context.CurrentViolations.Count == 0) { nodes.Clear(); nodes.Add(st.ElemName); hs.Clear(); hs.Add(""); generate(st.TargetAbstractNode[0], "FinishNode", true, false, "", ""); } }
AbstractNode generate(AbstractNode f, String end, bool flag, bool isCycle, String subName, String thread) { while (isCycle || (f != null && (flag ? !f.ElemName.StartsWith(end) : !f.ElemName.Equals(end)))) { if (!isCycle && !(f is FinishNode) && (f is IterationsNode && f.SourceAbstractNode.Count == 3 || (f is EndIfNode) && f.SourceAbstractNode.Count == 3 || !(f is IterationsNode) && !(f is EndIfNode) && !(f is EndParallelNode) && f.SourceAbstractNode.Count == 2)) { writer.WriteLine("while(true) {"); writer.PushIndent(" "); f = generate(f, f.ElemName, false, true, subName, thread); writer.PopIndent(); writer.WriteLine("}"); //f = null; } else if (f is FinishNode) { writer.WriteLine("return;"); break; } //Warning(f.GetType().ToString()); else if (f is IfNode) { AbstractNode g = null; for (int i = 0; i < f.TargetAbstractNode.Count; i++) { String cond = AbstractNodeReferencesTargetAbstractNode.GetLinksToTargetAbstractNode(f)[i].Condition; if (cond.Equals("out")) { continue; } else if (cond.Equals("true")) { writer.WriteLine("if (" + (f as IfNode).condition + ") {"); writer.PushIndent(" "); g = generate(f.TargetAbstractNode[i], "EndIfNode", true, false, subName, thread); writer.PopIndent(); writer.WriteLine("}"); } } for (int i = 0; i < f.TargetAbstractNode.Count; i++) { String cond = AbstractNodeReferencesTargetAbstractNode.GetLinksToTargetAbstractNode(f)[i].Condition; if (cond.Equals("out")) { continue; } else if (!cond.Equals("true")) { writer.WriteLine("else {"); writer.PushIndent(" "); f = generate(f.TargetAbstractNode[i], "EndIfNode", true, false, subName, thread); writer.PopIndent(); writer.WriteLine("}"); break; } } if (f == null) { f = g; } } else if (f is SubprogramCallNode) { writer.WriteLine(((SubprogramCallNode)f).Subprogram + "();"); for (int i = 0; i < f.TargetAbstractNode.Count; i++) { String cond = AbstractNodeReferencesTargetAbstractNode.GetLinksToTargetAbstractNode(f)[i].Condition; if (cond.Equals("out")) { continue; } f = f.TargetAbstractNode[i]; } } else if (f is IterationsNode) { writer.WriteLine(String.Format("for ({0} = 0; {0} < {1}; {0}++) {{", f.ElemName, (f as IterationsNode).number)); writer.PushIndent(" "); for (int i = 0; i < f.TargetAbstractNode.Count; i++) { String cond = AbstractNodeReferencesTargetAbstractNode.GetLinksToTargetAbstractNode(f)[i].Condition; if (cond.Equals("out")) { continue; } f = generate(f.TargetAbstractNode[i], f.ElemName, false, false, subName, thread); } writer.PopIndent(); writer.WriteLine("}"); } else if (f is EndParallelNode) { if (!AbstractNodeReferencesTargetAbstractNode.GetLinksToTargetAbstractNode(f)[0].Condition.Equals(thread)) { writer.WriteLine("return;"); break; } else { var list = AbstractNodeReferencesTargetAbstractNode.GetLinksToSourceAbstractNode(f); for (int i = 0; i < list.Count; i++) { if (!thread.Equals(list[i].Condition)) { writer.WriteLine("Threading.joinThread(\"{0}\");", list[i].Condition.Equals("") ? "main" : list[i].Condition); } } f = f.TargetAbstractNode[0]; } } else if (f is ParallelNode) { var list = AbstractNodeReferencesTargetAbstractNode.GetLinksToTargetAbstractNode(f); AbstractNode g = null; int cur = 0; for (int i = 0; i < list.Count; i++) { if (!thread.Equals(list[i].Condition)) { writer.WriteLine("Threading.startThread(\"{0}\", \"{1}\");", list[i].Condition, subName + f.ElemName + "_" + cur); cur++; } else { g = f.TargetAbstractNode[i]; } } f = g; } else if (f is BreakNode) { writer.WriteLine("break;"); break; } else if (f is SwitchNode) { writer.WriteLine(String.Format("switch ({0}) {{", ((SwitchNode)f).Condition)); AbstractNode g, g0 = null; writer.PushIndent(" "); for (int i = 0; i < f.TargetAbstractNode.Count; i++) { String cond = AbstractNodeReferencesTargetAbstractNode.GetLinksToTargetAbstractNode(f)[i].Condition; if (cond.Equals("out")) { continue; } else if (cond.Equals("")) { writer.WriteLine("default:"); } else { writer.WriteLine(String.Format("case {0}:", AbstractNodeReferencesTargetAbstractNode.GetLinksToTargetAbstractNode(f)[i].Condition)); } writer.PushIndent(" "); g = generate(f.TargetAbstractNode[i], "EndSwitch", true, false, subName, thread); writer.WriteLine("break;"); writer.PopIndent(); if (g != null) { g0 = g; } } writer.PopIndent(); writer.WriteLine("}"); f = g0; } else if (f is MotorsNode) { String[] ports = ((MotorsNode)f).Ports.Split(','); int power = ((MotorsNode)f).Power; foreach (String s in ports) { writer.WriteLine("brick.motor({0}).setPower({1});", s, power); } f = AbstractNodeReferencesTargetAbstractNode.GetLinksToTargetAbstractNode(f).First(obj => obj.Condition != "out").TargetAbstractNode; } else if (f is DelayNode) { int ms = ((DelayNode)f).Time; writer.WriteLine("script.wait({0});", ms); f = AbstractNodeReferencesTargetAbstractNode.GetLinksToTargetAbstractNode(f).First(obj => obj.Condition != "out").TargetAbstractNode; } else if (f is WaitSensorNode) { int dist = ((WaitSensorNode)f).Distance; string rv = ((WaitSensorNode)f).ReceivedValue; string port = ((WaitSensorNode)f).Port; writer.WriteLine("while (!(brick.sensor({0}).read() {1} {2})) {{", port, rv, dist); writer.PushIndent(" "); writer.WriteLine("script.wait(10);"); writer.PopIndent(); writer.WriteLine("}"); f = AbstractNodeReferencesTargetAbstractNode.GetLinksToTargetAbstractNode(f).First(obj => obj.Condition != "out").TargetAbstractNode; } else if (f is WaitTouchNode) { string port = ((WaitTouchNode)f).Port; writer.WriteLine("while (brick.sensor({0}).read() < 0) {{", port); writer.PushIndent(" "); writer.WriteLine("script.wait(10);"); writer.PopIndent(); writer.WriteLine("}"); f = AbstractNodeReferencesTargetAbstractNode.GetLinksToTargetAbstractNode(f).First(obj => obj.Condition != "out").TargetAbstractNode; } else if (f is MotorsOffNode) { String[] ports = ((MotorsOffNode)f).Ports.Split(','); foreach (String s in ports) { writer.WriteLine("brick.motor({0}).powerOff();", s); } f = AbstractNodeReferencesTargetAbstractNode.GetLinksToTargetAbstractNode(f).First(obj => obj.Condition != "out").TargetAbstractNode; } isCycle = false; } if (f is FinishNode && end.StartsWith("FinishNode")) { writer.WriteLine("return;"); } if (f == null) { return(null); } for (int i = 0; i < f.TargetAbstractNode.Count; i++) { String cond = AbstractNodeReferencesTargetAbstractNode.GetLinksToTargetAbstractNode(f)[i].Condition; if (cond.Equals("out")) { return(f.TargetAbstractNode[i]); } } return(f.TargetAbstractNode.Count > 0 ? f.TargetAbstractNode[f.TargetAbstractNode.Count - 1] : null); }