예제 #1
0
        public override void VisitForStatement(ForStatementSyntax node)
        {
            ContinueInfo ci = new ContinueInfo();

            ci.Init(node.Statement);
            m_ContinueInfoStack.Push(ci);

            if (null != node.Declaration)
            {
                VisitVariableDeclaration(node.Declaration);
            }
            CodeBuilder.AppendFormat("{0}while ", GetIndentString());
            if (null != node.Condition)
            {
                var oper = m_Model.GetOperation(node) as IForLoopStatement;
                IConversionExpression opd = null;
                if (null != oper)
                {
                    opd = oper.Condition as IConversionExpression;
                }
                OutputExpressionSyntax(node.Condition, opd);
            }
            else
            {
                CodeBuilder.AppendLine("true");
            }
            CodeBuilder.AppendLine(" do");
            if (ci.HaveContinue)
            {
                if (ci.HaveBreak)
                {
                    CodeBuilder.AppendFormat("{0}local {1} = false", GetIndentString(), ci.BreakFlagVarName);
                    CodeBuilder.AppendLine();
                }
                CodeBuilder.AppendFormat("{0}repeat", GetIndentString());
                CodeBuilder.AppendLine();
            }
            ++m_Indent;
            node.Statement.Accept(this);
            --m_Indent;
            if (ci.HaveContinue)
            {
                CodeBuilder.AppendFormat("{0}until true;", GetIndentString());
                CodeBuilder.AppendLine();
                if (ci.HaveBreak)
                {
                    CodeBuilder.AppendFormat("{0}if {1} then break; end;", GetIndentString(), ci.BreakFlagVarName);
                    CodeBuilder.AppendLine();
                }
            }
            foreach (var exp in node.Incrementors)
            {
                CodeBuilder.AppendFormat("{0}", GetIndentString());
                VisitToplevelExpression(exp, ";");
            }
            CodeBuilder.AppendFormat("{0}end;", GetIndentString());
            CodeBuilder.AppendLine();

            m_ContinueInfoStack.Pop();
        }
예제 #2
0
        public override void VisitForEachStatement(ForEachStatementSyntax node)
        {
            ContinueInfo ci = new ContinueInfo();

            ci.Init(node.Statement);
            m_ContinueInfoStack.Push(ci);

            string varName = string.Format("__compiler_foreach_{0}", node.GetLocation().GetLineSpan().StartLinePosition.Line);

            CodeBuilder.AppendFormat("{0}local {1} = (", GetIndentString(), varName);
            IConversionExpression opd = null;
            var oper = m_Model.GetOperation(node) as IForEachLoopStatement;

            if (null != oper)
            {
                opd = oper.Collection as IConversionExpression;
            }
            OutputExpressionSyntax(node.Expression, opd);
            CodeBuilder.AppendLine("):GetEnumerator();");
            CodeBuilder.AppendFormat("{0}while {1}:MoveNext() do", GetIndentString(), varName);
            CodeBuilder.AppendLine();
            if (ci.HaveContinue)
            {
                if (ci.HaveBreak)
                {
                    CodeBuilder.AppendFormat("{0}local {1} = false", GetIndentString(), ci.BreakFlagVarName);
                    CodeBuilder.AppendLine();
                }
                CodeBuilder.AppendFormat("{0}repeat", GetIndentString());
                CodeBuilder.AppendLine();
            }
            ++m_Indent;
            CodeBuilder.AppendFormat("{0}{1} = {2}.Current;", GetIndentString(), node.Identifier.Text, varName);
            CodeBuilder.AppendLine();
            node.Statement.Accept(this);
            --m_Indent;
            if (ci.HaveContinue)
            {
                CodeBuilder.AppendFormat("{0}until true;", GetIndentString());
                CodeBuilder.AppendLine();
                if (ci.HaveBreak)
                {
                    CodeBuilder.AppendFormat("{0}if {1} then break; end;", GetIndentString(), ci.BreakFlagVarName);
                    CodeBuilder.AppendLine();
                }
            }
            CodeBuilder.AppendFormat("{0}end;", GetIndentString());
            CodeBuilder.AppendLine();

            m_ContinueInfoStack.Pop();
        }
예제 #3
0
        public override void VisitDoStatement(DoStatementSyntax node)
        {
            ContinueInfo ci = new ContinueInfo();

            ci.Init(node.Statement);
            m_ContinueInfoStack.Push(ci);

            CodeBuilder.AppendFormat("{0}repeat", GetIndentString());
            CodeBuilder.AppendLine();
            if (ci.HaveContinue)
            {
                if (ci.HaveBreak)
                {
                    CodeBuilder.AppendFormat("{0}local {1} = false", GetIndentString(), ci.BreakFlagVarName);
                    CodeBuilder.AppendLine();
                }
                CodeBuilder.AppendFormat("{0}repeat", GetIndentString());
                CodeBuilder.AppendLine();
            }
            ++m_Indent;
            node.Statement.Accept(this);
            --m_Indent;
            if (ci.HaveContinue)
            {
                CodeBuilder.AppendFormat("{0}until true;", GetIndentString());
                CodeBuilder.AppendLine();
                if (ci.HaveBreak)
                {
                    CodeBuilder.AppendFormat("{0}if {1} then break; end;", GetIndentString(), ci.BreakFlagVarName);
                    CodeBuilder.AppendLine();
                }
            }
            CodeBuilder.AppendFormat("{0}until not (", GetIndentString());
            var oper = m_Model.GetOperation(node) as IWhileUntilLoopStatement;
            IConversionExpression opd = null;

            if (null != oper)
            {
                opd = oper.Condition as IConversionExpression;
            }
            OutputExpressionSyntax(node.Condition, opd);
            CodeBuilder.AppendLine(");");

            m_ContinueInfoStack.Pop();
        }
예제 #4
0
        public override void VisitDoStatement(DoStatementSyntax node)
        {
            ContinueInfo ci = new ContinueInfo();

            ci.Init(node.Statement);
            m_ContinueInfoStack.Push(ci);

            CodeBuilder.AppendFormat("{0}repeat", GetIndentString());
            CodeBuilder.AppendLine();
            if (ci.HaveContinue)
            {
                if (ci.HaveBreak)
                {
                    CodeBuilder.AppendFormat("{0}local {1} = false", GetIndentString(), ci.BreakFlagVarName);
                    CodeBuilder.AppendLine();
                }
                CodeBuilder.AppendFormat("{0}repeat", GetIndentString());
                CodeBuilder.AppendLine();
            }
            ++m_Indent;
            node.Statement.Accept(this);
            --m_Indent;
            if (ci.HaveContinue)
            {
                CodeBuilder.AppendFormat("{0}until true;", GetIndentString());
                CodeBuilder.AppendLine();
                if (ci.HaveBreak)
                {
                    CodeBuilder.AppendFormat("{0}if {1} then break; end;", GetIndentString(), ci.BreakFlagVarName);
                    CodeBuilder.AppendLine();
                }
            }
            CodeBuilder.AppendFormat("{0}until not (", GetIndentString());
            VisitExpressionSyntax(node.Condition);
            CodeBuilder.AppendLine(");");

            m_ContinueInfoStack.Pop();
        }
예제 #5
0
        public override void VisitSwitchStatement(SwitchStatementSyntax node)
        {
            string     varName = string.Format("__compiler_switch_{0}", node.GetLocation().GetLineSpan().StartLinePosition.Line);
            SwitchInfo si      = new SwitchInfo();

            si.SwitchVarName = varName;
            m_SwitchInfoStack.Push(si);

            CodeBuilder.AppendFormat("{0}local {1} = ", GetIndentString(), varName);
            IConversionExpression opd = null;
            var oper = m_Model.GetOperation(node) as ISwitchStatement;

            if (null != oper)
            {
                opd = oper.Value as IConversionExpression;
            }
            OutputExpressionSyntax(node.Expression, opd);
            CodeBuilder.AppendLine(";");

            int ct = node.Sections.Count;
            SwitchSectionSyntax defaultSection = null;

            for (int i = 0; i < ct; ++i)
            {
                var section = node.Sections[i];
                int lct     = section.Labels.Count;
                for (int j = 0; j < lct; ++j)
                {
                    var label = section.Labels[j];
                    if (label is DefaultSwitchLabelSyntax)
                    {
                        defaultSection = section;
                        break;
                    }
                }
            }
            for (int i = 0; i < ct; ++i)
            {
                var section = node.Sections[i];
                if (section == defaultSection)
                {
                    continue;
                }
                ContinueInfo ci = new ContinueInfo();
                ci.Init(section);
                m_ContinueInfoStack.Push(ci);

                BreakAnalysis ba = new BreakAnalysis();
                ba.Visit(section);
                if (ba.BreakCount > 1)
                {
                    ci.IsIgnoreBreak = false;
                }
                else
                {
                    ci.IsIgnoreBreak = true;
                }

                CodeBuilder.AppendFormat("{0}{1} ", GetIndentString(), i == 0 ? "if" : "elseif");
                int lct = section.Labels.Count;
                for (int j = 0; j < lct; ++j)
                {
                    var label = section.Labels[j] as CaseSwitchLabelSyntax;
                    if (null != label)
                    {
                        if (lct > 1)
                        {
                            CodeBuilder.Append("(");
                        }
                        CodeBuilder.AppendFormat("{0} == ", varName);
                        OutputExpressionSyntax(label.Value);
                        if (lct > 1)
                        {
                            CodeBuilder.Append(")");
                            if (j < lct - 1)
                            {
                                CodeBuilder.Append(" or ");
                            }
                        }
                    }
                }
                CodeBuilder.AppendLine(" then");
                if (ba.BreakCount > 1)
                {
                    CodeBuilder.AppendFormat("{0}repeat", GetIndentString());
                    CodeBuilder.AppendLine();
                }
                ++m_Indent;

                int sct = section.Statements.Count;
                for (int j = 0; j < sct; ++j)
                {
                    var statement = section.Statements[j];
                    statement.Accept(this);
                }

                --m_Indent;
                if (ba.BreakCount > 1)
                {
                    CodeBuilder.AppendFormat("{0}until 0 ~= 0;", GetIndentString());
                    CodeBuilder.AppendLine();
                }

                m_ContinueInfoStack.Pop();
            }
            if (null != defaultSection)
            {
                ContinueInfo ci = new ContinueInfo();
                ci.Init(defaultSection);
                m_ContinueInfoStack.Push(ci);

                BreakAnalysis ba = new BreakAnalysis();
                ba.Visit(defaultSection);
                if (ba.BreakCount > 1)
                {
                    ci.IsIgnoreBreak = false;
                }
                else
                {
                    ci.IsIgnoreBreak = true;
                }
                CodeBuilder.AppendFormat("{0}else", GetIndentString());
                CodeBuilder.AppendLine();
                if (ba.BreakCount > 1)
                {
                    CodeBuilder.AppendFormat("{0}repeat", GetIndentString());
                    CodeBuilder.AppendLine();
                }
                ++m_Indent;

                int sct = defaultSection.Statements.Count;
                for (int j = 0; j < sct; ++j)
                {
                    var statement = defaultSection.Statements[j];
                    statement.Accept(this);
                }

                --m_Indent;
                if (ba.BreakCount > 1)
                {
                    CodeBuilder.AppendFormat("{0}until 0 ~= 0;", GetIndentString());
                    CodeBuilder.AppendLine();
                }
                CodeBuilder.AppendFormat("{0}end;", GetIndentString());
                CodeBuilder.AppendLine();

                m_ContinueInfoStack.Pop();
            }
            else
            {
                CodeBuilder.AppendFormat("{0}end;", GetIndentString());
                CodeBuilder.AppendLine();
            }

            m_SwitchInfoStack.Pop();
        }