コード例 #1
0
ファイル: Optimizer.cs プロジェクト: lisiynos/pascalabcnet
 private void VisitForeach(foreach_node stmt)
 {
 	IncreaseNumUseVar(stmt.ident);
 	VisitExpression(stmt.in_what);
     VisitStatement(stmt.what_do);
 }
コード例 #2
0
        public override void visit(SyntaxTree.foreach_stmt _foreach_stmt)
        {
            var lambdaSearcher = new LambdaSearcher(_foreach_stmt.in_what);
            if (lambdaSearcher.CheckIfContainsLambdas())
            {
                AddError(new LambdasNotAllowedInForeachInWhatSatetement(get_location(lambdaSearcher.FoundLambda)));
            }

            //throw new NotSupportedError(get_location(_foreach_stmt));
            definition_node dn = null;
            var_definition_node vdn = null;
            statements_list sl2 = new statements_list(get_location(_foreach_stmt));
            convertion_data_and_alghoritms.statement_list_stack_push(sl2);

            expression_node in_what = convert_strong(_foreach_stmt.in_what);
            expression_node tmp = in_what;
            if (in_what is typed_expression) in_what = convert_typed_expression_to_function_call(in_what as typed_expression);
            type_node elem_type = null;
            if (in_what.type == null)
                in_what = tmp;
            //if (in_what.type.find_in_type("GetEnumerator") == null)

            if (!FindIEnumerableElementType(_foreach_stmt, in_what.type, ref elem_type))
            //if (!IsGetEnumerator(in_what.type, ref elem_type))
                AddError(in_what.location, "CAN_NOT_EXECUTE_FOREACH_BY_EXPR_OF_TYPE_{0}", in_what.type.name);

            if (_foreach_stmt.type_name == null)
            {
                location loc1 = get_location(_foreach_stmt.identifier);
                dn = context.check_name_node_type(_foreach_stmt.identifier.name, loc1,
                    general_node_type.variable_node);
                vdn = (var_definition_node)dn;
                if (!check_name_in_current_scope(_foreach_stmt.identifier.name))
                    AddError(loc1, "FOREACH_LOOP_CONTROL_MUST_BE_SIMPLE_LOCAL_VARIABLE");
            }
            else
            {
                //AddError(new NotSupportedError(get_location(_foreach_stmt.type_name)));
                vdn = context.add_var_definition(_foreach_stmt.identifier.name, get_location(_foreach_stmt.identifier));

                type_node tn;
                if (_foreach_stmt.type_name is SyntaxTree.no_type_foreach)
                {
                    tn = elem_type;
                }
                else
                {
                    tn = convert_strong(_foreach_stmt.type_name);
                    //if (tn == SystemLibrary.SystemLibrary.void_type)
                    //	AddError(new VoidNotValid(get_location(_foreach_stmt.type_name)));
                    check_for_type_allowed(tn, get_location(_foreach_stmt.type_name));
                }

                context.close_var_definition_list(tn, null);
            }

            //elem_type = vdn.type;
            if (!(vdn.type is compiled_generic_instance_type_node))
                convertion_data_and_alghoritms.check_convert_type_with_inheritance(vdn.type, elem_type, get_location(_foreach_stmt.identifier));

            //if (!convertion_data_and_alghoritms.eq_type_nodes(elem_type, vdn.type))
                //AddError(new TypesOfVarAndElementsInForeachMustBeEqual(vdn.type.name,elem_type.name,get_location(_foreach_stmt.identifier)));
                //AddError(new SimpleSemanticError("Тип элемента контейнера: " + elem_type.ToString() + "  Тип переменной foreach: " + vdn.type.ToString(), get_location(_foreach_stmt.identifier)));

            //convertion_data_and_alghoritms.check_convert_type_with_inheritance(vdn.type, elem_type, get_location(_foreach_stmt.identifier));
            //if (in_what.type.type_special_kind == SemanticTree.type_special_kind.set_type)
            /*{
                if (!convertion_data_and_alghoritms.eq_type_nodes(elem_type, vdn.type))
                {
                    possible_type_convertions ptc = type_table.get_convertions(vdn.type,elem_type);
                    if (ptc.first == null || ptc.first.is_explicit)
                    	if (vdn.node_location_kind == SemanticTree.node_location_kind.in_namespace_location)
                            throw new CanNotConvertTypes(new namespace_variable_reference(vdn as namespace_variable, get_location(_foreach_stmt.identifier)), vdn.type, elem_type, get_location(_foreach_stmt.identifier));
                        	else if (vdn.node_location_kind == SemanticTree.node_location_kind.in_function_location) throw new CanNotConvertTypes(new local_variable_reference(vdn as local_variable, 0, get_location(_foreach_stmt.identifier)), vdn.type, elem_type, get_location(_foreach_stmt.identifier));
							else if (vdn.node_location_kind == SemanticTree.node_location_kind.in_block_location) throw new CanNotConvertTypes(new local_block_variable_reference(vdn as local_block_variable,get_location(_foreach_stmt.identifier)),vdn.type,elem_type, get_location(_foreach_stmt.identifier));
                        	else throw new ForeachLoopControlMustBeSimpleLocalVariable(get_location(_foreach_stmt.identifier));
                	
                }
            }*/
            statements_list sl = new statements_list(get_location(_foreach_stmt.stmt));
            convertion_data_and_alghoritms.statement_list_stack_push(sl);
            CheckToEmbeddedStatementCannotBeADeclaration(_foreach_stmt.stmt);
            foreach_node fn = new foreach_node(vdn, in_what, null, get_location(_foreach_stmt));
			context.cycle_stack.push(fn);
			context.loop_var_stack.Push(vdn);
            context.enter_code_block_with_bind();
            statement_node body = convert_strong(_foreach_stmt.stmt);
            context.leave_code_block();
            context.loop_var_stack.Pop();
            sl = convertion_data_and_alghoritms.statement_list_stack.pop();
            //if (!(st is statements_list))
            if (sl.statements.Count > 0 || sl.local_variables.Count > 0)
            {
                sl.statements.AddElement(body);
                body = sl;
            }
            //CheckToEmbeddedStatementCannotBeADeclaration(_foreach_stmt.stmt);
            //statement_node body = convert_strong(_foreach_stmt.stmt);
            //foreach_node fn = new foreach_node(vdn, in_what, body, get_location(_foreach_stmt));
            fn.what_do = body;
            //statements_list sl2 = new statements_list(get_location(_foreach_stmt));
            convertion_data_and_alghoritms.statement_list_stack.pop();
            sl2.statements.AddElement(fn);
            context.cycle_stack.pop();
            //if (_foreach_stmt.type_name != null)
            //sl2.local_variables.Add(vdn as local_block_variable);
            return_value(sl2);
        }
コード例 #3
0
 private void VisitForeach(foreach_node fn)
 {
     //VisitVariableDefinition(fn.ident);
     bw.Write(GetMemberOffset(fn.ident));
     VisitExpression(fn.in_what);
     VisitStatement(fn.what_do);
 }
コード例 #4
0
ファイル: statements.cs プロジェクト: shusha1311/pascalabcnet
 /// <summary>
 /// Конструктор класса.
 /// </summary>
 /// <param name="fn"></param>
 /// <param name="loc">Расположение узла.</param>
 public foreach_continue_node(foreach_node fn, location loc) :
     base(null, loc)
 {
     _frnd = fn;
 }
コード例 #5
0
        internal void add_clip_for_set(common_function_node cfn)
        {
        	statements_list sl = cfn.function_code as statements_list;
        	if (sl == null) return;
        	foreach (common_parameter prm in cfn.parameters)
        	{
        		if (prm.type.type_special_kind == SemanticTree.type_special_kind.set_type && prm.parameter_type == SemanticTree.parameter_type.value ||
        		   prm.is_params && prm.type.element_type.type_special_kind == SemanticTree.type_special_kind.set_type)
        		{
        			if (!prm.is_params)
        			{
        				ordinal_type_interface oti = prm.type.element_type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface;
        				if (oti == null)
        				if (prm.type.element_type.type_special_kind == SemanticTree.type_special_kind.short_string)
        				{
                            base_function_call cmc2 = null;
                            if (SystemLibrary.SystemLibInitializer.ClipShortStringInSetProcedure.sym_info is common_namespace_function_node)
                                cmc2 = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetProcedure.sym_info as common_namespace_function_node, null);
                            else
                                cmc2 = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetProcedure.sym_info as compiled_function_node, null);
        					cmc2.parameters.AddElement(new common_parameter_reference(prm,0,null));
        					cmc2.parameters.AddElement(new int_const_node((prm.type.element_type as short_string_type_node).Length,null));
        					sl.statements.AddElementFirst(cmc2);
        					continue;
        				}
        				else continue;
                        base_function_call cmc = null;
                        if (SystemLibrary.SystemLibInitializer.ClipProcedure.sym_info is common_namespace_function_node)
                            cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipProcedure.sym_info as common_namespace_function_node, null);
                        else
                            cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipProcedure.sym_info as compiled_function_node, null);
        				cmc.parameters.AddElement(new common_parameter_reference(prm,0,null));
        			
        				cmc.parameters.AddElement(oti.lower_value);
        				cmc.parameters.AddElement(oti.upper_value);
        				sl.statements.AddElementFirst(cmc);
        			}
        			else
        			{
        				var_definition_node var = context.create_for_temp_variable(prm.type.element_type,null);
        				expression_node in_what = new common_parameter_reference(prm,0,null);
        				statements_list what_do = new statements_list(null);
        				ordinal_type_interface oti = prm.type.element_type.element_type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface;
        				bool short_str = false;
        				if (oti == null)
        				if (prm.type.element_type.element_type.type_special_kind == SemanticTree.type_special_kind.short_string)
        				{
        					short_str = true;
        				}
        				else continue;
        				base_function_call cmc = null;
                        if (!short_str)
                        {
                            if (SystemLibrary.SystemLibInitializer.ClipProcedure.sym_info is common_namespace_function_node)
                                cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipProcedure.sym_info as common_namespace_function_node, null);
                            else
                                cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipProcedure.sym_info as compiled_function_node, null);
                        }
                        else
                        {
                            if (SystemLibrary.SystemLibInitializer.ClipShortStringInSetProcedure.sym_info is common_namespace_function_node)
                                cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetProcedure.sym_info as common_namespace_function_node, null);
                            else
                                cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetProcedure.sym_info as compiled_function_node, null);
                        }
                        if (var is local_block_variable)
        				    cmc.parameters.AddElement(new local_block_variable_reference(var as local_block_variable,null));
        				else
        				    cmc.parameters.AddElement(new local_variable_reference(var as local_variable,0,null));	
        				if (!short_str)
        				{
        					cmc.parameters.AddElement(oti.lower_value);
        					cmc.parameters.AddElement(oti.upper_value);
        				}
        				else
        				{
        					cmc.parameters.AddElement(new int_const_node((prm.type.element_type.element_type as short_string_type_node).Length,null));
        				}
        				what_do.statements.AddElement(cmc);
        				foreach_node fn = new foreach_node(var,in_what,what_do,null);
        				sl.statements.AddElementFirst(fn);
        			}
        		}
        		else if (prm.type.type_special_kind == SemanticTree.type_special_kind.short_string && prm.parameter_type == SemanticTree.parameter_type.value
        		        || prm.is_params && prm.type.element_type.type_special_kind == SemanticTree.type_special_kind.short_string)
        		{
                    if (!prm.is_params)
                    {
                        base_function_call cmc = null;
                        if (SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info is common_namespace_function_node)
                            cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as common_namespace_function_node, null);
                        else
                            cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as compiled_function_node, null);
                        cmc.parameters.AddElement(new common_parameter_reference(prm, 0, null));
                        cmc.parameters.AddElement(new int_const_node((prm.type as short_string_type_node).Length, null));
                        concrete_parameter_type tmp_cpt = prm.concrete_parameter_type;
                        prm.concrete_parameter_type = concrete_parameter_type.cpt_none;
                        sl.statements.AddElementFirst(find_operator(compiler_string_consts.assign_name, new common_parameter_reference(prm, 0, null), cmc, null));
                        prm.concrete_parameter_type = tmp_cpt;
                    }
                    else
                    {
                        common_parameter_reference cpr = new common_parameter_reference(prm, 0, null);
                        compiled_function_node get_func = (prm.type.find_in_type("Length").sym_info as compiled_property_node).get_function as compiled_function_node;
                        local_variable var = context.create_for_temp_variable(SystemLibrary.SystemLibrary.integer_type, null) as local_variable;
                        local_variable len_var = context.create_for_temp_variable(SystemLibrary.SystemLibrary.integer_type, null) as local_variable;
                        statements_list body = new statements_list(null);
                        //compiled_property_node item_prop = prm.type.find_in_type("Item").sym_info as compiled_property_node;
                        base_function_call cmc = null;
                        if (SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info is common_namespace_function_node)
                            cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as common_namespace_function_node, null);
                        else
                            cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as compiled_function_node, null);
                        expression_node cond = new basic_function_call(SystemLibrary.SystemLibrary.int_sm as basic_function_node, null, new local_variable_reference(var, 0, null), new local_variable_reference(len_var, 0, null));
                        //compiled_function_call get_item = new compiled_function_call(item_prop.get_function as compiled_function_node,cpr,null);
                        //get_item.parameters.AddElement(new local_variable_reference(var,0,null));
                        cmc.parameters.AddElement(new simple_array_indexing(cpr, new local_variable_reference(var, 0, null), prm.type.element_type, null));
                        cmc.parameters.AddElement(new int_const_node((prm.type.element_type as short_string_type_node).Length, null));

                        body.statements.AddElement(find_operator(compiler_string_consts.assign_name, new simple_array_indexing(cpr, new local_variable_reference(var, 0, null), prm.type.element_type, null), cmc, null));
                        body.statements.AddElement(new basic_function_call(SystemLibrary.SystemLibrary.int_assign as basic_function_node, null, new local_variable_reference(var, 0, null),
                                                                           new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node, null, new local_variable_reference(var, 0, null), new int_const_node(1, null))));


                        while_node wn = new while_node(cond, body, null);
                        sl.statements.AddElementFirst(wn);
                        sl.statements.AddElementFirst(new basic_function_call(SystemLibrary.SystemLibrary.int_assign as basic_function_node, null,
                                                                           new local_variable_reference(len_var, 0, null), new compiled_function_call(get_func, cpr, null)));
                    }	
        			
        		}
        	}
        }
コード例 #6
0
ファイル: statements.cs プロジェクト: shusha1311/pascalabcnet
 /// <summary>
 /// Конструктор класса.
 /// </summary>
 /// <param name="fn">Цикл for внутри которого расположен этот break.</param>
 /// <param name="loc">Расположение узла.</param>
 public foreach_break_node(foreach_node fn, location loc) :
     base(null, loc)
 {
     _frnd = fn;
 }
コード例 #7
0
        public override void visit(foreach_stmt _foreach_stmt)
        {
            var loopIdentName = _foreach_stmt.identifier.name.ToLower();

            definition_node dn = null;
            var_definition_node vdn = null;

            var sl2 = new statements_list(_visitor.get_location(_foreach_stmt));
            _visitor.convertion_data_and_alghoritms.statement_list_stack_push(sl2);

            var newTreeNode = new CapturedVariablesTreeNodeForEachScope(_currentTreeNode, sl2.Scope.ScopeNum, _foreach_stmt);

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

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

            var inWhat = _visitor.convert_strong(_foreach_stmt.in_what);
            var tmp = inWhat;
            if (inWhat is typed_expression)
                inWhat = _visitor.convert_typed_expression_to_function_call(inWhat as typed_expression);

            type_node elemType = null;
            if (inWhat.type == null)
                inWhat = tmp;

            _visitor.FindIEnumerableElementType(_foreach_stmt, inWhat.type, ref elemType);

            if (_foreach_stmt.type_name == null)
            {
                var loc1 = _visitor.get_location(_foreach_stmt.identifier);
                dn = _visitor.context.check_name_node_type(loopIdentName, loc1, general_node_type.variable_node);
                vdn = (var_definition_node)dn;
            }
            else
            {
                vdn = _visitor.context.add_var_definition(loopIdentName, _visitor.get_location(_foreach_stmt.identifier));

                type_node tn;
                if (_foreach_stmt.type_name is no_type_foreach)
                {
                    tn = elemType;
                }
                else
                {
                    tn = _visitor.convert_strong(_foreach_stmt.type_name);
                    _visitor.check_for_type_allowed(tn, _visitor.get_location(_foreach_stmt.type_name));
                }


                _visitor.context.close_var_definition_list(tn, null);

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

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

            if (!(vdn.type is compiled_generic_instance_type_node))
                _visitor.convertion_data_and_alghoritms.check_convert_type_with_inheritance(vdn.type, elemType, _visitor.get_location(_foreach_stmt.identifier));

            var fn = new foreach_node(vdn, inWhat, null, _visitor.get_location(_foreach_stmt));
            _visitor.context.cycle_stack.push(fn);
            _visitor.context.loop_var_stack.Push(vdn);

            ProcessNode(_foreach_stmt.in_what);

            if (!(_foreach_stmt.stmt is statement_list))
            {
                var stmtList = new statement_list(_foreach_stmt.stmt, _foreach_stmt.stmt.source_context);
                _foreach_stmt.stmt = stmtList;
            }

            ProcessNode(_foreach_stmt.stmt);

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

            _currentTreeNode = _currentTreeNode.ParentNode;
        }
コード例 #8
0
ファイル: statements.cs プロジェクト: lisiynos/pascalabcnet
        /// <summary>
        /// Конструктор класса.
        /// </summary>
        /// <param name="fn"></param>
        /// <param name="loc">Расположение узла.</param>
		public foreach_continue_node(foreach_node fn,location loc):
			base(null,loc)
		{
			_frnd=fn;
		}
コード例 #9
0
ファイル: statements.cs プロジェクト: lisiynos/pascalabcnet
        /// <summary>
        /// Конструктор класса.
        /// </summary>
        /// <param name="fn">Цикл for внутри которого расположен этот break.</param>
        /// <param name="loc">Расположение узла.</param>
		public foreach_break_node(foreach_node fn,location loc) :
			base(null,loc)
		{
			_frnd=fn;
		}
コード例 #10
0
        public override void visit(SyntaxTree.foreach_stmt _foreach_stmt)
        {
            var lambdaSearcher = new LambdaSearcher(_foreach_stmt.in_what);
            if (lambdaSearcher.CheckIfContainsLambdas())
            {
                AddError(new LambdasNotAllowedInForeachInWhatSatetement(get_location(lambdaSearcher.FoundLambda)));
            }

            expression_node in_what = convert_strong(_foreach_stmt.in_what);

            // SSM 29.07.16 - если in_what - одномерный массив, то заменить код foreach на for
            var is1dimdynarr = false;
            var comptn = in_what.type as compiled_type_node;
            if (comptn != null && comptn.type_special_kind == SemanticTree.type_special_kind.array_kind && comptn.rank == 1)
            {
                is1dimdynarr = true;
            }
            if (!is1dimdynarr)
            {
                var comtn = in_what.type as common_type_node;
                if (comtn != null && comtn.internal_type_special_kind == SemanticTree.type_special_kind.array_kind && comtn.rank == 1)
                {
                    is1dimdynarr = true;
                }
            }


            /* SSM 23.08.16 Закомментировал оптимизацию. Не работает с лямбдами. Лямбды обходят старое дерево. А заменить foreach на for на этом этапе пока не получается - не развита инфраструктура
             * 
             * if (is1dimdynarr) // Замена foreach на for для массива
            {
                // сгенерировать код для for и вызвать соответствующий visit
                var arrid = GenIdentName();
                var vdarr = new var_statement(arrid, new semantic_addr_value(in_what)); // semantic_addr_value - перевод в синтаксис для мгновенного вычисления семантического выражения, которое уже вычислено в in_what

                var i = GenIdentName();
                var x = _foreach_stmt.identifier;

                // Возможны 3 случая:
                // 1. _foreach_stmt.type_name = null - значит, переменная определена в другом месте
                // 2. _foreach_stmt.type_name = no_type_foreach - значит, это for var x in a
                // 3. _foreach_stmt.type_name = T - значит, это for var x: T in a

                statement vd;
                if (_foreach_stmt.type_name == null) // 1.
                    vd = new assign(x, arrid.indexer(i));
                else if (_foreach_stmt.type_name is no_type_foreach) // 2.
                    vd = new var_statement(x, arrid.indexer(i));
                else // 3.
                    vd = new var_statement(x,_foreach_stmt.type_name, arrid.indexer(i));

                // Превратить старое тело в statement_list и добавить к нему в начало x := a[i] или var x := a[i] 
                var newbody = _foreach_stmt.stmt.ToStatementList();
                newbody.AddFirst(vd);

                var high = arrid.dot_node("Length").Minus(1);

                var fornode = new SyntaxTree.for_node(i, 0, high, newbody, for_cycle_type.to, null, null, true);

                //var stl = new SyntaxTree.statement_list(vdarr, fornode);
                //Replace(_foreach_stmt, stl);

                visit(vdarr);
                visit(fornode);

                return;
            }*/
            /// SSM 29.07.16 

            //throw new NotSupportedError(get_location(_foreach_stmt));
            definition_node dn = null;
            var_definition_node vdn = null;
            statements_list sl2 = new statements_list(get_location(_foreach_stmt));
            convertion_data_and_alghoritms.statement_list_stack_push(sl2);

            expression_node tmp = in_what;
            if (in_what is typed_expression) in_what = convert_typed_expression_to_function_call(in_what as typed_expression);
            type_node elem_type = null;
            if (in_what.type == null)
                in_what = tmp;
            //if (in_what.type.find_in_type("GetEnumerator") == null)

            //(in_what.type as common_type_node).internal_type_special_kind == SemanticTree.type_special_kind.array_kind
            //in_what.type as compiled_type_node

            if (!FindIEnumerableElementType(/*_foreach_stmt, */in_what.type, ref elem_type))
            //if (!IsGetEnumerator(in_what.type, ref elem_type))
                AddError(in_what.location, "CAN_NOT_EXECUTE_FOREACH_BY_EXPR_OF_TYPE_{0}", in_what.type.name);

            if (_foreach_stmt.type_name == null)
            {
                location loc1 = get_location(_foreach_stmt.identifier);
                dn = context.check_name_node_type(_foreach_stmt.identifier.name, loc1,
                    general_node_type.variable_node);
                vdn = (var_definition_node)dn;
                if (!check_name_in_current_scope(_foreach_stmt.identifier.name))
                    AddError(loc1, "FOREACH_LOOP_CONTROL_MUST_BE_SIMPLE_LOCAL_VARIABLE");
            }
            else
            {
                //AddError(new NotSupportedError(get_location(_foreach_stmt.type_name)));
                vdn = context.add_var_definition(_foreach_stmt.identifier.name, get_location(_foreach_stmt.identifier));

                type_node tn;
                if (_foreach_stmt.type_name is SyntaxTree.no_type_foreach)
                {
                    tn = elem_type;
                }
                else
                {
                    tn = convert_strong(_foreach_stmt.type_name);
                    //if (tn == SystemLibrary.SystemLibrary.void_type)
                    //	AddError(new VoidNotValid(get_location(_foreach_stmt.type_name)));
                    check_for_type_allowed(tn, get_location(_foreach_stmt.type_name));
                }

                context.close_var_definition_list(tn, null);
            }

            //elem_type = vdn.type;
            if (!(vdn.type is compiled_generic_instance_type_node))
                convertion_data_and_alghoritms.check_convert_type_with_inheritance(vdn.type, elem_type, get_location(_foreach_stmt.identifier));

            //if (!convertion_data_and_alghoritms.eq_type_nodes(elem_type, vdn.type))
                //AddError(new TypesOfVarAndElementsInForeachMustBeEqual(vdn.type.name,elem_type.name,get_location(_foreach_stmt.identifier)));
                //AddError(new SimpleSemanticError("Тип элемента контейнера: " + elem_type.ToString() + "  Тип переменной foreach: " + vdn.type.ToString(), get_location(_foreach_stmt.identifier)));

            //convertion_data_and_alghoritms.check_convert_type_with_inheritance(vdn.type, elem_type, get_location(_foreach_stmt.identifier));
            //if (in_what.type.type_special_kind == SemanticTree.type_special_kind.set_type)
            /*{
                if (!convertion_data_and_alghoritms.eq_type_nodes(elem_type, vdn.type))
                {
                    possible_type_convertions ptc = type_table.get_convertions(vdn.type,elem_type);
                    if (ptc.first == null || ptc.first.is_explicit)
                    	if (vdn.node_location_kind == SemanticTree.node_location_kind.in_namespace_location)
                            throw new CanNotConvertTypes(new namespace_variable_reference(vdn as namespace_variable, get_location(_foreach_stmt.identifier)), vdn.type, elem_type, get_location(_foreach_stmt.identifier));
                        	else if (vdn.node_location_kind == SemanticTree.node_location_kind.in_function_location) throw new CanNotConvertTypes(new local_variable_reference(vdn as local_variable, 0, get_location(_foreach_stmt.identifier)), vdn.type, elem_type, get_location(_foreach_stmt.identifier));
							else if (vdn.node_location_kind == SemanticTree.node_location_kind.in_block_location) throw new CanNotConvertTypes(new local_block_variable_reference(vdn as local_block_variable,get_location(_foreach_stmt.identifier)),vdn.type,elem_type, get_location(_foreach_stmt.identifier));
                        	else throw new ForeachLoopControlMustBeSimpleLocalVariable(get_location(_foreach_stmt.identifier));
                	
                }
            }*/
            statements_list sl = new statements_list(get_location(_foreach_stmt.stmt));
            convertion_data_and_alghoritms.statement_list_stack_push(sl);
            CheckToEmbeddedStatementCannotBeADeclaration(_foreach_stmt.stmt);
            foreach_node fn = new foreach_node(vdn, in_what, null, get_location(_foreach_stmt));
			context.cycle_stack.push(fn);
			context.loop_var_stack.Push(vdn);
            context.enter_code_block_with_bind();
            statement_node body = convert_strong(_foreach_stmt.stmt);
            context.leave_code_block();
            context.loop_var_stack.Pop();
            sl = convertion_data_and_alghoritms.statement_list_stack.pop();
            //if (!(st is statements_list))
            if (sl.statements.Count > 0 || sl.local_variables.Count > 0)
            {
                sl.statements.AddElement(body);
                body = sl;
            }
            //CheckToEmbeddedStatementCannotBeADeclaration(_foreach_stmt.stmt);
            //statement_node body = convert_strong(_foreach_stmt.stmt);
            //foreach_node fn = new foreach_node(vdn, in_what, body, get_location(_foreach_stmt));
            fn.what_do = body;
            //statements_list sl2 = new statements_list(get_location(_foreach_stmt));
            convertion_data_and_alghoritms.statement_list_stack.pop();
            sl2.statements.AddElement(fn);
            context.cycle_stack.pop();
            //if (_foreach_stmt.type_name != null)
            //sl2.local_variables.Add(vdn as local_block_variable);
            return_value(sl2);
        }