コード例 #1
0
ファイル: Generator.cs プロジェクト: SkyForce/RobotsLanguage
        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("}");
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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, "", "");
            }
        }
コード例 #4
0
ファイル: Generator.cs プロジェクト: SkyForce/RobotsLanguage
        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);
        }