public override void Compile(CompileContext context)
        {
            if (context.Options.Optimize && !ElseBranch.IsUsed)
            {
                IfBranch.Compile(context);
                return;
            }
            else if (context.Options.Optimize && !IfBranch.IsUsed)
            {
                ElseBranch.Compile(context);
                return;
            }
            Label elseStart = context.ILGenerator.DefineLabel();
            Label elseEnd   = context.ILGenerator.DefineLabel();

            context.MarkSequencePoint(Expression.LexicalInfo);
            this.Expression.Compile(context);
            context.ILGenerator.Emit(OpCodes.Brfalse, elseStart);
            IfBranch.Compile(context);
            context.ILGenerator.Emit(OpCodes.Br, elseEnd);
            context.ILGenerator.MarkLabel(elseStart);
            ElseBranch.Compile(context);
            context.ILGenerator.MarkLabel(elseEnd);
            if (context.Options.Debug && ElseBranch.LexicalInfo.EndLine != 0)
            {
                LexicalInfo l = ElseBranch.LexicalInfo;
                context.ILGenerator.MarkSequencePoint(context.DebugWriter, l.EndLine, l.EndColumn + 1, l.EndLine, l.EndColumn + 1);
            }
        }
예제 #2
0
        private ConditionBlock TranslateCondition(ICodeBlock parent, string condition, int startPos, out int endPos)
        {
            var result = new ConditionBlock(parent, Parser.ParseLine(condition), null);

            endPos = FindBlockEnd(startPos + 1);

            result.IfCode = Translate(result, startPos + 1, endPos);

            if (endPos >= Code.Count)
            {
                return(result);
            }

            var match = ElifBranch.Match(Code[endPos]);

            if (match.Success)
            {
                result.ElseCode = TranslateCondition(parent, match.Groups["condition"].ToString(),
                                                     endPos, out endPos);
            }
            else if (ElseBranch.IsMatch(Code[endPos]))
            {
                var endElse = FindBlockEnd(endPos + 1);
                result.ElseCode = Translate(result, endPos + 1, endElse);
                endPos          = endElse;
            }

            return(result);
        }
예제 #3
0
        public override void GenerateIntermediateCode()
        {
            //номер условного оператора, нужен для формирования меток
            int num_if = ++Counters.ifs;

            Condition.GenerateIntermediateCode();
            //то, что получилось, сравниваем с нулём
            if (Condition.MainVariable.Type == "int")
            {
                IntermediateCodeList.push(new CmpNode(Condition.MainVariable, new ConstantNode("int", "0", 0).MainVariable));
            }
            else if (Condition.MainVariable.Type == "bool")
            {
                IntermediateCodeList.push(new CmpNode(Condition.MainVariable, new ConstantNode("bool", "false", 0).MainVariable));
            }
            else
            {
                Console.WriteLine("Что-то не так с типами");
            }

            if (ElseBranch == null)
            {
                //если else-ветки нет, формируем метку на выход, если условие не выполнено
                //если равно нулю, то условие ложно и уходим
                IntermediateCodeList.push(new GoToLabel("exit_if_" + num_if.ToString(), "je"));
            }
            else
            {
                //если вторая ветка есть, формируем метку на неё
                IntermediateCodeList.push(new GoToLabel("else_" + num_if.ToString(), "je"));
            }
            //генерим код для if-ветки, она будет в любом случае
            IfBranch.GenerateIntermediateCode();
            //если есть вторая ветка, надо сгенерить код для неё
            if (ElseBranch != null)
            {
                //из if-ветки отправляем на выход
                IntermediateCodeList.push(new GoToLabel("exit_if_" + num_if.ToString(), "jmp"));
                //ставим метку else
                IntermediateCodeList.push(new PutLabel("else_" + num_if.ToString()));
                //Генерируем код else-ветки
                ElseBranch.GenerateIntermediateCode();
            }
            //ставим метку на выход
            IntermediateCodeList.push(new PutLabel("exit_if_" + num_if.ToString()));
        }
예제 #4
0
        public override bool SemanticAnalysis()
        {
            IsSemanticCorrect = true;
            try
            {
                IsSemanticCorrect &= Condition.SemanticAnalysis();
            }
            catch (SemanticException e)
            {
                Console.WriteLine(e.Message);
                IsSemanticCorrect = false;
            }

            try
            {
                IsSemanticCorrect &= IfBranch.SemanticAnalysis();
            }
            catch
            {
                IsSemanticCorrect = false;
            }

            if (ElseBranch != null)
            {
                try
                {
                    IsSemanticCorrect = ElseBranch.SemanticAnalysis();
                }
                catch (SemanticException e)
                {
                    Console.WriteLine(e.Message);
                    IsSemanticCorrect = false;
                }
            }

            IfBranch.CheckVariables();
            if (ElseBranch != null)
            {
                ElseBranch.CheckVariables();
            }
            return(IsSemanticCorrect);
        }