コード例 #1
0
        public override void visit(while_node wn)
        {
            var b = HasStatementVisitor <yield_node> .Has(wn);

            if (!b)
            {
                return;
            }

            var gotoBreak    = goto_statement.New;
            var gotoContinue = goto_statement.New;

            ReplaceBreakContinueWithGotoLabelVisitor replaceBreakContinueVis = new ReplaceBreakContinueWithGotoLabelVisitor(gotoContinue, gotoBreak);

            wn.statements.visit(replaceBreakContinueVis);

            ProcessNode(wn.statements);

            statement if0;

            //if (wn.expr is ident && (wn.expr as ident).name.ToLower() == "true")
            //    if0 = gotoBreak;
            //else
            if0 = new if_node(un_expr.Not(wn.expr), gotoBreak);
            var lb2 = new labeled_statement(gotoContinue.label, if0); // continue
            var lb1 = new labeled_statement(gotoBreak.label);         // break

            ReplaceStatement(wn, SeqStatements(lb2, wn.statements, gotoContinue, lb1));

            // в declarations ближайшего блока добавить описание labels
            block bl = listNodes.FindLast(x => x is block) as block;

            bl.defs.Add(new label_definitions(gotoBreak.label, gotoContinue.label));
        }
コード例 #2
0
        public node controls_if(ControlsIfBlock block)
        {
            // If/elseif/else condition.
            node code = null;

            if (block.elseCount_ != 0)
            {
                code = statementToCode(block, "ELSE");
                if (code == null)
                {
                    code = new nil_node(this);
                }
            }
            for (var n = block.elseifCount_; n >= 0; n--)
            {
                var argument = valueToCode(block, "IF" + n);
                if (argument == null)
                {
                    argument = new false_node(this);
                }
                var branch = statementToCode(block, "DO" + n);
                code = new if_node(this, argument, branch, code, false);
            }
            return(code);
        }
コード例 #3
0
        public override void visit(if_node _if_node)
        {
            var condition = _if_node.condition;

            if (condition is bin_expr binEpxr && HasExtendedIs(binEpxr))
            {
                if_node rightExprIfNode = null;
                if_node leftExprIfNode  = null;
                if (binEpxr.operation_type == Operators.LogicalAND)
                {
                    rightExprIfNode = new if_node(binEpxr.right, (statement)_if_node.then_body?.Clone(), (statement)_if_node.else_body?.Clone(), _if_node.source_context);
                    leftExprIfNode  = new if_node(binEpxr.left, rightExprIfNode, (statement)_if_node.else_body?.Clone(), _if_node.source_context);
                }
                else if (binEpxr.operation_type == Operators.LogicalOR)
                {
                    var rightExprThenBody = _if_node.else_body == null ? new empty_statement() : (statement)_if_node.else_body.Clone();
                    rightExprIfNode = new if_node(
                        new un_expr(binEpxr.right, Operators.LogicalNOT, binEpxr.source_context),
                        rightExprThenBody,
                        (statement)_if_node.then_body?.Clone(),
                        _if_node.source_context);

                    leftExprIfNode = new if_node(
                        new un_expr(binEpxr.left, Operators.LogicalNOT, binEpxr.source_context),
                        rightExprIfNode,
                        (statement)_if_node.then_body?.Clone(),
                        _if_node.source_context);
                }
                ReplaceUsingParent(_if_node, leftExprIfNode);
                visit(leftExprIfNode);
                visit(rightExprIfNode);
            }
        }
コード例 #4
0
        public override void visit(for_node fn)
        {
            ProcessNode(fn.statements);
            var b = HasStatementVisitor <yield_node> .Has(fn);

            if (!b)
            {
                return;
            }

            var gt1 = goto_statement.New;
            var gt2 = goto_statement.New;

            var endtemp = new ident(newVarName());
            var ass1    = new var_statement(fn.loop_variable, fn.type_name, fn.initial_value);
            var ass2    = new var_statement(endtemp, fn.type_name, fn.finish_value);


            var if0 = new if_node(bin_expr.Greater(fn.loop_variable, fn.finish_value), gt1);
            var lb2 = new labeled_statement(gt2.label, if0);
            var lb1 = new labeled_statement(gt1.label);
            var Inc = new procedure_call(new method_call(new ident("Inc"), new expression_list(fn.loop_variable)));

            ReplaceStatement(fn, SeqStatements(ass1, ass2, lb2, fn.statements, Inc, gt2, lb1));

            // в declarations ближайшего блока добавить описание labels
            block bl = listNodes.FindLast(x => x is block) as block;

            bl.defs.Add(new label_definitions(gt1.label, gt2.label));
        }
コード例 #5
0
        public override void visit(repeat_node rn)
        {
            var b = HasStatementVisitor <yield_node> .Has(rn);

            if (!b)
            {
                return;
            }

            var gotoContinue = goto_statement.New;
            var gotoBreak    = goto_statement.New;

            ReplaceBreakContinueWithGotoLabelVisitor replaceBreakContinueVis = new ReplaceBreakContinueWithGotoLabelVisitor(gotoContinue, gotoBreak);

            rn.statements.visit(replaceBreakContinueVis);

            ProcessNode(rn.statements);

            var gotoContinueIfNotCondition = new if_node(un_expr.Not(rn.expr), gotoContinue);
            var continueLabeledStatement   = new labeled_statement(gotoContinue.label, new statement_list(rn.statements, gotoContinueIfNotCondition));

            var breakLabeledStatement = new labeled_statement(gotoBreak.label);


            ReplaceStatement(rn, SeqStatements(gotoContinue, continueLabeledStatement, breakLabeledStatement));

            // в declarations ближайшего блока добавить описание labels
            block bl = listNodes.FindLast(x => x is block) as block;

            bl.defs.Add(new label_definitions(gotoContinue.label, gotoBreak.label));
        }
コード例 #6
0
        public override void visit(match_with matchWith)
        {
            desugaredMatchWith = null;
            _previousIf        = null;

            // Кэшируем выражение для однократного вычисления
            //var cachedExpression = NewGeneralName();
            //AddDefinitionsInUpperStatementList(matchWith, new[] { new var_statement(cachedExpression, matchWith.expr) });

            // Преобразование из сахара в известную конструкцию каждого case
            var usedDeconstructionTypes = new HashSet <string>();

            foreach (var patternCase in matchWith.case_list.elements)
            {
                if (patternCase == null)
                {
                    continue;
                }

                if (patternCase.pattern is deconstructor_pattern)
                {
                    // Проверяем встречался ли уже такой тип при деконструкции
                    // SSM 02.01.19 пока закомментировал этот кусок т.к. при этом коде падает стандартный пример ArithmSimplify.cs. #1408 снова открыл

                    /*var deconstructionType = (patternCase.pattern as deconstructor_pattern).
                     *  type as named_type_reference;
                     * if (deconstructionType != null &&
                     *  deconstructionType.names != null &&
                     *  deconstructionType.names.Count != 0)
                     * {
                     *  var deconstructionTypeName = deconstructionType.names[0].name;
                     *  if (usedDeconstructionTypes.Contains(deconstructionTypeName))
                     *  {
                     *      throw new SyntaxVisitorError("REPEATED_DECONSTRUCTION_TYPE",
                     *                                   patternCase.pattern.source_context);
                     *  }
                     *  usedDeconstructionTypes.Add(deconstructionTypeName);
                     * } */

                    DesugarDeconstructorPatternCase(matchWith.expr, patternCase);
                }
            }

            if (matchWith.defaultAction != null)
            {
                AddDefaultCase(matchWith.defaultAction as statement_list);
            }

            if (desugaredMatchWith == null)
            {
                desugaredMatchWith = new empty_statement();
            }

            // Замена выражения match with на новое несахарное поддерево и его обход
            ReplaceUsingParent(matchWith, desugaredMatchWith);
            visit(desugaredMatchWith);
        }
コード例 #7
0
 public override void visit(if_node _if_node)
 {
     AddPossibleComments(_if_node, true, false);
     _if_node.condition.visit(this);
     _if_node.then_body.visit(this);
     if (_if_node.else_body != null)
     {
         _if_node.else_body.visit(this);
     }
 }
コード例 #8
0
        private bool IsNestedIfWithExtendedIs(if_node ifNode)
        {
            var parent = ifNode.Parent;

            while (parent != null)
            {
                if (parent is statement_list stList &&
                    IsVisitElseBranchStatementListDeclaration(stList))
                {
                    return(true);
                }
                parent = parent.Parent;
            }
            return(false);
        }
コード例 #9
0
        private void AddDesugaredCaseToResult(statement desugaredCase, if_node newIf)
        {
            // Если результат пустой, значит это первый case
            if (desugaredMatchWith == null)
            {
                desugaredMatchWith = desugaredCase;
            }
            else
            {
                _previousIf.else_body = desugaredCase;
                _previousIf.FillParentsInDirectChilds();
            }

            // Запоминаем только что сгенерированный if
            _previousIf = newIf;
        }
コード例 #10
0
        private void VisitIf(if_node stmt)
        {
            RetVal rv = GetConstantValue(stmt.condition);

            VisitExpression(stmt.condition);
            if (rv == RetVal.False)
            {
                is_break_stmt = true;
            }
            VisitStatement(stmt.then_body);
            is_break_stmt = false;
            if (rv == RetVal.True)
            {
                is_break_stmt = true;
            }
            VisitStatement(stmt.else_body);
            is_break_stmt = false;
        }
コード例 #11
0
        public override void visit(if_node ifn)
        {
            ProcessNode(ifn.then_body);
            ProcessNode(ifn.else_body);

            var b = HasStatementVisitor <yield_node> .Has(ifn);

            if (!b)
            {
                return;
            }

            var gtAfter = goto_statement.New;
            var lbAfter = new labeled_statement(gtAfter.label);

            if ((object)ifn.else_body == null)
            {
                var if0 = new if_node(un_expr.Not(ifn.condition), gtAfter);
                //Replace(ifn, SeqStatements(gotoStartIfCondition, ifn.then_body, lbAfter));
                ReplaceStatement(ifn, SeqStatements(if0, ifn.then_body, lbAfter));

                // в declarations ближайшего блока добавить описание labels
                block bl = listNodes.FindLast(x => x is block) as block;

                bl.defs.Add(new label_definitions(gtAfter.label));
            }
            else
            {
                var gtAlt = goto_statement.New;
                var lbAlt = new labeled_statement(gtAlt.label, ifn.else_body);

                var if0 = new if_node(un_expr.Not(ifn.condition), gtAlt);

                ReplaceStatement(ifn, SeqStatements(if0, ifn.then_body, gtAfter, lbAlt, lbAfter));

                // в declarations ближайшего блока добавить описание labels
                block bl = listNodes.FindLast(x => x is block) as block;

                bl.defs.Add(new label_definitions(gtAfter.label, gtAlt.label));
            }
        }
コード例 #12
0
        public override void visit(while_node wn)
        {
            ProcessNode(wn.statements);
            var gt1 = new goto_statement(newLabelName());
            var gt2 = new goto_statement(newLabelName());
            var gt3 = new goto_statement(newLabelName());

            var if0 = new if_node(wn.expr, gt1, null);
            var lb3 = new labeled_statement(gt3.label, if0);
            var lb1 = new labeled_statement(gt1.label, wn.statements);
            var lb2 = new labeled_statement(gt2.label, new empty_statement());

            var stl = new statement_list(lb3, gt2, lb1, gt3, lb2);

            Replace(wn, stl);
            // в declarations ближайшего блока добавить описание labels
            block bl = listNodes.FindLast(x => x is block) as block;

            var ld = new label_definitions(gt1.label, gt2.label, gt3.label);

            bl.defs.Add(ld);
        }
コード例 #13
0
        public override void visit(match_with matchWith)
        {
            desugaredMatchWith = null;
            _previousIf        = null;

            // Кэшируем выражение для однократного вычисления
            //var cachedExpression = NewGeneralName();
            //AddDefinitionsInUpperStatementList(matchWith, new[] { new var_statement(cachedExpression, matchWith.expr) });

            // Преобразование из сахара в известную конструкцию каждого case
            foreach (var patternCase in matchWith.case_list.elements)
            {
                if (patternCase == null)
                {
                    continue;
                }

                if (patternCase.pattern is deconstructor_pattern)
                {
                    DesugarDeconstructorPatternCase(matchWith.expr, patternCase);
                }
            }

            if (matchWith.defaultAction != null)
            {
                AddDefaultCase(matchWith.defaultAction as statement_list);
            }

            if (desugaredMatchWith == null)
            {
                desugaredMatchWith = new empty_statement();
            }

            // Замена выражения match with на новое несахарное поддерево и его обход
            ReplaceUsingParent(matchWith, desugaredMatchWith);
            visit(desugaredMatchWith);
        }
コード例 #14
0
        public override void visit(while_node wn)
        {
            ProcessNode(wn.statements);
            var b = HasStatementVisitor <yield_node> .Has(wn);

            if (!b)
            {
                return;
            }

            var gt1 = goto_statement.New;
            var gt2 = goto_statement.New;

            var if0 = new if_node(un_expr.Not(wn.expr), gt1);
            var lb2 = new labeled_statement(gt2.label, if0);
            var lb1 = new labeled_statement(gt1.label);

            ReplaceStatement(wn, SeqStatements(lb2, wn.statements, gt2, lb1));

            // в declarations ближайшего блока добавить описание labels
            block bl = listNodes.FindLast(x => x is block) as block;

            bl.defs.Add(new label_definitions(gt1.label, gt2.label));
        }
コード例 #15
0
        private statement_list ConvertIfNode(if_node ifNode, List <statement> statementsBeforeIf, out statement elseBody)
        {
            // if e then <then> else <else>
            //
            // переводим в
            //
            // begin
            //   statementsBeforeIf
            //   if e then begin <then>; goto end_if end;
            // end
            // <else>
            // end_if: empty_statement

            // if e then <then>
            //
            // переводим в
            //
            // begin
            //   statementsBeforeIf
            //   if e then <then>
            // end

            // Добавляем, чтобы на конвертировать еще раз, если потребуется
            processedIfNodes.Add(ifNode);

            var statementsBeforeAndIf = new statement_list();

            statementsBeforeAndIf.AddMany(statementsBeforeIf);
            statementsBeforeAndIf.Add(ifNode);

            if (ifNode.else_body == null)
            {
                elseBody = null;
                return(statementsBeforeAndIf);
            }
            else
            {
                var result = new statement_list();
                result.Add(statementsBeforeAndIf);
                var endIfLabel = NewEndIfName();
                // добавляем метку
                if (!(ifNode.then_body is statement_list))
                {
                    ifNode.then_body        = new statement_list(ifNode.then_body, ifNode.then_body.source_context);
                    ifNode.then_body.Parent = ifNode;
                }

                var thenBody = ifNode.then_body as statement_list;
                thenBody.Add(new goto_statement(endIfLabel));
                // добавляем else и метку за ним
                result.Add(ifNode.else_body);
                result.Add(new labeled_statement(endIfLabel));
                // Возвращаем else для обхода, т.к. он уже не входит в if
                elseBody = ifNode.else_body;
                // удаляем else из if
                ifNode.else_body = null;
                // Добавляем метку
                AddLabel(endIfLabel);

                return(result);
            }
        }
コード例 #16
0
 public override void visit(if_node _if_node)
 {
 }
コード例 #17
0
 public virtual void visit(if_node _if_node)
 {
     DefaultVisit(_if_node);
 }
コード例 #18
0
		public virtual void post_do_visit(if_node _if_node)
		{
		}
コード例 #19
0
		public override void visit(if_node _if_node)
		{
			DefaultVisit(_if_node);
			pre_do_visit(_if_node);
			visit(if_node.condition);
			visit(if_node.then_body);
			visit(if_node.else_body);
			post_do_visit(_if_node);
		}
コード例 #20
0
		public virtual void visit(if_node _if_node)
		{
		}
コード例 #21
0
 public virtual void visit(if_node _if_node)
 {
 }
コード例 #22
0
 public override void visit(if_node _if_node)
 {
     prepare_node(_if_node.condition, "condition");
     prepare_node(_if_node.then_body, "then_body");
     prepare_node(_if_node.else_body, "else_body");
 }
コード例 #23
0
        private statement_list ConvertIfNode(if_node ifNode, List <statement> statementsBeforeIf, out statement elseBody)
        {
            // if e then <then> else <else>
            //
            // переводим в
            //
            // begin
            // var <>visitElseBranch := true;
            //   begin
            //     <>visitElseBranch := true;
            //     statementsBeforeIf
            //     if e then begin <then>; <>visitElseBranch := false; end;
            //   end
            //   if <>visitElseBranch then <else>
            // end

            // if e then <then>
            //
            // переводим в
            //
            // begin
            //   statementsBeforeIf
            //   if e then <then>
            // end

            // Добавляем объявление <>visitElseBranch если мы находимся в первом в цепочке if, который не является вложенным
            List <statement> visitElseStatList = null;

            if (ifNode.else_body != null &&
                !(ifNode.Parent is if_node ifParentNode &&
                  ifParentNode.condition is ident ifParentNodeIdent &&
                  ifParentNodeIdent.name.Equals(GeneratedVisitElseBranchVariableName)) &&
                !IsNestedIfWithExtendedIs(ifNode))
            {
                visitElseStatList = new List <statement>();
                visitElseStatList.Add(
                    new var_statement(
                        new ident(GeneratedVisitElseBranchVariableName, ifNode.source_context),
                        new bool_const(true, ifNode.source_context),
                        ifNode.source_context)
                    );
            }

            // Добавляем, чтобы на конвертировать еще раз, если потребуется
            processedIfNodes.Add(ifNode);

            if (ifNode.else_body != null)
            {
                statementsBeforeIf.Add(new assign(
                                           new ident(GeneratedVisitElseBranchVariableName, ifNode.source_context),
                                           new bool_const(true, ifNode.source_context),
                                           Operators.Assignment,
                                           ifNode.source_context));
            }
            var statementsBeforeAndIf = new statement_list();

            statementsBeforeAndIf.AddMany(statementsBeforeIf);
            statementsBeforeAndIf.Add(ifNode);

            if (ifNode.else_body == null)
            {
                elseBody = null;
                if (visitElseStatList != null)
                {
                    visitElseStatList.Add(statementsBeforeAndIf);
                    statementsBeforeAndIf = new statement_list(visitElseStatList);
                }
                return(statementsBeforeAndIf);
            }
            else
            {
                var result = new statement_list();
                result.Add(statementsBeforeAndIf);
                var endIfLabel = NewEndIfName();

                if (!(ifNode.then_body is statement_list))
                {
                    ifNode.then_body        = new statement_list(ifNode.then_body, ifNode.then_body.source_context);
                    ifNode.then_body.Parent = ifNode;
                }

                var thenBody = ifNode.then_body as statement_list;

                thenBody.Add(new assign(
                                 new ident(GeneratedVisitElseBranchVariableName, thenBody.source_context),
                                 new bool_const(false, thenBody.source_context),
                                 Operators.Assignment,
                                 thenBody.source_context));

                // добавляем else
                result.Add(
                    new if_node(
                        new ident(GeneratedVisitElseBranchVariableName, ifNode.else_body.source_context),
                        ifNode.else_body,
                        null,
                        ifNode.else_body.source_context));

                // Возвращаем else для обхода, т.к. он уже не входит в if
                elseBody = ifNode.else_body;
                // удаляем else из if
                ifNode.else_body = null;

                if (visitElseStatList != null)
                {
                    visitElseStatList.Add(result);
                    result = new statement_list(visitElseStatList);
                }

                return(result);
            }
        }
コード例 #24
0
        public override void visit(for_node fn)
        {
            var b = HasStatementVisitor <yield_node> .Has(fn);

            if (!b)
            {
                return;
            }

            var gotoContinue = goto_statement.New;
            var gotoBreak    = goto_statement.New;
            var gotoStart    = goto_statement.New;

            ReplaceBreakContinueWithGotoLabelVisitor replaceBreakContinueVis = new ReplaceBreakContinueWithGotoLabelVisitor(gotoContinue, gotoBreak);

            fn.statements.visit(replaceBreakContinueVis);

            ProcessNode(fn.statements);

            var newNames = this.NewVarNames(fn.loop_variable);

            var newLoopVar = fn.create_loop_variable ? new ident(newNames.VarName) : fn.loop_variable;

            // Нужно заменить fn.loop_variable -> newLoopVar в теле цикла
            var replacerVis = new ReplaceVariableNameVisitor(fn.loop_variable, newLoopVar);

            fn.visit(replacerVis);

            fn.loop_variable = newLoopVar;

            var endtemp = new ident(newNames.VarEndName); //new ident(newVarName());

            //var ass1 = new var_statement(fn.loop_variable, fn.type_name, fn.initial_value);
            //var ass1 = new var_statement(fn.loop_variable, fn.type_name, fn.initial_value);
            //var ass2 = new var_statement(endtemp, fn.type_name, fn.finish_value);

            // frninja 05/06/16 - фиксим для !fn.create_variable
            var ass1 = fn.create_loop_variable
                ? new var_statement(fn.loop_variable, fn.type_name, fn.initial_value) as statement
                : new assign(fn.loop_variable, fn.initial_value) as statement;


            var if0 = new if_node((fn.cycle_type == for_cycle_type.to) ?
                                  bin_expr.Greater(fn.loop_variable, fn.finish_value) :
                                  bin_expr.Less(fn.loop_variable, fn.finish_value), gotoBreak);

            var lb2 = new labeled_statement(gotoStart.label, if0);
            var lb1 = new labeled_statement(gotoBreak.label);
            var Inc = new procedure_call(new method_call((fn.cycle_type == for_cycle_type.to) ?
                                                         new ident("Inc") :
                                                         new ident("Dec"), new expression_list(fn.loop_variable)));

            var lbInc = new labeled_statement(gotoContinue.label, Inc);

            ReplaceStatement(fn, SeqStatements(ass1, lb2, fn.statements, lbInc, gotoStart, lb1));

            // в declarations ближайшего блока добавить описание labels
            block bl = listNodes.FindLast(x => x is block) as block;

            bl.defs.Add(new label_definitions(gotoContinue.label, gotoBreak.label, gotoStart.label));
        }
コード例 #25
0
		public virtual void visit(if_node _if_node)
		{
			DefaultVisit(_if_node);
		}
コード例 #26
0
        public override void visit(for_node fn)
        {
            var b = HasStatementVisitor <yield_node> .Has(fn);

            if (!b)
            {
                return;
            }

            var gotoContinue = goto_statement.New;
            var gotoBreak    = goto_statement.New;
            var gotoStart    = goto_statement.New;

            ReplaceBreakContinueWithGotoLabelVisitor replaceBreakContinueVis = new ReplaceBreakContinueWithGotoLabelVisitor(gotoContinue, gotoBreak);

            fn.statements.visit(replaceBreakContinueVis);

            ProcessNode(fn.statements);

            var newNames = this.NewVarNames(fn.loop_variable);

            var newLoopVar = fn.create_loop_variable ? new ident(newNames.VarName) : fn.loop_variable;

            // Нужно заменить fn.loop_variable -> newLoopVar в теле цикла
            var replacerVis = new ReplaceVariableNameVisitor(fn.loop_variable, newLoopVar);

            fn.visit(replacerVis);

            fn.loop_variable = newLoopVar;

            var endtemp = new ident(newNames.VarEndName); //new ident(newVarName());

            //var ass1 = new var_statement(fn.loop_variable, fn.type_name, fn.initial_value);
            //var ass1 = new var_statement(fn.loop_variable, fn.type_name, fn.initial_value);
            //var ass2 = new var_statement(endtemp, fn.type_name, fn.finish_value);

            // Исправления в связи с #1254 (новый алгоритм)
            // цикл for i:=a to b do
            //          i := a
            //          if i > b then goto break
            //Start:    stmts
            //          if i >= b then goto break
            //Continue: Inc(i)
            //          goto Start
            //Break:

            // цикл for i:=a downto b do
            //          i := a
            //          if i < b then goto break
            //Start:    stmts
            //          if i <= b then goto break
            //Continue: Dec(i)
            //          goto Start
            //Break:

            // frninja 05/06/16 - фиксим для !fn.create_variable
            var ass1 = fn.create_loop_variable
                ? new var_statement(fn.loop_variable, fn.type_name, fn.initial_value) as statement
                : new assign(fn.loop_variable, fn.initial_value) as statement;

            var if0 = new if_node((fn.cycle_type == for_cycle_type.to) ?
                                  bin_expr.Greater(fn.loop_variable, fn.finish_value) :
                                  bin_expr.Less(fn.loop_variable, fn.finish_value), gotoBreak);

            var if1 = new if_node((fn.cycle_type == for_cycle_type.to) ?
                                  bin_expr.GreaterEqual(fn.loop_variable, fn.finish_value) :
                                  bin_expr.LessEqual(fn.loop_variable, fn.finish_value), gotoBreak);

            var lb1 = new labeled_statement(gotoStart.label);
            var lb2 = new labeled_statement(gotoBreak.label); // пустой оператор
            var Inc = new procedure_call(new method_call((fn.cycle_type == for_cycle_type.to) ?
                                                         new ident("Inc") :
                                                         new ident("Dec"), new expression_list(fn.loop_variable)));

            var lbInc = new labeled_statement(gotoContinue.label, Inc);

            ReplaceStatement(fn, SeqStatements(ass1, if0, lb1, fn.statements, if1, lbInc, gotoStart, lb2));

            /*var if0 = new if_node((fn.cycle_type == for_cycle_type.to) ?
             *  bin_expr.Greater(fn.loop_variable, fn.finish_value) :
             *  bin_expr.Less(fn.loop_variable, fn.finish_value), gotoBreak);
             *
             * var lb2 = new labeled_statement(gotoStart.label, if0);
             * var lb1 = new labeled_statement(gotoBreak.label); // пустой оператор
             * var Inc = new procedure_call(new method_call((fn.cycle_type == for_cycle_type.to) ?
             *  new ident("Inc") :
             *  new ident("Dec"), new expression_list(fn.loop_variable)));
             *
             * var lbInc = new labeled_statement(gotoContinue.label, Inc);
             *
             * ReplaceStatement(fn, SeqStatements(ass1, lb2, fn.statements, lbInc, gotoStart, lb1));*/

            // в declarations ближайшего блока добавить описание labels
            block bl = listNodes.FindLast(x => x is block) as block;

            bl.defs.Add(new label_definitions(gotoContinue.label, gotoBreak.label, gotoStart.label));
        }
コード例 #27
0
        public override void visit(match_with matchWith)
        {
            desugaredMatchWith = null;
            _previousIf        = null;

            matchedExprVarDeclaration = new var_statement(
                new ident(GeneratedMatchExprVariableName, matchWith.expr.source_context),
                matchWith.expr.Clone() as expression,
                matchWith.expr.source_context);
            ReplaceUsingParent(matchWith.expr, new ident(GeneratedMatchExprVariableName, matchWith.expr.source_context));

            /*if (matchWith.Parent is statement_list stl)
             * {
             *  stl.InsertBefore(matchWith, matchedExprVarDeclaration);
             * }
             * else
             * {
             *  var enclosingStl = new statement_list(matchedExprVarDeclaration, matchWith);
             *  enclosingStl.source_context = matchWith.source_context;
             *  ReplaceUsingParent(matchWith, enclosingStl);
             * }*/

            // Кэшируем выражение для однократного вычисления
            //var cachedExpression = NewGeneralName();
            //AddDefinitionsInUpperStatementList(matchWith, new[] { new var_statement(cachedExpression, matchWith.expr) });

            // Преобразование из сахара в известную конструкцию каждого case
            var usedDeconstructionTypes = new HashSet <string>();

            foreach (var patternCase in matchWith.case_list.elements)
            {
                if (patternCase == null)
                {
                    continue;
                }
                DefaultDesugarPattern(matchWith.expr, patternCase);

                /*switch (patternCase.pattern)
                 * {
                 *  case deconstructor_pattern pattern:
                 *      {
                 *          // Проверяем встречался ли уже такой тип при деконструкции
                 *          // SSM 02.01.19 пока закомментировал этот кусок т.к. при этом коде падает стандартный пример ArithmSimplify.cs. #1408 снова открыл
                 *          var deconstructionType = (patternCase.pattern as deconstructor_pattern).
                 *              type as named_type_reference;
                 *          if (deconstructionType != null &&
                 *              deconstructionType.names != null &&
                 *              deconstructionType.names.Count != 0)
                 *          {
                 *              var deconstructionTypeName = deconstructionType.names[0].name;
                 *              if (usedDeconstructionTypes.Contains(deconstructionTypeName))
                 *              {
                 *                  throw new SyntaxVisitorError("REPEATED_DECONSTRUCTION_TYPE",
                 *                                               patternCase.pattern.source_context);
                 *              }
                 *              usedDeconstructionTypes.Add(deconstructionTypeName);
                 *          }
                 *
                 * DefaultDesugarPattern(matchWith.expr, patternCase);
                 *          break;
                 *      }
                 *  case const_pattern p:
                 *      {
                 *          //DesugarConstPatternCase(matchWith.expr, patternCase);
                 *          DefaultDesugarPattern(matchWith.expr, patternCase);
                 *          break;
                 *      }
                 *  case collection_pattern p:
                 *      {
                 *          DefaultDesugarPattern(matchWith.expr, patternCase);
                 *          break;
                 *      }
                 *  case tuple_pattern p:
                 *      {
                 *          DefaultDesugarPattern(matchWith.expr, patternCase);
                 *          break;
                 *      }
                 * }*/
            }

            if (matchWith.defaultAction != null)
            {
                AddDefaultCase(matchWith.defaultAction as statement_list);
            }

            if (desugaredMatchWith == null)
            {
                desugaredMatchWith = new empty_statement();
            }

            if (typeChecks.Count != 0)
            {
                typeChecks.Add(desugaredMatchWith);
                desugaredMatchWith = new statement_list(typeChecks);
            }

            desugaredMatchWith = new statement_list(matchedExprVarDeclaration, desugaredMatchWith);

            // Замена выражения match with на новое несахарное поддерево и его обход
            ReplaceUsingParent(matchWith, desugaredMatchWith);
            visit(desugaredMatchWith);
        }
コード例 #28
0
		public override void visit(if_node _if_node)
		{
			executer.visit(_if_node);
			if (_if_node.condition != null)
				this.visit((dynamic)_if_node.condition);
			if (_if_node.then_body != null)
				this.visit((dynamic)_if_node.then_body);
			if (_if_node.else_body != null)
				this.visit((dynamic)_if_node.else_body);
			if (_if_node.attributes != null)
				this.visit((dynamic)_if_node.attributes);
		}
コード例 #29
0
        // frninja 30/05/16
        public override void visit(case_node csn)
        {
            var b = HasStatementVisitor <yield_node> .Has(csn);

            if (!b)
            {
                return;
            }

            /*
             *
             * case i of
             *   cv1: bla1;
             *   cv2: bla2;
             *   ..
             *   cvN: blaN;
             * else: bla_else;
             *
             * --->
             *
             * if i satisfy cv1
             *   then bla1
             * else if i satisfy cv2
             *   then bla2
             * ..
             * else if i satisfy cvN
             *   then blaN
             * else bla_else
             *
             */

            if_node   currentIfNode       = null;
            statement currentIfElseClause = (csn.else_statement != null) ? csn.else_statement :new statement_list(new empty_statement());;

            for (int i = csn.conditions.variants.Count - 1; i >= 0; --i)
            {
                case_variant cv = csn.conditions.variants[i];

                ProcessNode(cv.exec_if_true);

                var ifCondition = this.CreateConditionFromCaseVariant(csn.param, cv.conditions);
                currentIfNode       = new if_node(ifCondition, new statement_list(cv.exec_if_true), new statement_list(currentIfElseClause));
                currentIfElseClause = currentIfNode;
            }

            if_node finalIfNode = currentIfNode;

            if (finalIfNode == null) // SSM - значит, в цикл мы не заходили и у case отсутствуют все ветви кроме else - поскольку yieldы в case есть
            {
                ReplaceStatement(csn, csn.else_statement);
            }
            else
            {
                ReplaceStatement(csn, finalIfNode);
            }

            if (finalIfNode != null)
            {
                visit(finalIfNode);
            }
        }