private void VisitFor(for_node stmt)
		{
            if(CanWriteObject(stmt.initialization_statement))
			    VisitStatement(stmt.initialization_statement);
			VisitExpression(stmt.while_expr);
			if (CanWriteObject(stmt.init_while_expr))
				VisitExpression(stmt.init_while_expr);
			VisitStatement(stmt.increment_statement);
			VisitStatement(stmt.body);
			bw.Write(stmt.bool_cycle);
		}
예제 #2
0
 private void VisitFor(for_node stmt)
 {
     if (extended_mode)
     {
         if (stmt.init_while_expr is basic_function_call)
         {
             basic_function_call bfc = stmt.init_while_expr as basic_function_call;
             if (!(bfc.real_parameters[0] is local_block_variable_reference))
                 AddHint("USE_LOCAL_BLOCK_VARIABLES_FOR_CYCLE_COUNTER", stmt.location);
             else
             {
                 local_block_variable lbv = (bfc.real_parameters[0] as local_block_variable_reference).var;
                 if (lbv.loc.begin_line_num < stmt.location.begin_line_num || lbv.loc.begin_column_num < stmt.location.end_column_num)
                     AddHint("USE_LOCAL_BLOCK_VARIABLES_CYCLE_COUNTER", stmt.location);
             }
         }
     }
     VisitStatement(stmt.init_while_expr);
     VisitStatement(stmt.initialization_statement);
     VisitStatement(stmt.increment_statement);
     VisitExpression(stmt.while_expr);
     VisitStatement(stmt.body);
 }
        public override void visit(SyntaxTree.for_node _for_node)
        {
            #region MikhailoMMX, обработка omp parallel for
            bool isGenerateParallel = false;
            bool isGenerateSequential = true;
            if (OpenMP.ForsFound)
            {
                OpenMP.LoopVariables.Push(_for_node.loop_variable.name.ToLower());
                //если в программе есть хоть одна директива parallel for - проверяем:
                if (DirectivesToNodesLinks.ContainsKey(_for_node) && OpenMP.IsParallelForDirective(DirectivesToNodesLinks[_for_node]))
                {
                    //перед этим узлом есть директива parallel for
                    if (CurrentParallelPosition == ParallelPosition.Outside)            //входим в самый внешний параллельный for
                    {
                        if (_for_node.create_loop_variable || (_for_node.type_name != null))
                        {
                            //сгенерировать сначала последовательную ветку, затем параллельную
                            //устанавливаем флаг и продолжаем конвертирование, считая, что конвертируем последовательную ветку
                            isGenerateParallel = true;
                            CurrentParallelPosition = ParallelPosition.InsideSequential;
                            //в конце за счет флага вернем состояние обратно и сгенерируем и параллельную ветку тоже
                        }
                        else
                            WarningsList.Add(new OMP_BuildigError(new Exception("Переменная параллельного цикла должна быть определена в заголовке цикла"), new location(_for_node.source_context.begin_position.line_num, _for_node.source_context.begin_position.column_num, _for_node.source_context.end_position.line_num, _for_node.source_context.end_position.column_num, new document(_for_node.source_context.FileName))));
                    }
                    else //уже генерируем одну из веток
                        //если это параллельная ветка - последовательную генерировать не будем
                        if (CurrentParallelPosition == ParallelPosition.InsideParallel)
                        {
                            isGenerateParallel = true;
                            isGenerateSequential = false;
                        }
                        //else
                        //а если последовательная - то флаг isGenerateParallel не установлен, сгенерируется только последовательная
                }
            }
            #endregion
 

            location loc1 = get_location(_for_node.loop_variable);
            var_definition_node vdn = null;
            expression_node left, right, res;
            expression_node initv = convert_strong(_for_node.initial_value);
            expression_node tmp = initv;
            if (initv is typed_expression) initv = convert_typed_expression_to_function_call(initv as typed_expression);
            if (initv.type == null)
            	initv = tmp;
            statements_list head_stmts = new statements_list(loc1);
            convertion_data_and_alghoritms.statement_list_stack_push(head_stmts);
            if (_for_node.type_name == null && !_for_node.create_loop_variable)
            {
                definition_node dn = context.check_name_node_type(_for_node.loop_variable.name, loc1,
                    general_node_type.variable_node);
                vdn = (var_definition_node)dn;
                if (context.is_loop_variable(vdn))
                    AddError(get_location(_for_node.loop_variable), "CANNOT_ASSIGN_TO_LOOP_VARIABLE");
                if (!check_name_in_current_scope(_for_node.loop_variable.name))
                    AddError(new ForLoopControlMustBeSimpleLocalVariable(loc1));
            }
            else
            {
                //В разработке DS
                //throw new NotSupportedError(get_location(_for_node.type_name));
                type_node tn;
                if (_for_node.type_name != null)
                    tn = convert_strong(_for_node.type_name);
                else
                    tn = initv.type;
                //if (tn == SystemLibrary.SystemLibrary.void_type && _for_node.type_name != null)
                //	AddError(new VoidNotValid(get_location(_for_node.type_name)))
                if (_for_node.type_name != null)
                    check_for_type_allowed(tn,get_location(_for_node.type_name));
                vdn = context.add_var_definition(_for_node.loop_variable.name, get_location(_for_node.loop_variable), tn, SemanticTree.polymorphic_state.ps_common);
            }
            internal_interface ii = vdn.type.get_internal_interface(internal_interface_kind.ordinal_interface);
            if (ii == null)
            {
                AddError(new OrdinalTypeExpected(loc1));
            }
            ordinal_type_interface oti = (ordinal_type_interface)ii;


            location loc2 = get_location(_for_node.finish_value);
            var_definition_node vdn_finish = context.create_for_temp_variable(vdn.type, loc2);
            //Это должно стаять первее!
            left = create_variable_reference(vdn_finish, loc1);
            expression_node finishValue = convert_strong(_for_node.finish_value);
            right = finishValue;
            if (right is typed_expression) right = convert_typed_expression_to_function_call(right as typed_expression);
            res = find_operator(compiler_string_consts.assign_name, left, right, loc2);
            head_stmts.statements.AddElement(res);

            left = create_variable_reference(vdn, loc1);
            right = initv;
            res = find_operator(compiler_string_consts.assign_name, left, right, loc1);
            head_stmts.statements.AddElement(res);


            //for_node fn=new for_node(sl,;
            //fn.initialization_statement=sl;

            location loc3 = get_location(_for_node.initial_value);

            statement_node sn_inc = null;
            expression_node sn_while = null;
            expression_node sn_init_while = null;
            left = create_variable_reference(vdn, loc3);
            right = create_variable_reference(vdn, loc2);
            expression_node right_border = create_variable_reference(vdn_finish, loc2);
            switch (_for_node.cycle_type)
            {
                case SyntaxTree.for_cycle_type.to:
                    {
                        sn_inc = convertion_data_and_alghoritms.create_simple_function_call(oti.inc_method, loc1, left);
                        //if (vdn.type != SystemLibrary.SystemLibrary.bool_type)
                        sn_while = convertion_data_and_alghoritms.create_simple_function_call(oti.lower_method, loc2, right, right_border);
                        sn_init_while = convertion_data_and_alghoritms.create_simple_function_call(oti.lower_eq_method, loc2, right, right_border);
//                        else
//                        	sn_while = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibrary.bool_noteq, loc2, right, right_border);
                        break;
                    }
                case SyntaxTree.for_cycle_type.downto:
                    {
                        sn_inc = convertion_data_and_alghoritms.create_simple_function_call(oti.dec_method, loc1, left);
                        //if (vdn.type != SystemLibrary.SystemLibrary.bool_type)
                        sn_while = convertion_data_and_alghoritms.create_simple_function_call(oti.greater_method, loc2, right, right_border);
                        sn_init_while = convertion_data_and_alghoritms.create_simple_function_call(oti.greater_eq_method, loc2, right, right_border);
//                        else
//                        	sn_while = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibrary.bool_noteq, loc2, right, right_border);
                        break;
                    }
            }
            //fn.increment_statement=sn_inc;
            //fn.while_expr=sn_while;

            CheckToEmbeddedStatementCannotBeADeclaration(_for_node.statements);

            //DarkStar Modifed
            //исправил ошибку:  не работали break в циклах
            for_node fn = new for_node(null, sn_while, sn_init_while, sn_inc, null, get_location(_for_node));
            if (vdn.type == SystemLibrary.SystemLibrary.bool_type)
            	fn.bool_cycle = true;
            context.cycle_stack.push(fn);
            context.loop_var_stack.Push(vdn);
            statements_list slst = new statements_list(get_location(_for_node.statements));
            convertion_data_and_alghoritms.statement_list_stack_push(slst);

            context.enter_code_block_with_bind();
            fn.body = convert_strong(_for_node.statements);
            context.leave_code_block();

            slst = convertion_data_and_alghoritms.statement_list_stack.pop();
            if (slst.statements.Count > 0 || slst.local_variables.Count > 0)
            {
                slst.statements.AddElement(fn.body);
                fn.body = slst;
            }

            context.cycle_stack.pop();
            context.loop_var_stack.Pop();
            head_stmts = convertion_data_and_alghoritms.statement_list_stack.pop();
            head_stmts.statements.AddElement(fn);

            #region MikhailoMMX, обработка omp parallel for
            //флаг был установлен только если это самый внешний parallel for и нужно сгенерировать обе ветки
            //или если это вложенный parallel for, нужно сгенерировать обе ветки, но без проверки на OMP_Available
            //Последовательная ветка только что сгенерирована, теперь меняем состояние и генерируем параллельную
            if (isGenerateParallel)
            {
                CurrentParallelPosition = ParallelPosition.InsideParallel;
                statements_list stl = OpenMP.TryConvertFor(head_stmts, _for_node, fn, vdn, initv, finishValue, this);
                CurrentParallelPosition = ParallelPosition.Outside;
                if (stl != null)
                {
                    OpenMP.LoopVariables.Pop();
                    return_value(stl);
                    return;
                }
            }
            if (OpenMP.ForsFound)
            {
                OpenMP.LoopVariables.Pop();
            }
            #endregion

            return_value(head_stmts);
        }
        public override void visit(SyntaxTree.c_for_cycle node)
        {
            //throw new NotSupportedError(get_location(node));
            location loc1 = get_location(node.expr1);
            statements_list head_stmts = new statements_list(loc1);
            convertion_data_and_alghoritms.statement_list_stack_push(head_stmts);
            //statement_node sn_init = convert_weak((SyntaxTree.statement)node.expr1); // SSM 12/06/15 - всё равно c-узлы никому не нужны
            statement_node sn_init = convert_weak(node.expr1); // SSM 12/06/15
            expression_node sn_cond = convert_weak(node.expr2);
            //statement_node sn_next = convert_weak((SyntaxTree.statement)node.expr3); // SSM 12/06/15
            statement_node sn_next = convert_weak(node.expr3); // SSM 12/06/15

            CheckToEmbeddedStatementCannotBeADeclaration(node.stmt);

            for_node fn = new for_node(sn_init, sn_cond, null, sn_next, null, get_location(node));
            context.cycle_stack.push(fn);

            statements_list slst = new statements_list(get_location(node.stmt));
            convertion_data_and_alghoritms.statement_list_stack_push(slst);

            context.enter_code_block_with_bind();
            fn.body = convert_strong(node.stmt);
            context.leave_code_block();

            slst = convertion_data_and_alghoritms.statement_list_stack.pop();
            if (slst.statements.Count > 0 || slst.local_variables.Count > 0)
            {
                slst.statements.AddElement(fn.body);
                fn.body = slst;
            }

            context.cycle_stack.pop();

            head_stmts = convertion_data_and_alghoritms.statement_list_stack.pop();
            head_stmts.statements.AddElement(fn);
            return_value(head_stmts);

            /*slst = convertion_data_and_alghoritms.statement_list_stack.pop();
            if (slst.statements.Count > 0 || slst.local_variables.Count > 0)
            {
                slst.statements.AddElement(fn.body);
                fn.body = slst;
            }

            context.cycle_stack.pop();*/
            //ret.return_value(slst);
        }
예제 #5
0
 private void VisitFor(for_node stmt)
 {
     VisitStatement(stmt.initialization_statement);
     VisitStatement(stmt.increment_statement);
     VisitExpression(stmt.while_expr);
     VisitStatement(stmt.body);
 }
예제 #6
0
        public override void visit(PascalABCCompiler.SyntaxTree.for_node _for_node)
        {
            var loc1           = _visitor.get_location(_for_node.loop_variable);
            var loopIdentName  = _for_node.loop_variable.name.ToLower();
            var nodesToProcess = new List <syntax_tree_node>();

            var_definition_node vdn;
            var initv = _visitor.convert_strong(_for_node.initial_value);
            var tmp   = initv;

            if (initv is typed_expression)
            {
                initv = _visitor.convert_typed_expression_to_function_call(initv as typed_expression);
            }

            if (initv.type == null)
            {
                initv = tmp;
            }

            var headStmts = new statements_list(loc1);

            _visitor.convertion_data_and_alghoritms.statement_list_stack_push(headStmts);

            var newTreeNode = new CapturedVariablesTreeNodeForScope(_currentTreeNode, headStmts.Scope.ScopeNum, _for_node);

            if (_currentTreeNode != null)
            {
                _currentTreeNode.ChildNodes.Add(newTreeNode);
            }
            _currentTreeNode = newTreeNode;

            _scopesCapturedVarsNodesDictionary.Add(headStmts.Scope.ScopeNum, _currentTreeNode);


            if (_for_node.type_name == null && !_for_node.create_loop_variable)
            {
                var dn = _visitor.context.check_name_node_type(loopIdentName, loc1, general_node_type.variable_node);
                vdn = (var_definition_node)dn;
                nodesToProcess.Add(_for_node.loop_variable);
            }
            else
            {
                var tn = _for_node.type_name != null?_visitor.convert_strong(_for_node.type_name) : initv.type;

                vdn = _visitor.context.add_var_definition(loopIdentName,
                                                          _visitor.get_location(_for_node.loop_variable), tn,
                                                          polymorphic_state.ps_common);

                _currentTreeNode.VariablesDefinedInScope.Add(new CapturedVariablesTreeNode.CapturedSymbolInfo(_for_node, _visitor.context.find(loopIdentName)));
            }


            newTreeNode.SymbolInfoLoopVar = _visitor.context.find(loopIdentName);

            var fn = new PascalABCCompiler.TreeRealization.for_node(null, null, null, null, null, _visitor.get_location(_for_node));

            if (vdn.type == SystemLibrary.bool_type)
            {
                fn.bool_cycle = true;
            }
            _visitor.context.cycle_stack.push(fn);
            _visitor.context.loop_var_stack.Push(vdn);

            nodesToProcess.Add(_for_node.initial_value);
            nodesToProcess.Add(_for_node.finish_value);
            nodesToProcess.Add(_for_node.increment_value);

            foreach (var n in nodesToProcess)
            {
                ProcessNode(n);
            }

            if (!(_for_node.statements is statement_list))
            {
                var stmtList = new statement_list(_for_node.statements, _for_node.statements.source_context);
                _for_node.statements = stmtList;
            }
            ProcessNode(_for_node.statements);

            _visitor.context.cycle_stack.pop();
            _visitor.context.loop_var_stack.Pop();
            _visitor.convertion_data_and_alghoritms.statement_list_stack.pop();

            _currentTreeNode = _currentTreeNode.ParentNode;
        }
예제 #7
0
 /// <summary>
 /// Конструктор класса.
 /// </summary>
 /// <param name="fn"></param>
 /// <param name="loc">Расположение узла.</param>
 public for_continue_node(for_node fn, location loc) :
     base(null, loc)
 {
     _frnd = fn;
 }
예제 #8
0
 /// <summary>
 /// Конструктор класса.
 /// </summary>
 /// <param name="fn">Цикл for внутри которого расположен этот break.</param>
 /// <param name="loc">Расположение узла.</param>
 public for_break_node(for_node fn, location loc) :
     base(null, loc)
 {
     _frnd = fn;
 }
		private statement_node CreateFor()
		{
            statement_node init_stmt=null;
            if (CanReadObject())
                init_stmt = CreateStatement();
            expression_node while_expr = CreateExpression();
            expression_node init_while_expr = null;
            if (CanReadObject())
                init_while_expr = CreateExpression();
			for_node stmt = new for_node(init_stmt,while_expr,init_while_expr,CreateStatement(),CreateStatement(),null);
			stmt.bool_cycle = br.ReadBoolean();
			return stmt;
		}
        public override void visit(PascalABCCompiler.SyntaxTree.for_node _for_node)
        {
            var loc1 = _visitor.get_location(_for_node.loop_variable);
            var loopIdentName = _for_node.loop_variable.name.ToLower();
            var nodesToProcess = new List<syntax_tree_node>();

            var_definition_node vdn;
            var initv = _visitor.convert_strong(_for_node.initial_value);
            var tmp = initv;

            if (initv is typed_expression)
            {
                initv = _visitor.convert_typed_expression_to_function_call(initv as typed_expression);
            }

            if (initv.type == null)
            {
                initv = tmp;
            }

            var headStmts = new statements_list(loc1);
            _visitor.convertion_data_and_alghoritms.statement_list_stack_push(headStmts);

            var newTreeNode = new CapturedVariablesTreeNodeForScope(_currentTreeNode, headStmts.Scope.ScopeNum, _for_node);

            if (_currentTreeNode != null)
            {
                _currentTreeNode.ChildNodes.Add(newTreeNode);
            }
            _currentTreeNode = newTreeNode;

            _scopesCapturedVarsNodesDictionary.Add(headStmts.Scope.ScopeNum, _currentTreeNode);


            if (_for_node.type_name == null && !_for_node.create_loop_variable)
            {
                var dn = _visitor.context.check_name_node_type(loopIdentName, loc1, general_node_type.variable_node);
                vdn = (var_definition_node)dn;
                nodesToProcess.Add(_for_node.loop_variable);
            }
            else
            {
                var tn = _for_node.type_name != null ? _visitor.convert_strong(_for_node.type_name) : initv.type;
                vdn = _visitor.context.add_var_definition(loopIdentName,
                                                          _visitor.get_location(_for_node.loop_variable), tn,
                                                          polymorphic_state.ps_common);

                _currentTreeNode.VariablesDefinedInScope.Add(new CapturedVariablesTreeNode.CapturedSymbolInfo(_for_node, _visitor.context.find(loopIdentName)));
            }


            newTreeNode.SymbolInfoLoopVar = _visitor.context.find(loopIdentName);

            var fn = new PascalABCCompiler.TreeRealization.for_node(null, null, null, null, null, _visitor.get_location(_for_node));
            if (vdn.type == SystemLibrary.bool_type)
            {
                fn.bool_cycle = true;
            }
            _visitor.context.cycle_stack.push(fn);
            _visitor.context.loop_var_stack.Push(vdn);

            nodesToProcess.Add(_for_node.initial_value);
            nodesToProcess.Add(_for_node.finish_value);
            nodesToProcess.Add(_for_node.increment_value);

            foreach (var n in nodesToProcess)
            {
                ProcessNode(n);
            }

            if (!(_for_node.statements is statement_list))
            {
                var stmtList = new statement_list(_for_node.statements, _for_node.statements.source_context);
                _for_node.statements = stmtList;
            }
            ProcessNode(_for_node.statements);

            _visitor.context.cycle_stack.pop();
            _visitor.context.loop_var_stack.Pop();
            _visitor.convertion_data_and_alghoritms.statement_list_stack.pop();

            _currentTreeNode = _currentTreeNode.ParentNode;
        }
예제 #11
0
        //Проверки на доступность OMP и директиву проводятся перед вызовом.
        internal static statements_list TryConvertFor(statements_list for_head_stmts, SyntaxTree.for_node for_node, for_node fn, var_definition_node loop_variable, expression_node fromInclusive, expression_node toInclusive, syntax_tree_visitor syntax_tree_visitor)
        {
            try
            {
                location loc = fn.location;
                statements_list omp_stmts = new statements_list(loc);
                statements_list head_stmts = new statements_list(loc);

                syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_push(head_stmts);

                if (!InParallelSectionCreated)
                    CreateInParallelVariable(syntax_tree_visitor, out InParallelSection);
                //если omp доступен то (выполнять паралельно) иначе (выполнять for)
                if_node ifnode = CreateIfCondition(syntax_tree_visitor, omp_stmts, for_head_stmts, loc);
                head_stmts.statements.AddElement(ifnode);

                //генерим ветку в случае когда доступен omp
                if (!GenerateOMPParallelForCall(fn.body, for_node, loop_variable, omp_stmts, syntax_tree_visitor, fromInclusive, toInclusive))
                {
                    syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_pop();
                    return null;
                }

                syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_pop();

                return head_stmts;
            }
            catch (OpenMPException e)
            {
                Exception ex = new Exception(e.ToString());
                syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_pop();
                syntax_tree_visitor.WarningsList.Add(new OMP_BuildigError(ex, syntax_tree_visitor.get_location(new SyntaxTree.syntax_tree_node(e.SC))));
            }
            catch (Exception e)
            {
                syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_pop();
                syntax_tree_visitor.WarningsList.Add(new OMP_BuildigError(e, fn.location));
            }
            return null;
        }
예제 #12
0
        /// <summary>
        /// Конструктор класса.
        /// </summary>
        /// <param name="fn"></param>
        /// <param name="loc">Расположение узла.</param>
		public for_continue_node(for_node fn,location loc):
			base(null,loc)
		{
			_frnd=fn;
		}
예제 #13
0
        /// <summary>
        /// Конструктор класса.
        /// </summary>
        /// <param name="fn">Цикл for внутри которого расположен этот break.</param>
        /// <param name="loc">Расположение узла.</param>
		public for_break_node(for_node fn,location loc) :
			base(null,loc)
		{
			_frnd=fn;
		}