public override void visit(SyntaxTree.class_members _class_members)
        {
            foreach (var def in _class_members.members.Where(d => d is const_definition ||
                                                            d is consts_definitions_list ||
                                                            d is variable_definitions ||
                                                            d is var_def_statement))
            {
                var lambdaSearcher = new LambdaSearcher(def);
                if (lambdaSearcher.CheckIfContainsLambdas())
                {
                    AddError(new LambdasNotAllowedInFieldsInitialization(get_location(lambdaSearcher.FoundLambda)));
                }
            }

            weak_node_test_and_visit(_class_members.access_mod);
            foreach (SyntaxTree.declaration sd in _class_members.members)
            {
                hard_node_test_and_visit(sd);
            }
        }
        public override void visit(SyntaxTree.interface_node _interface_node)
        {
            if (_interface_node.interface_definitions != null && _interface_node.interface_definitions.defs != null)
            {
                foreach (var def in _interface_node.interface_definitions.defs.Where(d => d is const_definition ||
                                                                                     d is consts_definitions_list ||
                                                                                     d is variable_definitions))
                {
                    var lambdaSearcher = new LambdaSearcher(def);
                    if (lambdaSearcher.CheckIfContainsLambdas())
                    {
                        AddError(new LambdasNotAllowedInInterfacePartOfModuleInInit(get_location(lambdaSearcher.FoundLambda)));
                    }
                }
            }

            weak_node_test_and_visit(_interface_node.interface_definitions);
        }
        public void visit_implementation(SyntaxTree.unit_module _unit_module)
        {
            if (_unit_module.initialization_part != null)
            {
                var lambdaSearcher = new LambdaSearcher(_unit_module.initialization_part);
                if (lambdaSearcher.CheckIfContainsLambdas())
                {
                    AddError(new LambdasNotAllowedInInitializationPartOfModule(get_location(lambdaSearcher.FoundLambda)));
                }
            }

            if (_unit_module.finalization_part != null)
            {
                var lambdaSearcher = new LambdaSearcher(_unit_module.finalization_part);
                if (lambdaSearcher.CheckIfContainsLambdas())
                {
                    AddError(new LambdasNotAllowedInFinalizationPartOfModule(get_location(lambdaSearcher.FoundLambda)));
                }
            }

            //using_list.AddRange(implementation_using_list);
            /*if (_unit_module.implementation_part != null)
            {
                weak_node_test_and_visit(_unit_module.implementation_part.using_namespaces);
            }*/

            SymbolTable.Scope[] used_units = build_referenced_units(referenced_units,false);            

            _compiled_unit.implementation_scope =
                convertion_data_and_alghoritms.symbol_table.CreateUnitImplementationScope(_compiled_unit.scope, used_units);

            location loc = null;
            if (_unit_module.unit_name != null)
            {
                loc = get_location(_unit_module.unit_name);
            }

            common_namespace_node cnsn = context.create_namespace(_unit_module.unit_name.idunit_name.name + compiler_string_consts.ImplementationSectionNamespaceName,
                _compiled_unit, _compiled_unit.implementation_scope, loc);

            //cnsn.scope=_compiled_unit.implementation_scope;

            if (_unit_module.implementation_part != null)
            {
                hard_node_test_and_visit(_unit_module.implementation_part);
            }

            //weak_node_test_and_visit(_unit_module.initialization_part);
            context.enter_code_block_without_bind();

            statement_node init_statements = convert_weak(_unit_module.initialization_part);
            context.leave_code_block();
            common_namespace_function_node initialization_function = null;
            if (init_statements != null)
            {
                context.check_labels(context.converted_namespace.labels);
                //(ssyy) Блокируем поставленные метки, чтобы не допустить переход из finalization-секции
                //context.block_defined_labels(context.converted_namespace.labels);
                initialization_function = new common_namespace_function_node(compiler_string_consts.initialization_function_name,
                    null, init_statements.location, context.converted_namespace, convertion_data_and_alghoritms.symbol_table.CreateScope(context.converted_namespace.scope));
                initialization_function.function_code = init_statements;
                cnsn.functions.AddElement(initialization_function);
                _compiled_unit.main_function = initialization_function;
                context.apply_special_local_vars(_compiled_unit.main_function);
            }

            context.enter_code_block_without_bind();
            statement_node final_statements = convert_weak(_unit_module.finalization_part);
            context.leave_code_block();
            common_namespace_function_node finalization_function = null;
            if (final_statements != null)
            {
                context.check_labels(context.converted_namespace.labels);
                finalization_function = new common_namespace_function_node(compiler_string_consts.finalization_function_name,
                    null, final_statements.location, context.converted_namespace, convertion_data_and_alghoritms.symbol_table.CreateScope(context.converted_namespace.scope));
                finalization_function.function_code = final_statements;
                cnsn.functions.AddElement(finalization_function);
                _compiled_unit.finalization_method = finalization_function;
                context.apply_special_local_vars(_compiled_unit.finalization_method);
            }

            context.check_all_name_unit_defined(_compiled_unit);
        }
        public override void visit(SyntaxTree.block _block)
        {
            if (context.converting_block() != block_type.namespace_block && _block.defs != null && _block.defs.defs != null)
            {
                foreach (var def in _block.defs.defs.Where(d => d is const_definition ||
                                                                d is consts_definitions_list ||
                                                                d is variable_definitions))
                {
                    var lambdaSearcher = new LambdaSearcher(def);
                    if (lambdaSearcher.CheckIfContainsLambdas())
                    {
                        AddError(new LambdasNotAllowedInDeclarationsSection(get_location(lambdaSearcher.FoundLambda)));     // SSM 6.06.15 - Хочется убрать это. В разделе описаний лямбды нужны - пусть и без замыканий. Если внутри подпрограммы - не нужны, но Вы же запретили везде!
                    }
                }
            }

            weak_node_test_and_visit(_block.defs);

            //ssyy добавил генерацию вызова конструктора предка без параметров
            if (context.converting_block() == block_type.function_block)
            {
                common_method_node cmn = context.top_function as common_method_node;
                if (cmn != null && cmn.is_constructor && !(cmn.polymorphic_state == SemanticTree.polymorphic_state.ps_static))
                {
                    context.allow_inherited_ctor_call = true;
                    if (_block.program_code != null && _block.program_code.subnodes != null)
                    {
                        //(ssyy) Для записей конструктор предка не вызываем.
                        bool should_ctor_add = context.converted_type.is_class;
                        if (should_ctor_add)
                        {
                            if (_block.program_code.subnodes.Count > 0)
                            {
                                SyntaxTree.procedure_call pc = _block.program_code.subnodes[0] as SyntaxTree.procedure_call;
                                if (pc != null || _block.program_code.subnodes[0] is SyntaxTree.inherited_message)
                                {
                                    //SyntaxTree.inherited_ident ii = pc.func_name as SyntaxTree.inherited_ident;
                                    //SyntaxTree.method_call mc = pc.func_name as SyntaxTree.method_call;
                                    //SyntaxTree.ident id = pc.func_name as SyntaxTree.ident;
                                    //if (/*ii != null*/id != null || mc != null /*&& mc.dereferencing_value is SyntaxTree.inherited_ident*/)
                                    {
                                        //(ssyy) Не уверен, что следующий оператор необходим.
                                        convertion_data_and_alghoritms.check_node_parser_error(_block.program_code);

                                        statement_node inh = convert_strong(_block.program_code.subnodes[0]);

                                        compiled_constructor_call c1 = inh as compiled_constructor_call;
                                        if (c1 != null && !c1._new_obj_awaited)
                                        {
                                            should_ctor_add = false;
                                        }
                                        else
                                        {
                                            common_constructor_call c2 = inh as common_constructor_call;
                                            if (c2 != null && !c2._new_obj_awaited)
                                            {
                                                should_ctor_add = false;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        if (should_ctor_add)
                        {
                            //Пытаемся добавить вызов .ctor() предка...
                            //Для начала проверим, есть ли у предка таковой.
                            bool not_found = true;
                            SymbolInfo sym = context.converted_type.base_type.find_in_type(compiler_string_consts.default_constructor_name, context.CurrentScope);
                            while (not_found && sym != null)
                            {
                                compiled_constructor_node ccn = sym.sym_info as compiled_constructor_node;
                                if (ccn != null && ccn.parameters.Count == 0)
                                {
                                    not_found = false;
                                }
                                else
                                {
                                    common_method_node cnode = sym.sym_info as common_method_node;
                                    if (cnode != null && cnode.is_constructor && (cnode.parameters.Count == 0 || cnode.parameters[0].default_value != null))
                                    {
                                        not_found = false;
                                    }
                                }
                                sym = sym.Next;
                            }
                            if (not_found)
                            {
                                //У предка нет конструктора по умолчанию
                                AddError(get_location(_block.program_code), "INHERITED_CONSTRUCTOR_CALL_EXPECTED");
                            }
                            else
                            {
                                //Генерируем вызов .ctor() предка
                                SyntaxTree.inherited_ident ii = new SyntaxTree.inherited_ident();
                                ii.name = compiler_string_consts.default_constructor_name;
                                _block.program_code.subnodes.Insert(0, new SyntaxTree.procedure_call(ii));
                                //context.allow_inherited_ctor_call = false;
                            }
                        }
                    }
                }
            }
            //\ssyy

            //ssyy
            if (context.converting_block() == block_type.namespace_block)
            {
                context.check_predefinition_defined();
            }

            if (lambdaProcessingState == LambdaProcessingState.None && _block.program_code != null)
            {
                var lambdaSearcher = new LambdaSearcher(_block.program_code);
                var lambdaIsFound = lambdaSearcher.CheckIfContainsLambdas();

                if ((context.converting_block() == block_type.function_block ||
                     context.converting_block() == block_type.namespace_block) &&
                    lambdaIsFound)
                    // TODO: Пока обрабатываются только блок функции и основной блок, необходимо обрабатывать случаи появлений лямбд в var_def_statement
                {
                    if (context.converting_block() == block_type.function_block)
                    {
                        if (context.func_stack.top().functions_nodes_list.Count > 0)
                        {
                            AddError(new LambdasNotAllowedWhenNestedSubprogrammesAreUsed(get_location(lambdaSearcher.FoundLambda)));
                        }
                    }

                    lambdaProcessingState = LambdaProcessingState.TypeInferencePhase;
                    visit_program_code(_block.program_code);

                    lambdaProcessingState = LambdaProcessingState.ClosuresProcessingPhase;
                    CapturedVariablesSubstitutionsManager.Substitute(this, _block.defs, _block.program_code);
                    
                    lambdaProcessingState = LambdaProcessingState.FinishPhase;

                    context.code = visit_program_code(_block.program_code);

                    lambdaProcessingState = LambdaProcessingState.None;
                }
                else
                {
                    context.code = visit_program_code(_block.program_code);
                }
            }
            else
            {
                context.code = visit_program_code(_block.program_code);
            }
        }
        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);
        }
Ejemplo n.º 6
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);
        }