コード例 #1
0
        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);
            }
        }
コード例 #2
0
        public void lambda_body_visit(SyntaxTree.block _block)
        {
            //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();
            }

            context.enter_code_block_with_bind();
            statement_node sn = convert_strong(_block.program_code);
            context.leave_code_block();

            context.code = sn;
        }