コード例 #1
0
 private void VisitTypeOfOperator(typeof_operator node)
 {
     WriteTypeReference(node.oftype);
 }
コード例 #2
0
        internal void visit_method_call(SyntaxTree.method_call _method_call)
        {
            // frninja 01/03/16 - for iterator capturing (yield)
            if (_method_call.dereferencing_value is yield_unknown_ident)
            {
                var nodeToVisit = new method_call(ProcessUnknownIdent(_method_call.dereferencing_value as yield_unknown_ident), _method_call.parameters);
                visit(nodeToVisit);
                return;
            }
            // end frninja

            //lroman
            if (_method_call.dereferencing_value is closure_substituting_node)
            {
                var nodeToVisit =
                    new method_call(((closure_substituting_node) _method_call.dereferencing_value).substitution,
                                    _method_call.parameters);
                visit(nodeToVisit);
                return;
            }

            bool proc_wait = procedure_wait;
			bool lambdas_are_in_parameters = false; //lroman//

            var syntax_nodes_parameters = _method_call.parameters == null
                                              ? new List<expression>()
                                              : _method_call.parameters.expressions;
            if (procedure_wait)
            {
                procedure_wait = false;
            }
            //throw new ArgumentNullException("test");

            motivation mot = motivation_keeper.motivation;

            expression_node expr_node = null;
            expressions_list exprs = new expressions_list();

            SyntaxTree.ident id = null;

            SymbolInfo si = null;

            type_node to_type = null;

            SyntaxTree.addressed_value deref_value = _method_call.dereferencing_value;
            int templ_args_count = 0;
            //bool needs_generic_type_search = false;
            SyntaxTree.ident_with_templateparams iwt = deref_value as SyntaxTree.ident_with_templateparams;
            if (iwt != null)
            {
                deref_value = iwt.name;
                templ_args_count = iwt.template_params.params_list.Count;
                //needs_generic_type_search = _method_call.parameters.expressions.Count == 1;
            }

            SyntaxTree.inherited_ident inh_id = deref_value as SyntaxTree.inherited_ident;
            if (inh_id != null)
            {
                inherited_ident_processing = true;
                si = find_in_base(inh_id);
                if (si != null) 
            	if (si.sym_info is common_method_node)
            	{
            		if ((si.sym_info as common_method_node).polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract)
                        AddError(get_location(inh_id), "CANNOT_CALL_ABSTRACT_METHOD");
            	}
            	else
            	if (si.sym_info is compiled_function_node)
            	{
            		if ((si.sym_info as compiled_function_node).polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract)
                        AddError(get_location(inh_id), "CANNOT_CALL_ABSTRACT_METHOD");
            	}
                id = inh_id;
            }
            else
            {
                id = deref_value as SyntaxTree.ident;
                if (id != null)
                {
                    if (templ_args_count != 0)
                    {
                        //Ищем generics
                        si = context.find(id.name + compiler_string_consts.generic_params_infix + templ_args_count.ToString());
                        if (si != null)
                        {
                            si = new SymbolInfo(get_generic_instance(si, iwt.template_params.params_list));
                            iwt = null;
                        }
                    }
                    if (si == null)
                    {
                        SyntaxTree.operator_name_ident oni = id as SyntaxTree.operator_name_ident;
                        if (oni != null)
                        {
                            si = context.find(name_reflector.get_name(oni.operator_type));
                        }
                        else
                        {
                            si = context.find(id.name);
                            if (templ_args_count != 0)
                            {
                                SymbolInfo conv = ConvertTypeToInstance(si, iwt.template_params.params_list, get_location(id));
                                if (conv != null)
                                {
                                    si = conv;
                                    iwt = null;
                                }
                            }
                        }
                    }
                }
                else
                {
                    SyntaxTree.dot_node _dot_node = deref_value as SyntaxTree.dot_node;
                    if (_dot_node != null)
                    {
						bool skip_first_parameter = false; //lroman//
                        bool has_extension_overload = false;
                        semantic_node sn = convert_semantic_strong(_dot_node.left);

                        //SyntaxTree.ident id_right = ConvertOperatorNameToIdent(_dot_node.right as SyntaxTree.ident);
                        SyntaxTree.ident id_right = _dot_node.right as SyntaxTree.ident;
                        switch (sn.general_node_type)
                        {
                            case general_node_type.expression:
                                {
                                    expression_node exp = (expression_node)sn;
                                    if (exp is typed_expression)
                                        try_convert_typed_expression_to_function_call(ref exp);
                                    SyntaxTree.operator_name_ident oni_right = id_right as SyntaxTree.operator_name_ident;
                                    if (oni_right != null)
                                    {
                                        si = exp.type.find_in_type(name_reflector.get_name(oni_right.operator_type), context.CurrentScope);
                                    }
                                    else
                                    {
                                        si = exp.type.find_in_type(id_right.name, context.CurrentScope);
                                        if (si != null && si.sym_info != null && si.sym_info.semantic_node_type == semantic_node_type.wrap_def)
                                            BasePCUReader.RestoreSymbols(si, id_right.name);
                                    }

                                    
                                    //definition_node ddn=check_name_node_type(id_right.name,si,get_location(id_right),
                                    //	general_node_type.function_node,general_node_type.variable_node);

                                    location subloc = get_location(id_right);

                                    if (si == null)
                                    {
                                        AddError(new UndefinedNameReference(id_right.name, subloc));
                                    }

                                    if (si.sym_info.general_node_type != general_node_type.function_node)
                                    {
                                        if (si.sym_info.general_node_type == general_node_type.type_node)
                                        {
                                            to_type = ((type_node)(si.sym_info));
                                        }
                                        else
                                        {
                                            dot_node_as_expression_dot_ident(exp, id_right, motivation.expression_evaluation, _dot_node.left);
                                            exp = ret.get_expression();
                                            internal_interface ii = exp.type.get_internal_interface(internal_interface_kind.delegate_interface);
                                            if (ii == null)
                                            {
                                                AddError(subloc, "EXPECTED_DELEGATE");
                                            }
                                            delegate_internal_interface dii = ii as delegate_internal_interface;
                                            si = new SymbolInfo(dii.invoke_method);
                                        }
                                    }

                                    if (to_type != null)
                                    {
                                        if ((_method_call.parameters == null) || (_method_call.parameters.expressions.Count != 1))
                                        {
                                            AddError(get_location(_method_call), "ONLY_ONE_PARAMETER_OF_TYPE_CONVERSION_ALLOWED" );
                                        }
                                    }
                                    SymbolInfo tmp_si = si;
                                    while (si != null)
                                    {
                                        if (si.sym_info is common_namespace_function_node)
                                        {
                                            common_namespace_function_node cnfn = si.sym_info as common_namespace_function_node;
                                            if (cnfn.ConnectedToType != null && !cnfn.IsOperator)
                                            {
                                                exprs.AddElementFirst(exp);
                                                skip_first_parameter = true;
                                                break;
                                            }
                                        }
                                        if (si.sym_info is compiled_function_node)
                                        {
                                            compiled_function_node cfn = si.sym_info as compiled_function_node;
                                            if (cfn.ConnectedToType != null)
                                            {
                                                exprs.AddElementFirst(exp);
                                                skip_first_parameter = true;
                                                if (cfn.is_generic_function)
                                                {
                                                    //generic_convertions.DeduceFunction(cfn, exprs);
                                                    //si.sym_info = cfn.get_instance(new List<type_node>(new type_node[] { exp.type }), true, get_location(_method_call));
                                                }
                                                break;
                                            }

                                        }
                                        si = si.Next;
                                    }
                                    
                                    si = tmp_si;
                                    if (skip_first_parameter)
                                    {
                                        SymbolInfo new_si = null;
                                        bool has_obj_methods = false;
                                        List<SymbolInfo> si_list = new List<SymbolInfo>();
                                        while (si != null)
                                        {
                                            if (si.sym_info is common_namespace_function_node)
                                            {
                                                common_namespace_function_node cnfn = si.sym_info as common_namespace_function_node;
                                                if (cnfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static || cnfn.ConnectedToType != null)
                                                    si_list.Add(si);
                                                if (cnfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && cnfn.ConnectedToType == null)
                                                    has_obj_methods = true;
                                            }
                                            else if (si.sym_info is compiled_function_node)
                                            {
                                                compiled_function_node cfn = si.sym_info as compiled_function_node;
                                                if (cfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static || cfn.ConnectedToType != null)
                                                    si_list.Add(si);
                                                if (cfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && cfn.ConnectedToType == null)
                                                    has_obj_methods = true;
                                            }
                                            else if (si.sym_info is common_method_node)
                                            {
                                                common_method_node cfn = si.sym_info as common_method_node;
                                                if (cfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static)
                                                    si_list.Add(si);
                                                if (cfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static)
                                                    has_obj_methods = true;
                                            }
                                            si = si.Next;
                                        }
                                        for (int i = 0; i < si_list.Count; i++)
                                        {
                                            if (new_si == null)
                                            {
                                                new_si = si_list[i];
                                                si = new_si;
                                            }
                                            else
                                            {
                                                si.Next = si_list[i];
                                                si = si.Next;
                                            }
                                        }
                                        if (si != null)
                                            si.Next = null;
                                        si = new_si;
                                    }
                                    if (_method_call.parameters != null)
                                    {
                                    	foreach (SyntaxTree.expression en in _method_call.parameters.expressions)
                                        {
                                            #region Отмечаем флаг в лямбдах, говорящий о том, что в первый раз будем их "обходить" для вывода типов
                                            //lroman//
                                            if (en is SyntaxTree.function_lambda_definition)
                                            {
                                                lambdas_are_in_parameters = true;
                                                ((SyntaxTree.function_lambda_definition)en).lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing;
                                            }
                                            //lroman//
                                            #endregion
                                            var cen = convert_strong(en);
                                            exprs.AddElement(cen);
                                        }
                                    }

                                    expression_node subexpr1 = null;

                                    if (to_type != null)
                                    {
                                        subexpr1 = convertion_data_and_alghoritms.explicit_convert_type(exprs[0], to_type);
                                    }
                                    else
                                    {
                                        if (iwt != null)
                                        {
                                            si = get_generic_functions(si, true, subloc);
                                            si = get_function_instances(si, iwt.template_params.params_list, id_right.name, subloc, si.Next == null);
                                        }
										#region Если встретились лямбды в фактических параметрах, то выбираем нужную функцию из перегруженных, выводим типы, отмечаем флаг в лямбдах, говорящий о том, что мы их реально обходим
                                        //lroman//
                                        if (lambdas_are_in_parameters)
                                        {
                                            LambdaHelper.processingLambdaParametersForTypeInference++;
                                            // SSM 21.05.14 - попытка обработать перегруженные функции с параметрами-лямбдами с различными возвращаемыми значениями
                                            function_node_list spf = null;
                                            try
                                            {
                                                ThrowCompilationError = false;
                                                function_node ffn = convertion_data_and_alghoritms.select_function(exprs, si, subloc, syntax_nodes_parameters);
                                                if (ffn == null)
                                                {
                                                    if (skip_first_parameter)
                                                    {
                                                        expressions_list ex_list = new expressions_list();
                                                        ex_list.AddRange(exprs);
                                                        ex_list.remove_at(0);
                                                        ffn = convertion_data_and_alghoritms.select_function(ex_list, si, subloc, syntax_nodes_parameters);
                                                        if (ffn == null)
                                                        {
                                                            ThrowCompilationError = true;
                                                            throw LastError();
                                                        }
                                                        RemoveLastError();
                                                        skip_first_parameter = false;
                                                        exprs = ex_list;
                                                        ThrowCompilationError = true;
                                                    }
                                                    else
                                                    {
                                                        ThrowCompilationError = true;
                                                        throw LastError();
                                                    }
                                                        
                                                }
                                                ThrowCompilationError = true;
                                                int exprCounter = 0;
                                                if (skip_first_parameter)
                                                {
                                                    exprCounter++;
                                                }
                                                foreach (SyntaxTree.expression en in _method_call.parameters.expressions)
                                                {
                                                    if (!(en is SyntaxTree.function_lambda_definition))
                                                    {
                                                        exprCounter++;
                                                        continue;
                                                    }
                                                    else
                                                    {
                                                        var enLambda = (SyntaxTree.function_lambda_definition)en;
                                                        LambdaHelper.InferTypesFromVarStmt(ffn.parameters[exprCounter].type, enLambda, this);
                                                        enLambda.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing;
                                                        exprs[exprCounter] = convert_strong(en);
                                                        enLambda.lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing;
                                                        exprCounter++;
                                                    }
                                                }
                                            }
                                            catch (SeveralFunctionsCanBeCalled sf)
                                            {
                                                spf = sf.set_of_possible_functions; // Возможны несколько перегруженных версий - надо выводить дальше в надежде что какие-то уйдут и останется одна
                                            }

                                            Exception lastmultex = null;
                                            if (spf != null) // пытаемся инстанцировать одну за другой и ошибки гасим try
                                            {   // exprs - глобальная, поэтому надо копировать
                                                int spfnum = -1; // первый номер правильно инстанцированной. Если потом встретился второй, то тоже ошибка
                                                                 // SSM 4.08.15. Сейчас меняю эту логику. Если будет много кандидатов, но ровно один с совпадающим типом возвращаемого значения, то его и надо выбирать.
                                                                 // не забыть, что аналогичный код есть в create_constructor_call!!!!!!!
                                                int GoodVersionsCount = 0;
                                                int GoodVersionsCountWithSameResType = 0;
                                                for (int i = 0; i < spf.Count; i++) // цикл по версиям
                                                {
                                                    function_node fnn = spf[i];
                                                    try
                                                    {
                                                        int exprCounter = 0;
                                                        if (skip_first_parameter)
                                                        {
                                                            exprCounter++;
                                                        }

                                                        expressions_list exprs1 = new expressions_list();
                                                        exprs1.AddRange(exprs); // сделали копию

                                                        foreach (SyntaxTree.expression en in _method_call.parameters.expressions)
                                                        {
                                                            if (!(en is SyntaxTree.function_lambda_definition))
                                                            {
                                                                exprCounter++;
                                                                continue;
                                                            }
                                                            else
                                                            {
                                                                var fld = en as SyntaxTree.function_lambda_definition;

                                                                var lambdaName = fld.lambda_name;                           //lroman Сохранять имя необходимо
                                                                var fl = fld.lambda_visit_mode;

                                                                // запомнили типы параметров лямбды - SSM
                                                                object[] realparamstype = new object[fld.formal_parameters.params_list.Count]; // здесь хранятся выведенные типы лямбд или null если типы явно заданы
                                                                for (var k = 0; k < fld.formal_parameters.params_list.Count; k++)
                                                                {
                                                                    var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type;
                                                                    if (laminftypeK == null)
                                                                        realparamstype[k] = null;
                                                                    else realparamstype[k] = laminftypeK.real_type;
                                                                }

                                                                // запоминаем реальный тип возвращаемого значения если он не указан явно (это должен быть any_type или null если он указан явно) - он может измениться при следующем вызове, поэтому мы его восстановим
                                                                var restype = fld.return_type as SyntaxTree.lambda_inferred_type;
                                                                object realrestype = null;
                                                                if (restype != null)
                                                                    realrestype = restype.real_type;
                                                                LambdaHelper.InferTypesFromVarStmt(fnn.parameters[exprCounter].type, fld, this);
                                                                fld.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; //lroman
                                                                fld.lambda_name = LambdaHelper.GetAuxiliaryLambdaName(lambdaName); // поправляю имя. Думаю, назад возвращать не надо. ПРОВЕРИТЬ!

                                                                //contextChanger.SaveContextAndUpToNearestDefSect();
                                                                try
                                                                {
                                                                    exprs1[exprCounter] = convert_strong(en);

                                                                    type_node resexprtype = fld.RealSemTypeOfResExpr as type_node;
                                                                    type_node resformaltype = fld.RealSemTypeOfResult as type_node;
                                                                    var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность
                                                                    if (bbb)
                                                                    {
                                                                        GoodVersionsCountWithSameResType += 1;
                                                                        spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. 
                                                                    }

                                                                    /*compiled_type_node tt;
                                                                    tt = fnn.parameters[exprCounter].type as compiled_type_node;
                                                                    if (tt != null && tt.compiled_type.FullName.ToLower().StartsWith("system.func"))
                                                                    {
                                                                        resformaltype = tt.instance_params[tt.instance_params.Count - 1]; // Последний параметр в записи Func<T,T1,...TN> - тип возвращаемого значения
                                                                        var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность
                                                                        if (bbb)
                                                                        {
                                                                            GoodVersionsCountWithSameResType += 1;
                                                                            spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. 
                                                                        }
                                                                    }*/
                                                                }
                                                                catch
                                                                {
                                                                    throw;
                                                                }
                                                                finally
                                                                {
                                                                    LambdaHelper.RemoveLambdaInfoFromCompilationContext(context, en as function_lambda_definition);
                                                                    // восстанавливаем сохраненный тип возвращаемого значения
                                                                    if (restype != null)
                                                                        restype.real_type = realrestype;
                                                                    // восстанавливаем сохраненные типы параметров лямбды, которые не были заданы явно
                                                                    for (var k = 0; k < fld.formal_parameters.params_list.Count; k++)
                                                                    {
                                                                        var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type;
                                                                        if (laminftypeK != null)
                                                                            laminftypeK.real_type = realparamstype[k];
                                                                    }

                                                                    fld.lambda_name = lambdaName; //lroman Восстанавливаем имена
                                                                    fld.lambda_visit_mode = fl;
                                                                }

                                                                //contextChanger.RestoreCurrentContext();
                                                                exprCounter++;
                                                            }
                                                        }
                                                        /*if (spfnum >= 0) // два удачных инстанцирования - плохо. Может, одно - с более близким типом возвращаемого значения, тогда это плохо - надо доделать, но пока так
                                                        {
                                                            spfnum = -2;
                                                            break;
                                                        }*/

                                                        if (GoodVersionsCountWithSameResType == 0)
                                                            spfnum = i; // здесь запоминаем индекс только если нет подошедших, совпадающих по типу возвращаемого значения
                                                        GoodVersionsCount += 1;
                                                        for (int j = 0; j < exprs.Count; j++) // копируем назад если всё хорошо
                                                            exprs[j] = exprs1[j];
                                                    }
                                                    catch (Exception e)
                                                    {
                                                        // если сюда попали, значит, не вывели типы в лямбде и надо эту инстанцию пропускать
                                                        //contextChanger.RestoreCurrentContext();
                                                        lastmultex = e;
                                                    }
                                                } // конец цикла по версиям
                                                if (GoodVersionsCount > 1 && GoodVersionsCountWithSameResType != 1) // подошло много, но не было ровно одной с совпадающим типом возвращаемого значения
                                                    throw new SeveralFunctionsCanBeCalled(subloc, spf);
                                                if (GoodVersionsCount == 0) // было много, но ни одна не подошла из-за лямбд
                                                {
                                                    throw lastmultex;
                                                    //throw new NoFunctionWithSameArguments(subloc2, false);
                                                }

                                                int kk = 0;
                                                if (skip_first_parameter)
                                                    kk++;
                                                foreach (SyntaxTree.expression en in _method_call.parameters.expressions) //lroman окончательно подставить типы в лямбды
                                                {
                                                    if (!(en is SyntaxTree.function_lambda_definition))
                                                    {
                                                        kk++;
                                                        continue;
                                                    }
                                                    else
                                                    {
                                                        LambdaHelper.InferTypesFromVarStmt(spf[spfnum].parameters[kk].type, en as SyntaxTree.function_lambda_definition, this);
                                                        exprs[kk] = convert_strong(en);
                                                        kk++;
                                                    }
                                                }
                                            }
                                            // SSM 21.05.14 end
                                            LambdaHelper.processingLambdaParametersForTypeInference--;
                                        }
                                        //lroman//
                                        #endregion

                                        function_node fn = null;
                                        if (!skip_first_parameter || si.Next == null)
                                            fn = convertion_data_and_alghoritms.select_function(exprs, si, subloc, syntax_nodes_parameters);
                                        else
                                        {
                                            try
                                            {
                                                ThrowCompilationError = false;
                                                fn = convertion_data_and_alghoritms.select_function(exprs, si, subloc, syntax_nodes_parameters);
                                                if (fn == null && skip_first_parameter)
                                                {
                                                    if (si.Next == null)
                                                    {
                                                        ThrowCompilationError = true;
                                                        throw LastError();
                                                    }
                                                    RemoveLastError();
                                                    skip_first_parameter = false;
                                                    si = tmp_si;
                                                    exprs.remove_at(0);
                                                    fn = convertion_data_and_alghoritms.select_function(exprs, si, subloc, syntax_nodes_parameters);
                                                    if (fn == null)
                                                    {
                                                        ThrowCompilationError = true;
                                                        throw LastError();
                                                    }
//                                                    else
//                                                        RemoveLastError(); // ошибка уже убрана чуть выше
                                                }
                                            }
                                            catch (Exception ex)
                                            {
                                                ThrowCompilationError = true;
                                                if (skip_first_parameter)
                                                {
                                                    si = tmp_si;
                                                    exprs.remove_at(0);
                                                    fn = convertion_data_and_alghoritms.select_function(exprs, si, subloc, syntax_nodes_parameters);
                                                }
                                                else
                                                    throw ex;
                                            }
                                            ThrowCompilationError = true;
                                        }
                                        SemanticTree.IGenericInstance igi = fn as SemanticTree.IGenericInstance;
                                        if (igi != null)
                                        {
                                            //проверяем на соответствие ограничителям
                                            int num_err;
                                            //CompilationErrorWithLocation err = generic_parameter_eliminations.check_type_list(
                                        }
                                        base_function_call bfc = create_not_static_method_call(fn, exp, get_location(id_right), proc_wait);
                                        bfc.parameters.AddRange(exprs);
                                        subexpr1 = bfc;
                                    }

                                    switch (mot)
                                    {
                                        case motivation.expression_evaluation:
                                            {
                                                return_value(subexpr1);
                                                return;
                                            }
                                        case motivation.semantic_node_reciving:
                                            {
                                                return_semantic_value(subexpr1);
                                                return;
                                            }
                                        default:
                                            {
                                                AddError(subexpr1.location, "EXPRESSION_IS_NOT_ADDRESSED");
                                                return;
                                            }
                                    }

                                }
                            case general_node_type.namespace_node:
                                {
                                    namespace_node nsn = (namespace_node)sn;
                                    if (templ_args_count != 0)
                                    {
                                        //Ищем generics
                                        si = context.find(id_right.name + compiler_string_consts.generic_params_infix + templ_args_count.ToString());
                                        if (si != null)
                                        {
                                            si = new SymbolInfo(get_generic_instance(si, iwt.template_params.params_list));
                                            iwt = null;
                                        }
                                    }
                                    if (si == null)
                                    {
                                        SyntaxTree.operator_name_ident oni_right = id_right as SyntaxTree.operator_name_ident;
                                        if (oni_right != null)
                                        {
                                            si = nsn.find(name_reflector.get_name(oni_right.operator_type));
                                        }
                                        else
                                        {
                                            si = nsn.find(id_right.name);
                                            if (templ_args_count != 0)
                                            {
                                                SymbolInfo conv = ConvertTypeToInstance(si, iwt.template_params.params_list, get_location(id_right));
                                                if (conv != null)
                                                {
                                                    si = conv;
                                                    iwt = null;
                                                }
                                            }
                                        }
                                    }
                                    id = id_right;
                                    break;
                                }
                            case general_node_type.unit_node:
                                {
                                    unit_node un = (unit_node)sn;
                                    SyntaxTree.operator_name_ident oni_right = id_right as SyntaxTree.operator_name_ident;
                                    if (oni_right != null)
                                    {
                                        si = un.find_only_in_namespace(name_reflector.get_name(oni_right.operator_type));
                                    }
                                    else
                                    {
                                        si = un.find_only_in_namespace(id_right.name);
                                    }
                                    id = id_right;
                                    break;
                                }
                            case general_node_type.type_node:
                                {
                                    type_node tn = (type_node)sn;
                                    /*if (tn == SystemLibrary.SystemLibrary.void_type)
                                    {
                                        throw new VoidNotValid(get_location(id_right));
                                    }*/
                                    check_for_type_allowed(tn,get_location(id_right));
                                    SyntaxTree.operator_name_ident oni_right = id_right as SyntaxTree.operator_name_ident;
                                    if (oni_right != null)
                                    {
                                        si = tn.find_in_type(name_reflector.get_name(oni_right.operator_type), context.CurrentScope);
                                    }
                                    else
                                    {
                                        si = tn.find_in_type(id_right.name, context.CurrentScope);//CurrentScope
                                        delete_inherited_constructors(ref si, tn);
                                        delete_extension_methods(ref si, tn); // SSM 2.2.2016 Пока временно закомментировал - в старом коде этого не было. Из-за этого не работает System.Linq.Enumerable.Select
                                    }

                                    //definition_node ddn2=check_name_node_type(id_right.name,si,get_location(id_right),
                                    //    general_node_type.function_node);

                                    expression_node exp = null;
                                    location subloc = get_location(id_right);

                                    if (si == null)
                                    {
                                        AddError( new UndefinedNameReference(id_right.name, subloc));
                                    }

                                    if (si.sym_info.general_node_type != general_node_type.function_node)
                                    {
                                        if (si.sym_info.general_node_type == general_node_type.type_node)
                                        {
                                            to_type = ((type_node)(si.sym_info));
                                        }
                                        else
                                        {
                                            dot_node_as_type_ident(tn, id_right, motivation.expression_evaluation);
                                            exp = ret.get_expression();
                                            internal_interface ii = exp.type.get_internal_interface(internal_interface_kind.delegate_interface);
                                            if (ii == null)
                                            {
                                                AddError(subloc, "EXPECTED_DELEGATE");
                                            }
                                            delegate_internal_interface dii = ii as delegate_internal_interface;
                                            si = new SymbolInfo(dii.invoke_method);
                                        }
                                    }

                                    if (to_type != null)
                                    {
                                        if ((_method_call.parameters == null) || (_method_call.parameters.expressions.Count != 1))
                                        {
                                            AddError(get_location(_method_call), "ONLY_ONE_PARAMETER_OF_TYPE_CONVERSION_ALLOWED" );
                                        }
                                    }

                                    if (_method_call.parameters != null)
                                    {
                                        foreach (SyntaxTree.expression en in _method_call.parameters.expressions)
                                        {
                                            #region Отмечаем флаг в лямбдах, говорящий о том, что в первый раз будем их "обходить" для вывода типов
                                            //lroman//
                                            if (en is SyntaxTree.function_lambda_definition)
                                            {
                                                lambdas_are_in_parameters = true;
                                                ((SyntaxTree.function_lambda_definition)en).lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing;
                                            }
                                            //lroman//
                                            #endregion
                                            exprs.AddElement(convert_strong(en));
                                        }
                                    }

                                    expression_node subexpr2 = null;

                                    if (to_type != null)
                                    {
                                        subexpr2 = convertion_data_and_alghoritms.explicit_convert_type(exprs[0], to_type);
                                    }
                                    else
                                    {
                                        if (iwt != null)
                                        {
                                            si = get_generic_functions(si, true, subloc);
                                            si = get_function_instances(si, iwt.template_params.params_list, id_right.name, subloc, si.Next == null);
                                        }
                                        #region Если встретились лямбды в фактических параметрах, то выбираем нужную функцию из перегруженных, выводим типы, отмечаем флаг в лямбдах, говорящий о том, что мы их реально обходим
                                        //lroman//
                                        if (lambdas_are_in_parameters)
                                        {
                                            LambdaHelper.processingLambdaParametersForTypeInference++;
                                            // SSM 21.05.14 - попытка обработать перегруженные функции с параметрами-лямбдами с различными возвращаемыми значениями
                                            function_node_list spf = null;
                                            try
                                            {
                                                function_node ffn = convertion_data_and_alghoritms.select_function(exprs, si, subloc, syntax_nodes_parameters);
                                                int exprCounter = 0;
                                                if (skip_first_parameter)
                                                {
                                                    exprCounter++;
                                                }
                                                foreach (SyntaxTree.expression en in _method_call.parameters.expressions)
                                                {
                                                    if (!(en is SyntaxTree.function_lambda_definition))
                                                    {
                                                        exprCounter++;
                                                        continue;
                                                    }
                                                    else
                                                    {
                                                        var enLambda = (SyntaxTree.function_lambda_definition)en;
                                                        LambdaHelper.InferTypesFromVarStmt(ffn.parameters[exprCounter].type, enLambda, this);
                                                        enLambda.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing;
                                                        exprs[exprCounter] = convert_strong(en);
                                                        enLambda.lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing;
                                                        exprCounter++;
                                                    }
                                                }
                                            }
                                            catch (SeveralFunctionsCanBeCalled sf)
                                            {
                                                spf = sf.set_of_possible_functions; // Возможны несколько перегруженных версий - надо выводить дальше в надежде что какие-то уйдут и останется одна
                                            }

                                            Exception lastmultex = null;
                                            if (spf != null) // пытаемся инстанцировать одну за другой и ошибки гасим try
                                            {   // exprs - глобальная, поэтому надо копировать
                                                int spfnum = -1; // первый номер правильно инстанцированной. Если потом встретился второй, то тоже ошибка
                                                                 // SSM 4.08.15. Сейчас меняю эту логику. Если будет много кандидатов, но ровно один с совпадающим типом возвращаемого значения, то его и надо выбирать.
                                                                 // не забыть, что аналогичный код есть в create_constructor_call!!!!!!!
                                                int GoodVersionsCount = 0;
                                                int GoodVersionsCountWithSameResType = 0;
                                                for (int i = 0; i < spf.Count; i++) // цикл по версиям
                                                {
                                                    function_node fnn = spf[i];
                                                    try
                                                    {
                                                        int exprCounter = 0;
                                                        if (skip_first_parameter)
                                                        {
                                                            exprCounter++;
                                                        }

                                                        expressions_list exprs1 = new expressions_list();
                                                        exprs1.AddRange(exprs); // сделали копию

                                                        foreach (SyntaxTree.expression en in _method_call.parameters.expressions)
                                                        {
                                                            if (!(en is SyntaxTree.function_lambda_definition))
                                                            {
                                                                exprCounter++;
                                                                continue;
                                                            }
                                                            else
                                                            {
                                                                var fld = en as SyntaxTree.function_lambda_definition;

                                                                var lambdaName = fld.lambda_name;                           //lroman Сохранять имя необходимо
                                                                var fl = fld.lambda_visit_mode;

                                                                // запомнили типы параметров лямбды - SSM
                                                                object[] realparamstype = new object[fld.formal_parameters.params_list.Count]; // здесь хранятся выведенные типы лямбд или null если типы явно заданы
                                                                for (var k = 0; k < fld.formal_parameters.params_list.Count; k++)
                                                                {
                                                                    var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type;
                                                                    if (laminftypeK == null)
                                                                        realparamstype[k] = null;
                                                                    else realparamstype[k] = laminftypeK.real_type;
                                                                }

                                                                // запоминаем реальный тип возвращаемого значения если он не указан явно (это должен быть any_type или null если он указан явно) - он может измениться при следующем вызове, поэтому мы его восстановим
                                                                var restype = fld.return_type as SyntaxTree.lambda_inferred_type;
                                                                object realrestype = null;
                                                                if (restype != null)
                                                                    realrestype = restype.real_type;
                                                                LambdaHelper.InferTypesFromVarStmt(fnn.parameters[exprCounter].type, fld, this);
                                                                fld.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; //lroman
                                                                fld.lambda_name = LambdaHelper.GetAuxiliaryLambdaName(lambdaName); // поправляю имя. Думаю, назад возвращать не надо. ПРОВЕРИТЬ!

                                                                //contextChanger.SaveContextAndUpToNearestDefSect();
                                                                try
                                                                {
                                                                    exprs1[exprCounter] = convert_strong(en);

                                                                    type_node resexprtype = fld.RealSemTypeOfResExpr as type_node;
                                                                    type_node resformaltype = fld.RealSemTypeOfResult as type_node;
                                                                    var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность
                                                                    if (bbb)
                                                                    {
                                                                        GoodVersionsCountWithSameResType += 1;
                                                                        spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. 
                                                                    }

                                                                    /*compiled_type_node tt;
                                                                    tt = fnn.parameters[exprCounter].type as compiled_type_node;
                                                                    if (tt != null && tt.compiled_type.FullName.ToLower().StartsWith("system.func"))
                                                                    {
                                                                        resformaltype = tt.instance_params[tt.instance_params.Count - 1]; // Последний параметр в записи Func<T,T1,...TN> - тип возвращаемого значения
                                                                        var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность
                                                                        if (bbb)
                                                                        {
                                                                            GoodVersionsCountWithSameResType += 1;
                                                                            spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. 
                                                                        }
                                                                    }*/
                                                                }
                                                                catch
                                                                {
                                                                    throw;
                                                                }
                                                                finally
                                                                {
                                                                    LambdaHelper.RemoveLambdaInfoFromCompilationContext(context, en as function_lambda_definition);
                                                                    // восстанавливаем сохраненный тип возвращаемого значения
                                                                    if (restype != null)
                                                                        restype.real_type = realrestype;
                                                                    // восстанавливаем сохраненные типы параметров лямбды, которые не были заданы явно
                                                                    for (var k = 0; k < fld.formal_parameters.params_list.Count; k++)
                                                                    {
                                                                        var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type;
                                                                        if (laminftypeK != null)
                                                                            laminftypeK.real_type = realparamstype[k];
                                                                    }

                                                                    fld.lambda_name = lambdaName; //lroman Восстанавливаем имена
                                                                    fld.lambda_visit_mode = fl;
                                                                }

                                                                //contextChanger.RestoreCurrentContext();
                                                                exprCounter++;
                                                            }
                                                        }
                                                        /*if (spfnum >= 0) // два удачных инстанцирования - плохо. Может, одно - с более близким типом возвращаемого значения, тогда это плохо - надо доделать, но пока так
                                                        {
                                                            spfnum = -2;
                                                            break;
                                                        }*/

                                                        if (GoodVersionsCountWithSameResType == 0)
                                                            spfnum = i; // здесь запоминаем индекс только если нет подошедших, совпадающих по типу возвращаемого значения
                                                        GoodVersionsCount += 1;
                                                        for (int j = 0; j < exprs.Count; j++) // копируем назад если всё хорошо
                                                            exprs[j] = exprs1[j];
                                                    }
                                                    catch (Exception e)
                                                    {
                                                        // если сюда попали, значит, не вывели типы в лямбде и надо эту инстанцию пропускать
                                                        //contextChanger.RestoreCurrentContext();
                                                        lastmultex = e;
                                                    }
                                                } // конец цикла по версиям
                                                if (GoodVersionsCount > 1 && GoodVersionsCountWithSameResType != 1) // подошло много, но не было ровно одной с совпадающим типом возвращаемого значения
                                                    throw new SeveralFunctionsCanBeCalled(subloc, spf);
                                                if (GoodVersionsCount == 0) // было много, но ни одна не подошла из-за лямбд
                                                {
                                                    throw lastmultex;
                                                    //throw new NoFunctionWithSameArguments(subloc2, false);
                                                }

                                                int kk = 0;
                                                if (skip_first_parameter)
                                                    kk++;
                                                foreach (SyntaxTree.expression en in _method_call.parameters.expressions) //lroman окончательно подставить типы в лямбды
                                                {
                                                    if (!(en is SyntaxTree.function_lambda_definition))
                                                    {
                                                        kk++;
                                                        continue;
                                                    }
                                                    else
                                                    {
                                                        LambdaHelper.InferTypesFromVarStmt(spf[spfnum].parameters[kk].type, en as SyntaxTree.function_lambda_definition, this);
                                                        exprs[kk] = convert_strong(en);
                                                        kk++;
                                                    }
                                                }
                                            }
                                            // SSM 21.05.14 end
                                            LambdaHelper.processingLambdaParametersForTypeInference--;
                                        }
                                        //lroman//
                                        #endregion

                                        function_node fn = convertion_data_and_alghoritms.select_function(exprs, si, subloc, syntax_nodes_parameters);
                                        if (!debug && fn == SystemLibrary.SystemLibrary.assert_method)
                                        {
//                                        	return_value(new empty_statement(null));
//                                        	return;
                                        }
                                        /*if ((proc_wait==false)&&(fn.return_value_type==null))
                                        {
                                            throw new FunctionExpectedProcedureMeet(fn,get_location(id_right));
                                        }*/

                                        base_function_call bfc2 = null;
                                        if (exp == null)
                                        {
                                            bfc2 = create_static_method_call(fn, subloc, tn, proc_wait);
                                        }
                                        else
                                        {
                                            bfc2 = create_not_static_method_call(fn, exp, subloc, proc_wait);
                                        }
                                        bfc2.parameters.AddRange(exprs);
                                        subexpr2 = bfc2;
                                    }

                                    switch (mot)
                                    {
                                        case motivation.expression_evaluation:
                                            {
                                                return_value(subexpr2);
                                                return;
                                            }
                                        case motivation.semantic_node_reciving:
                                            {
                                                return_semantic_value(subexpr2);
                                                return;
                                            }
                                        default:
                                            {
                                                AddError(subexpr2.location, "EXPRESSION_IS_NOT_ADDRESSED");
                                                return;
                                            }
                                    }
                                }
                        }
                    }
                    else
                    {
                        SyntaxTree.expression expr = deref_value as SyntaxTree.expression;
                        if (expr != null)
                        {
                            //throw new CompilerInternalError("Not supported");
                            expression_node exp_int = convert_strong(expr);
                            location sloc = get_location(expr);
                            internal_interface ii = exp_int.type.get_internal_interface(internal_interface_kind.delegate_interface);
                            if (ii == null)
                            {
                                AddError(sloc, "EXPECTED_DELEGATE");
                            }
                            delegate_internal_interface dii = (delegate_internal_interface)ii;
                            si = new SymbolInfo(dii.invoke_method);

                            if (_method_call.parameters != null)
                            {
                                foreach (SyntaxTree.expression en in _method_call.parameters.expressions)
                                {
                                    #region Отмечаем флаг в лямбдах, говорящий о том, что в первый раз будем их "обходить" для вывода типов
                                    //lroman//
                                    if (en is SyntaxTree.function_lambda_definition)
                                    {
                                        lambdas_are_in_parameters = true;
                                        ((SyntaxTree.function_lambda_definition)en).lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing;
                                    }
                                    //lroman//
                                    #endregion
                                    exprs.AddElement(convert_strong(en));
                                }
                            }
                            location subloc = sloc;
                            #region Если встретились лямбды в фактических параметрах, то выбираем нужную функцию из перегруженных, выводим типы, отмечаем флаг в лямбдах, говорящий о том, что мы их реально обходим
                            //lroman//
                            if (lambdas_are_in_parameters)
                            {
                                LambdaHelper.processingLambdaParametersForTypeInference++;
                                // SSM 21.05.14 - попытка обработать перегруженные функции с параметрами-лямбдами с различными возвращаемыми значениями
                                function_node_list spf = null;
                                try
                                {
                                    function_node ffn = convertion_data_and_alghoritms.select_function(exprs, si, subloc, syntax_nodes_parameters);
                                    int exprCounter = 0;
                                    
                                    foreach (SyntaxTree.expression en in _method_call.parameters.expressions)
                                    {
                                        if (!(en is SyntaxTree.function_lambda_definition))
                                        {
                                            exprCounter++;
                                            continue;
                                        }
                                        else
                                        {
                                            var enLambda = (SyntaxTree.function_lambda_definition)en;
                                            LambdaHelper.InferTypesFromVarStmt(ffn.parameters[exprCounter].type, enLambda, this);
                                            enLambda.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing;
                                            exprs[exprCounter] = convert_strong(en);
                                            enLambda.lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing;
                                            exprCounter++;
                                        }
                                    }
                                }
                                catch (SeveralFunctionsCanBeCalled sf)
                                {
                                    spf = sf.set_of_possible_functions; // Возможны несколько перегруженных версий - надо выводить дальше в надежде что какие-то уйдут и останется одна
                                }

                                Exception lastmultex = null;
                                if (spf != null) // пытаемся инстанцировать одну за другой и ошибки гасим try
                                {   // exprs - глобальная, поэтому надо копировать
                                    int spfnum = -1; // первый номер правильно инстанцированной. Если потом встретился второй, то тоже ошибка
                                                     // SSM 4.08.15. Сейчас меняю эту логику. Если будет много кандидатов, но ровно один с совпадающим типом возвращаемого значения, то его и надо выбирать.
                                                     // не забыть, что аналогичный код есть в create_constructor_call!!!!!!!
                                    int GoodVersionsCount = 0;
                                    int GoodVersionsCountWithSameResType = 0;
                                    for (int i = 0; i < spf.Count; i++) // цикл по версиям
                                    {
                                        function_node fnn = spf[i];
                                        try
                                        {
                                            int exprCounter = 0;
                                            

                                            expressions_list exprs1 = new expressions_list();
                                            exprs1.AddRange(exprs); // сделали копию

                                            foreach (SyntaxTree.expression en in _method_call.parameters.expressions)
                                            {
                                                if (!(en is SyntaxTree.function_lambda_definition))
                                                {
                                                    exprCounter++;
                                                    continue;
                                                }
                                                else
                                                {
                                                    var fld = en as SyntaxTree.function_lambda_definition;

                                                    var lambdaName = fld.lambda_name;                           //lroman Сохранять имя необходимо
                                                    var fl = fld.lambda_visit_mode;

                                                    // запомнили типы параметров лямбды - SSM
                                                    object[] realparamstype = new object[fld.formal_parameters.params_list.Count]; // здесь хранятся выведенные типы лямбд или null если типы явно заданы
                                                    for (var k = 0; k < fld.formal_parameters.params_list.Count; k++)
                                                    {
                                                        var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type;
                                                        if (laminftypeK == null)
                                                            realparamstype[k] = null;
                                                        else realparamstype[k] = laminftypeK.real_type;
                                                    }

                                                    // запоминаем реальный тип возвращаемого значения если он не указан явно (это должен быть any_type или null если он указан явно) - он может измениться при следующем вызове, поэтому мы его восстановим
                                                    var restype = fld.return_type as SyntaxTree.lambda_inferred_type;
                                                    object realrestype = null;
                                                    if (restype != null)
                                                        realrestype = restype.real_type;
                                                    LambdaHelper.InferTypesFromVarStmt(fnn.parameters[exprCounter].type, fld, this);
                                                    fld.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; //lroman
                                                    fld.lambda_name = LambdaHelper.GetAuxiliaryLambdaName(lambdaName); // поправляю имя. Думаю, назад возвращать не надо. ПРОВЕРИТЬ!

                                                    //contextChanger.SaveContextAndUpToNearestDefSect();
                                                    try
                                                    {
                                                        exprs1[exprCounter] = convert_strong(en);

                                                        type_node resexprtype = fld.RealSemTypeOfResExpr as type_node;
                                                        type_node resformaltype = fld.RealSemTypeOfResult as type_node;
                                                        var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность
                                                        if (bbb)
                                                        {
                                                            GoodVersionsCountWithSameResType += 1;
                                                            spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. 
                                                        }

                                                        /*compiled_type_node tt;
                                                        tt = fnn.parameters[exprCounter].type as compiled_type_node;
                                                        if (tt != null && tt.compiled_type.FullName.ToLower().StartsWith("system.func"))
                                                        {
                                                            resformaltype = tt.instance_params[tt.instance_params.Count - 1]; // Последний параметр в записи Func<T,T1,...TN> - тип возвращаемого значения
                                                            var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность
                                                            if (bbb)
                                                            {
                                                                GoodVersionsCountWithSameResType += 1;
                                                                spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. 
                                                            }
                                                        }*/
                                                    }
                                                    catch
                                                    {
                                                        throw;
                                                    }
                                                    finally
                                                    {
                                                        LambdaHelper.RemoveLambdaInfoFromCompilationContext(context, en as function_lambda_definition);
                                                        // восстанавливаем сохраненный тип возвращаемого значения
                                                        if (restype != null)
                                                            restype.real_type = realrestype;
                                                        // восстанавливаем сохраненные типы параметров лямбды, которые не были заданы явно
                                                        for (var k = 0; k < fld.formal_parameters.params_list.Count; k++)
                                                        {
                                                            var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type;
                                                            if (laminftypeK != null)
                                                                laminftypeK.real_type = realparamstype[k];
                                                        }

                                                        fld.lambda_name = lambdaName; //lroman Восстанавливаем имена
                                                        fld.lambda_visit_mode = fl;
                                                    }

                                                    //contextChanger.RestoreCurrentContext();
                                                    exprCounter++;
                                                }
                                            }
                                            /*if (spfnum >= 0) // два удачных инстанцирования - плохо. Может, одно - с более близким типом возвращаемого значения, тогда это плохо - надо доделать, но пока так
                                            {
                                                spfnum = -2;
                                                break;
                                            }*/

                                            if (GoodVersionsCountWithSameResType == 0)
                                                spfnum = i; // здесь запоминаем индекс только если нет подошедших, совпадающих по типу возвращаемого значения
                                            GoodVersionsCount += 1;
                                            for (int j = 0; j < exprs.Count; j++) // копируем назад если всё хорошо
                                                exprs[j] = exprs1[j];
                                        }
                                        catch (Exception e)
                                        {
                                            // если сюда попали, значит, не вывели типы в лямбде и надо эту инстанцию пропускать
                                            //contextChanger.RestoreCurrentContext();
                                            lastmultex = e;
                                        }
                                    } // конец цикла по версиям
                                    if (GoodVersionsCount > 1 && GoodVersionsCountWithSameResType != 1) // подошло много, но не было ровно одной с совпадающим типом возвращаемого значения
                                        throw new SeveralFunctionsCanBeCalled(subloc, spf);
                                    if (GoodVersionsCount == 0) // было много, но ни одна не подошла из-за лямбд
                                    {
                                        throw lastmultex;
                                        //throw new NoFunctionWithSameArguments(subloc2, false);
                                    }

                                    int kk = 0;
                                    
                                    foreach (SyntaxTree.expression en in _method_call.parameters.expressions) //lroman окончательно подставить типы в лямбды
                                    {
                                        if (!(en is SyntaxTree.function_lambda_definition))
                                        {
                                            kk++;
                                            continue;
                                        }
                                        else
                                        {
                                            LambdaHelper.InferTypesFromVarStmt(spf[spfnum].parameters[kk].type, en as SyntaxTree.function_lambda_definition, this);
                                            exprs[kk] = convert_strong(en);
                                            kk++;
                                        }
                                    }
                                }
                                // SSM 21.05.14 end
                                LambdaHelper.processingLambdaParametersForTypeInference--;
                            }
                            //lroman//
                            #endregion

                            function_node del_func = convertion_data_and_alghoritms.select_function(exprs, si, sloc, syntax_nodes_parameters);
                            base_function_call bbfc = create_not_static_method_call(del_func, exp_int, sloc, proc_wait);
                            bbfc.parameters.AddRange(exprs);

                            switch (mot)
                            {
                                case motivation.expression_evaluation:
                                    {
                                        return_value(bbfc);
                                        return;
                                    }
                                case motivation.semantic_node_reciving:
                                    {
                                        return_semantic_value(bbfc);
                                        return;
                                    }
                                default:
                                    {
                                        AddError(bbfc.location, "EXPRESSION_IS_NOT_ADDRESSED");
                                        return;
                                    }
                            }
                        }
                        else
                        {
                            throw new CompilerInternalError("Unexpected method name kind");
                        }
                    }
                }
            }

            //definition_node dn=check_name_node_type(id.name,si,get_location(_method_call),general_node_type.function_node);

            expression_node exp2 = null;
            location subloc2 = get_location(id);

            List<TreeConverter.SymbolInfo> sibak = new List<TreeConverter.SymbolInfo>();
            TreeConverter.SymbolInfo ssi=si;
            while (ssi != null)
            {
                ssi = ssi.Next;
                sibak.Add(ssi);
            }


            if (si == null)
            {
                AddError(new UndefinedNameReference(id.name, subloc2));
            }
			is_format_allowed = false;
            if (SystemUnitAssigned)
                if (SystemLibrary.SystemLibInitializer.read_procedure.Equal(si) || SystemLibrary.SystemLibInitializer.readln_procedure.Equal(si))
                {
                    
            		expression_node bfcint = make_read_call(si, _method_call.parameters, subloc2);
                    if (!proc_wait)
                        AddError(subloc2, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", (si.sym_info as function_node).name);
                    switch (mot)
                    {
                        case motivation.expression_evaluation:
                            {
                                return_value(bfcint);
                                return;
                            }
                        case motivation.semantic_node_reciving:
                            {
                                return_semantic_value(bfcint);
                                return;
                            }
                        default:
                            {
                                AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED");
                                return;
                            }
                    }

                    return;
                }
            else if (SystemLibrary.SystemLibInitializer.write_procedure.Equal(si) || SystemLibrary.SystemLibInitializer.writeln_procedure.Equal(si) || SystemLibrary.SystemLibInitializer.StrProcedure.Equal(si))
            {
            	is_format_allowed = true;
            }
            else if (SystemLibrary.SystemLibInitializer.ArrayCopyFunction.Equal(si))
            {
            	if (_method_call.parameters != null && _method_call.parameters.expressions.Count == 1)
            	{
            		expression_node param0 = convert_strong(_method_call.parameters.expressions[0]);
            		if (param0.type.type_special_kind == SemanticTree.type_special_kind.array_kind)
            		{
            			location loc = get_location(_method_call);
            			expression_node en = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.ArrayCopyFunction.sym_info as function_node,loc,param0);
                    	function_node fn = convertion_data_and_alghoritms.get_empty_conversion(en.type, param0.type, false);
                    	en = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, en);
                    	return_value(en);
                    	return;
            		}
            	}
            }
            else if (SystemLibrary.SystemLibInitializer.SetLengthProcedure.Equal(si) || SystemLibrary.SystemLibrary.resize_func == si.sym_info as function_node)
            {
            	if (_method_call.parameters != null && _method_call.parameters.expressions.Count >= 2)
            	{
            		expression_node param0 = convert_strong(_method_call.parameters.expressions[0]);
            		if (!param0.is_addressed)
            			AddError(new ThisExpressionCanNotBePassedAsVarParameter(param0));
            		if (param0.type.type_special_kind == SemanticTree.type_special_kind.short_string)
            		{
            			expression_node param1 = convert_strong(_method_call.parameters.expressions[1]);
            			param1 = convertion_data_and_alghoritms.convert_type(param1,SystemLibrary.SystemLibrary.integer_type);
                        base_function_call cnfn = null; 
                        if (SystemLibrary.SystemLibInitializer.SetLengthForShortStringProcedure.sym_info is common_namespace_function_node)
                            cnfn = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.SetLengthForShortStringProcedure.sym_info as common_namespace_function_node, get_location(_method_call));
            			else
                            cnfn = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.SetLengthForShortStringProcedure.sym_info as compiled_function_node, get_location(_method_call));
                        cnfn.parameters.AddElement(param0);
            			cnfn.parameters.AddElement(param1);
            			cnfn.parameters.AddElement(new int_const_node((param0.type as short_string_type_node).Length,null));
            			switch (mot)
                    	{
                        	case motivation.expression_evaluation:
                            {
                                return_value(cnfn);
                                return;
                            }
                        	case motivation.semantic_node_reciving:
                            {
                                return_semantic_value(cnfn);
                                return;
                            }
                        	default:
                            {
                                AddError(cnfn.location, "EXPRESSION_IS_NOT_ADDRESSED");
                                return;
                            }
                    	}
            		}
            		else if (param0.type.type_special_kind == SemanticTree.type_special_kind.array_kind)
            		{
            			int rank = 1;
            			if (param0.type is compiled_type_node)
            				rank = (param0.type as compiled_type_node).rank;
            			else if (param0.type is common_type_node)
            				rank = (param0.type as common_type_node).rank;
            			if (_method_call.parameters.expressions.Count-1 != rank)
            				AddError(get_location(_method_call), "{0}_PARAMETERS_EXPECTED", rank+1);
            			if (rank > 1)
            			{
            				type_node tn = param0.type.element_type;
            				location loc = get_location(_method_call);
            				typeof_operator to = new typeof_operator(tn, loc);
                    		List<expression_node> lst = new List<expression_node>();
                    		//размер
                    		for (int i=1; i<_method_call.parameters.expressions.Count; i++)
                    		{
                    			expression_node expr = convert_strong(_method_call.parameters.expressions[i]);;
                    			expr = convertion_data_and_alghoritms.convert_type(expr, SystemLibrary.SystemLibrary.integer_type);
                    			if (expr is int_const_node && (expr as int_const_node).constant_value < 0)
                    				AddError(expr.location,"NEGATIVE_ARRAY_LENGTH_({0})_NOT_ALLOWED", (expr as int_const_node).constant_value);
                    			lst.Add(expr);
                    		}
                    		//это вызов спецфункции
                    		
                    		expression_node retv = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.NewArrayProcedureDecl, loc, to, new int_const_node(lst.Count,loc));
                    		common_namespace_function_call cnfc = retv as common_namespace_function_call;
                    		foreach (expression_node e in lst)
                    			cnfc.parameters.AddElement(e);
                    		expression_node en = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.CopyWithSizeFunction.sym_info as function_node,loc,param0,cnfc);
                    		function_node fn = convertion_data_and_alghoritms.get_empty_conversion(en.type, retv.type, false);
                    		en = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, en);
                    		basic_function_call bfc = new basic_function_call(tn.find(compiler_string_consts.assign_name).sym_info as basic_function_node,loc,param0,en);
                    		return_value(bfc);
                    		return;
            			}
            		}
            	}
            }
            else if (SystemLibrary.SystemLibInitializer.InsertProcedure.Equal(si))
            {
            	if (_method_call.parameters != null && _method_call.parameters.expressions.Count == 3)
            	{
            		//expression_node param0 = convert_strong(_method_call.parameters.expressions[0]);
            		expression_node param1 = convert_strong(_method_call.parameters.expressions[1]);
            		//expression_node param2 = convert_strong(_method_call.parameters.expressions[2]);
            		if (param1.type.type_special_kind == SemanticTree.type_special_kind.short_string)
            		{
            			expression_node param0 = convert_strong(_method_call.parameters.expressions[0]);
            			expression_node param2 = convert_strong(_method_call.parameters.expressions[2]);
            			param0 = convertion_data_and_alghoritms.convert_type(param0,SystemLibrary.SystemLibrary.string_type);
            			param2 = convertion_data_and_alghoritms.convert_type(param2,SystemLibrary.SystemLibrary.integer_type);
                        base_function_call cnfn = null;
                        if (SystemLibrary.SystemLibInitializer.InsertInShortStringProcedure.sym_info is common_namespace_function_node)
                            cnfn = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.InsertInShortStringProcedure.sym_info as common_namespace_function_node, get_location(_method_call));
            			else
                            cnfn = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.InsertInShortStringProcedure.sym_info as compiled_function_node, get_location(_method_call));
                        cnfn.parameters.AddElement(param0);
            			cnfn.parameters.AddElement(param1);
            			cnfn.parameters.AddElement(param2);
            			cnfn.parameters.AddElement(new int_const_node((param1.type as short_string_type_node).Length,null));
            			switch (mot)
                    	{
                        	case motivation.expression_evaluation:
                            {
                                return_value(cnfn);
                                return;
                            }
                        	case motivation.semantic_node_reciving:
                            {
                                return_semantic_value(cnfn);
                                return;
                            }
                        	default:
                            {
                                AddError(cnfn.location, "EXPRESSION_IS_NOT_ADDRESSED");
                                return;
                            }
                    	}
            		}
            	}
            }
            else if (SystemLibrary.SystemLibInitializer.DeleteProcedure.Equal(si))
            {
            	if (_method_call.parameters != null && _method_call.parameters.expressions.Count == 3)
            	{
            		//expression_node param0 = convert_strong(_method_call.parameters.expressions[0]);
            		expression_node param0 = convert_strong(_method_call.parameters.expressions[0]);
            		//expression_node param2 = convert_strong(_method_call.parameters.expressions[2]);
            		if (param0.type.type_special_kind == SemanticTree.type_special_kind.short_string)
            		{
            			expression_node param1 = convert_strong(_method_call.parameters.expressions[1]);
            			expression_node param2 = convert_strong(_method_call.parameters.expressions[2]);
            			param1 = convertion_data_and_alghoritms.convert_type(param1,SystemLibrary.SystemLibrary.integer_type);
            			param2 = convertion_data_and_alghoritms.convert_type(param2,SystemLibrary.SystemLibrary.integer_type);
                        base_function_call cnfn = null;
                        if (SystemLibrary.SystemLibInitializer.DeleteProcedure.sym_info is common_namespace_function_node) 
                            cnfn = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.DeleteProcedure.sym_info as common_namespace_function_node, get_location(_method_call));
                        else
                            cnfn = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.DeleteProcedure.sym_info as compiled_function_node, get_location(_method_call));
            			cnfn.parameters.AddElement(param0);
            			cnfn.parameters.AddElement(param1);
            			cnfn.parameters.AddElement(param2);
            			switch (mot)
                    	{
                        	case motivation.expression_evaluation:
                            {
                                return_value(cnfn);
                                return;
                            }
                        	case motivation.semantic_node_reciving:
                            {
                                return_semantic_value(cnfn);
                                return;
                            }
                        	default:
                            {
                                AddError(cnfn.location, "EXPRESSION_IS_NOT_ADDRESSED");
                                return;
                            }
                    	}
            		}
            	}
            }
            else if (SystemLibrary.SystemLibInitializer.IncludeProcedure.Equal(si)
                            || SystemLibrary.SystemLibInitializer.ExcludeProcedure.Equal(si))
            {
            	if (_method_call.parameters != null && _method_call.parameters.expressions.Count == 2)
            	{
            		expression_node param0 = convert_strong(_method_call.parameters.expressions[0]);
            		expression_node param1 = convert_strong(_method_call.parameters.expressions[1]);
            		expressions_list args = new expressions_list();
            		args.AddElement(param0);
            		args.AddElement(param1);
            		CheckSpecialFunctionCall(si,args,get_location(_method_call));
                    expression_node en_cnfn = null;
                    if (SystemLibrary.SystemLibInitializer.IncludeProcedure.sym_info is common_namespace_function_node)
                    {
                        common_namespace_function_call cnfn = null;
                        if (SystemLibrary.SystemLibInitializer.IncludeProcedure.Equal(si)) cnfn = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.IncludeProcedure.sym_info as common_namespace_function_node, get_location(_method_call));
                        else cnfn = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ExcludeProcedure.sym_info as common_namespace_function_node, get_location(_method_call));
                        cnfn.parameters.AddElement(param0);
                        cnfn.parameters.AddElement(param1);
                        en_cnfn = cnfn;
                    }
                    else
                    {
                        compiled_static_method_call cnfn = null;
                        if (SystemLibrary.SystemLibInitializer.IncludeProcedure.Equal(si)) cnfn = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.IncludeProcedure.sym_info as compiled_function_node, get_location(_method_call));
                        else cnfn = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ExcludeProcedure.sym_info as compiled_function_node, get_location(_method_call));
                        cnfn.parameters.AddElement(param0);
                        cnfn.parameters.AddElement(param1);
                        en_cnfn = cnfn;
                    }
            		switch (mot)
                    {
                        	case motivation.expression_evaluation:
                            {
                                return_value(en_cnfn);
                                return;
                            }
                        	case motivation.semantic_node_reciving:
                            {
                                return_semantic_value(en_cnfn);
                                return;
                            }
                        	default:
                            {
                                AddError(en_cnfn.location, "EXPRESSION_IS_NOT_ADDRESSED");
                                return;
                            }
                    }
            	}
            }
            else if (SystemLibrary.SystemLibInitializer.IncProcedure.Equal(si))
            {
            	expression_node bfcint = make_inc_call(si, _method_call.parameters, subloc2);
            	if (!proc_wait)
                        AddError(subloc2, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", (si.sym_info as function_node).name);
            	switch (mot)
                    {
                        case motivation.expression_evaluation:
                            {
                                return_value(bfcint);
                                return;
                            }
                        case motivation.semantic_node_reciving:
                            {
                                return_semantic_value(bfcint);
                                return;
                            }
                        default:
                            {
                                AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED");
                                return;
                            }
                    }

                    return;
            }
            else if (SystemLibrary.SystemLibInitializer.DecProcedure.Equal(si))
            {
            	expression_node bfcint = make_dec_call(si, _method_call.parameters, subloc2);
            	if (!proc_wait)
                        AddError(subloc2, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", (si.sym_info as function_node).name);
            	switch (mot)
                    {
                        case motivation.expression_evaluation:
                            {
                                return_value(bfcint);
                                return;
                            }
                        case motivation.semantic_node_reciving:
                            {
                                return_semantic_value(bfcint);
                                return;
                            }
                        default:
                            {
                                AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED");
                                return;
                            }
                    }

                    return;
            }
            else if (SystemLibrary.SystemLibInitializer.SuccFunction.Equal(si))
            {
            	expression_node bfcint = make_succ_call(si, _method_call.parameters, subloc2);
            	switch (mot)
                    {
                        case motivation.expression_evaluation:
                            {
                                return_value(bfcint);
                                return;
                            }
                        case motivation.semantic_node_reciving:
                            {
                                return_semantic_value(bfcint);
                                return;
                            }
                        default:
                            {
                                AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED");
                                return;
                            }
                    }

                    return;
            }
            else if (SystemLibrary.SystemLibInitializer.PredFunction.Equal(si))
            {
            	expression_node bfcint = make_pred_call(si, _method_call.parameters, subloc2);
            	switch (mot)
                    {
                        case motivation.expression_evaluation:
                            {
                                return_value(bfcint);
                                return;
                            }
                        case motivation.semantic_node_reciving:
                            {
                                return_semantic_value(bfcint);
                                return;
                            }
                        default:
                            {
                                AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED");
                                return;
                            }
                    }

                    return;
            }
            else if (SystemLibrary.SystemLibInitializer.OrdFunction.Equal(si))
            {
            	expression_node bfcint = make_ord_call(si, _method_call.parameters, subloc2);
            	switch (mot)
                    {
                        case motivation.expression_evaluation:
                            {
                                return_value(bfcint);
                                return;
                            }
                        case motivation.semantic_node_reciving:
                            {
                                return_semantic_value(bfcint);
                                return;
                            }
                        default:
                            {
                                AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED");
                                return;
                            }
                    }

                    return;
            }
            else if (SystemLibrary.SystemLibInitializer.LowFunction.Equal(si))
            {
            	if (_method_call.parameters != null && _method_call.parameters.expressions.Count == 1)
            	{
            		expression_node param0 = convert_strong(_method_call.parameters.expressions[0]);
            		if (param0.type.type_special_kind == SemanticTree.type_special_kind.array_wrapper)
            		{
            			bounded_array_interface bai = param0.type.get_internal_interface(internal_interface_kind.bounded_array_interface) as bounded_array_interface;
            			expression_node en = new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value),get_location(_method_call));
            			switch (mot)
                    	{
                        	case motivation.expression_evaluation:
                            {
                                return_value(en);
                                return;
                            }
                        	case motivation.semantic_node_reciving:
                            {
                                return_semantic_value(en);
                                return;
                            }
                        	default:
                            {
                                AddError(en.location, "EXPRESSION_IS_NOT_ADDRESSED");
                                return;
                            }
                    	}
            		}
            	}
            }
            else if (SystemLibrary.SystemLibInitializer.HighFunction.Equal(si))
            {
            	if (_method_call.parameters != null && _method_call.parameters.expressions.Count == 1)
            	{
            		expression_node param0 = convert_strong(_method_call.parameters.expressions[0]);
            		if (param0.type.type_special_kind == SemanticTree.type_special_kind.array_wrapper)
            		{
            			bounded_array_interface bai = param0.type.get_internal_interface(internal_interface_kind.bounded_array_interface) as bounded_array_interface;
            			expression_node en = new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.upper_value),get_location(_method_call));
            			switch (mot)
                    	{
                        	case motivation.expression_evaluation:
                            {
                                return_value(en);
                                return;
                            }
                        	case motivation.semantic_node_reciving:
                            {
                                return_semantic_value(en);
                                return;
                            }
                        	default:
                            {
                                AddError(en.location, "EXPRESSION_IS_NOT_ADDRESSED");
                                return;
                            }
                    	}
            		}
            	}
            }
            else if (si == SystemLibrary.SystemLibInitializer.NewProcedure)
            {
            	expression_node bfcint = make_new_call(si, _method_call.parameters, subloc2);
            	if (!proc_wait)
                        AddError(subloc2, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", (si.sym_info as function_node).name);
            	switch (mot)
                    {
                        case motivation.expression_evaluation:
                            {
                                return_value(bfcint);
                                return;
                            }
                        case motivation.semantic_node_reciving:
                            {
                                return_semantic_value(bfcint);
                                return;
                            }
                        default:
                            {
                                AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED");
                                return;
                            }
                    }

                    return;
            }
            else if (si == SystemLibrary.SystemLibInitializer.DisposeProcedure)
            {
                //if (convertion_data_and_alghoritms.select_function(convert_expression_list(_method_call.parameters.expressions), si, subloc2) == SystemLibrary.SystemLibInitializer.DisposeProcedure.sym_info)
                //{
                    expression_node bfcint = make_dispose_call(si, _method_call.parameters, subloc2);
                    if (!proc_wait)
                        AddError(subloc2, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", (si.sym_info as function_node).name);
                    switch (mot)
                    {
                        case motivation.expression_evaluation:
                            {
                                return_value(bfcint);
                                return;
                            }
                        case motivation.semantic_node_reciving:
                            {
                                return_semantic_value(bfcint);
                                return;
                            }
                        default:
                            {
                                AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED");
                                return;
                            }
                    }

                    return;
               // }
            }
            else if (!debug && SystemLibrary.SystemLibInitializer.AssertProcedure.Equal(si))
            {
//            	return_value(new empty_statement(null));
//            	return;
            }
            /*else if (SystemLibrary.SystemLibInitializer.IncProcedure != null && SystemLibrary.SystemLibInitializer.IncProcedure.Equal(si))
            	{
            		expression_node bfcint = make_inc_call(si, _method_call.parameters, subloc2);
            	}*/

            if (si.sym_info.general_node_type != general_node_type.function_node)
            {
                if (si.sym_info.general_node_type == general_node_type.type_node)
                {
                    to_type = ((type_node)(si.sym_info));
                    /*if (to_type == SystemLibrary.SystemLibrary.void_type)
                    {
                        throw new VoidNotValid(subloc2);
                    }*/
                    check_for_type_allowed(to_type,subloc2);
                }
                else
                {
                    exp2 = ident_value_reciving(si, id);
                    internal_interface ii = exp2.type.get_internal_interface(internal_interface_kind.delegate_interface);
                    if (ii == null)
                    {
                        AddError(subloc2, "EXPECTED_DELEGATE");
                    }
                    if (exp2 is nonstatic_event_reference)
                    {
                    	nonstatic_event_reference nser = exp2 as nonstatic_event_reference;
                    	common_event ce = nser.en as common_event;
                    	if (ce != null)
                    		exp2 = new class_field_reference(ce.field,new this_node(ce.cont_type,null),null);
                    	else
                    		AddError(get_location(_method_call), "EVENT_{0}_MUST_BE_IN_LEFT_PART", nser.en.name);
                    }
                    else if (exp2 is static_event_reference)
                    {
                    	static_event_reference nser = exp2 as static_event_reference;
                    	common_event ce = nser.en as common_event;
                        if (ce != null)
                            exp2 = new static_class_field_reference(ce.field, null);
                        else if (nser.en is common_namespace_event && _compiled_unit.namespaces.IndexOf((nser.en as common_namespace_event).namespace_node) != -1)
                            exp2 = new namespace_variable_reference((nser.en as common_namespace_event).field, null);
                        else
                            AddError(get_location(_method_call), "EVENT_{0}_MUST_BE_IN_LEFT_PART", nser.en.name);
                    }
                    delegate_internal_interface dii = ii as delegate_internal_interface;
                    si = new SymbolInfo(dii.invoke_method);
                }
            }

            if (to_type != null)
            {
                if ((_method_call.parameters == null) || (_method_call.parameters.expressions.Count != 1))
                {
                    AddError(get_location(_method_call), "ONLY_ONE_PARAMETER_OF_TYPE_CONVERSION_ALLOWED");
                }
            }

            if (_method_call.parameters != null)
            {
                foreach (SyntaxTree.expression en in _method_call.parameters.expressions)
                {
                	bool tmp = is_format_allowed;
					
					#region Отмечаем флаг в лямбдах, говорящий о том, что в первый раз будем их "обходить" для вывода типов
                    //lroman//
                    if (en is SyntaxTree.function_lambda_definition)
                    {
                        lambdas_are_in_parameters = true;
                        ((SyntaxTree.function_lambda_definition)en).lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing;
                    }
                    //lroman//
                    #endregion
					
                	exprs.AddElement(convert_strong(en));
                	is_format_allowed = tmp;
                }
            }
			is_format_allowed = false;
            CheckSpecialFunctionCall(si, exprs,get_location(_method_call));

            ssi=si;
            foreach (SymbolInfo sii in sibak)
            {
                ssi.Next = sii;
                ssi = sii;
            }

            if (to_type != null)
            {
                //(ssyy) К вызову функции здесь явно не приводим, т.к. это излишне.
                expression_node ee = exprs[0];
                bool del = to_type is common_type_node && (to_type as common_type_node).IsDelegate;
                if (!del)
                try_convert_typed_expression_to_function_call(ref ee);
                else
                	ee = convert_strong(_method_call.parameters.expressions[0]);
                expr_node = convertion_data_and_alghoritms.explicit_convert_type(ee, to_type);
                //expression_node expr = convert_if_typed_expression_to_function_call(exprs[0]);
                //expr_node = convertion_data_and_alghoritms.explicit_convert_type(expr, to_type);
            }
            else
            {
                if (exp2 == null)
                {
                    location mcloc = get_location(_method_call);
                    if (iwt != null)
                    {
                        si = get_generic_functions(si, true, mcloc);
                        si = get_function_instances(si, iwt.template_params.params_list, id.name, mcloc, si.Next == null);
                    }
					
					#region Если встретились лямбды в фактических параметрах, то выбираем нужную функцию из перегруженных, выводим типы, отмечаем флаг в лямбдах, говорящий о том, что мы их реально обходим 
                    //lroman//
                    if (lambdas_are_in_parameters)
                    {
                        LambdaHelper.processingLambdaParametersForTypeInference++;
                        // SSM 21.05.14 - попытка обработать перегруженные функции с параметрами-лямбдами с различными возвращаемыми значениями
                        function_node_list spf = null;
                        try
                        {
                            function_node fn = convertion_data_and_alghoritms.select_function(exprs, si, subloc2, syntax_nodes_parameters);
                            int exprCounter = 0;
                            foreach (SyntaxTree.expression en in _method_call.parameters.expressions)
                            {
                                if (!(en is SyntaxTree.function_lambda_definition))
                                {
                                    exprCounter++;
                                    continue;
                                }
                                else
                                {
                                    var enLambda = (SyntaxTree.function_lambda_definition) en;
                                    LambdaHelper.InferTypesFromVarStmt(fn.parameters[exprCounter].type, enLambda, this);
                                    enLambda.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing;
                                    exprs[exprCounter] = convert_strong(en);
                                    enLambda.lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing;
                                    exprCounter++;
                                }
                            }
                        }
                        catch (SeveralFunctionsCanBeCalled sf)
                        {
                            spf = sf.set_of_possible_functions; // Возможны несколько перегруженных версий - надо выводить дальше в надежде что какие-то уйдут и останется одна
                        }

                        Exception lastmultex = null;
                        if (spf != null) // пытаемся инстанцировать одну за другой и ошибки гасим try
                        {   // exprs - глобальная, поэтому надо копировать
                            int spfnum = -1; // первый номер правильно инстанцированной. Если потом встретился второй, то тоже ошибка
                                             // SSM 4.08.15. Сейчас меняю эту логику. Если будет много кандидатов, но ровно один с совпадающим типом возвращаемого значения, то его и надо выбирать.
                                             // не забыть, что аналогичный код есть в create_constructor_call!!!!!!! И еще выше по коду!!! кошмар!!!
                            int GoodVersionsCount = 0;
                            int GoodVersionsCountWithSameResType = 0;
                            for (int i = 0; i < spf.Count; i++) // цикл по версиям
                            {
                                function_node fn = spf[i];
                                try // внутренний try регенерирует исключение, а этот гасит
                                {
                                    int exprCounter = 0;
                                    expressions_list exprs1 = new expressions_list();
                                    exprs1.AddRange(exprs); // сделали копию

                                    foreach (SyntaxTree.expression en in _method_call.parameters.expressions)
                                    {
                                        if (!(en is SyntaxTree.function_lambda_definition))
                                        {
                                            exprCounter++;
                                            continue;
                                        }
                                        else
                                        {
                                            var fld = en as SyntaxTree.function_lambda_definition;

                                            var lambdaName = fld.lambda_name;                           //lroman Сохранять имя необходимо
                                            var fl = fld.lambda_visit_mode;

                                            // запомнили типы параметров лямбды - SSM
                                            object[] realparamstype = new object[fld.formal_parameters.params_list.Count]; // здесь хранятся выведенные типы лямбд или null если типы явно заданы
                                            for (var k = 0; k < fld.formal_parameters.params_list.Count; k++)
                                            {
                                                var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type;
                                                if (laminftypeK == null)
                                                    realparamstype[k] = null;
                                                else realparamstype[k] = laminftypeK.real_type;
                                            }

                                            // запоминаем реальный тип возвращаемого значения если он не указан явно (это должен быть any_type или null если он указан явно) - он может измениться при следующем вызове, поэтому мы его восстановим
                                            var restype = fld.return_type as SyntaxTree.lambda_inferred_type;
                                            object realrestype = null;
                                            if (restype != null) 
                                                realrestype = restype.real_type;  

                                            LambdaHelper.InferTypesFromVarStmt(fn.parameters[exprCounter].type, fld, this);
                                            fld.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; //lroman
                                            fld.lambda_name = LambdaHelper.GetAuxiliaryLambdaName(lambdaName); // поправляю имя. Думаю, назад возвращать не надо. ПРОВЕРИТЬ!

                                            //contextChanger.SaveContextAndUpToNearestDefSect();
                                            try
                                            {
                                                exprs1[exprCounter] = convert_strong(en);

                                                // SSM 7/08/15

                                                type_node resexprtype = fld.RealSemTypeOfResExpr as type_node;
                                                type_node resformaltype = fld.RealSemTypeOfResult as type_node;
                                                var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность
                                                if (bbb)
                                                {
                                                    GoodVersionsCountWithSameResType += 1;
                                                    spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. 
                                                }

                                                /*var tt = fn.parameters[exprCounter].type as compiled_type_node;
                                                if (tt != null && tt.compiled_type.FullName.ToLower().StartsWith("system.func"))
                                                {
                                                    resformaltype = tt.instance_params[tt.instance_params.Count - 1]; // Последний параметр в записи Func<T,T1,...TN> - тип возвращаемого значения
                                                    var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность
                                                    if (bbb)
                                                    {
                                                        GoodVersionsCountWithSameResType += 1;
                                                        spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. 
                                                    }
                                                }*/
                                            }
                                            catch
                                            {
                                                throw;
                                            }
                                            finally
                                            {
                                                LambdaHelper.RemoveLambdaInfoFromCompilationContext(context, en as function_lambda_definition);
                                                // восстанавливаем сохраненный тип возвращаемого значения
                                                if (restype != null)
                                                    restype.real_type = realrestype;
                                                // восстанавливаем сохраненные типы параметров лямбды, которые не были заданы явно
                                                for (var k = 0; k < fld.formal_parameters.params_list.Count; k++)
                                                {
                                                    var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type;
                                                    if (laminftypeK != null)
                                                        laminftypeK.real_type = realparamstype[k];
                                                }

                                                fld.lambda_name = lambdaName; //lroman Восстанавливаем имена
                                                fld.lambda_visit_mode = fl;
                                            }

                                            //contextChanger.RestoreCurrentContext();
                                            exprCounter++;
                                        }
                                    }
                                    /*if (spfnum >= 0) // два удачных инстанцирования - плохо. Может, одно - с более близким типом возвращаемого значения, тогда это плохо - надо доделать, но пока так
                                    {
                                        spfnum = -2;
                                        break;
                                    }*/

                                    if (GoodVersionsCountWithSameResType==0)
                                        spfnum = i; // здесь запоминаем индекс только если нет подошедших, совпадающих по типу возвращаемого значения
                                    GoodVersionsCount += 1;
                                    for (int j = 0; j < exprs.Count; j++) // копируем назад если всё хорошо
                                        exprs[j] = exprs1[j];
                                }
                                catch (Exception e)
                                {
                                    // если сюда попали, значит, не вывели типы в лямбде и надо эту инстанцию пропускать
                                    //contextChanger.RestoreCurrentContext();
                                    lastmultex = e;
                                }
                            } //--------------- конец цикла по версиям

                            if (GoodVersionsCount>1 && GoodVersionsCountWithSameResType!=1) // подошло много, но не было ровно одной с совпадающим типом возвращаемого значения
                                throw new SeveralFunctionsCanBeCalled(subloc2, spf);
                            if (GoodVersionsCount == 0) // было много, но ни одна не подошла из-за лямбд
                            {
                                throw lastmultex;
                                //throw new NoFunctionWithSameArguments(subloc2, false);
                            }

                            var kk = 0;
                            foreach (SyntaxTree.expression en in _method_call.parameters.expressions) //lroman окончательно подставить типы в лямбды
                            {
                                if (!(en is SyntaxTree.function_lambda_definition))
                                {
                                    kk++;
                                    continue;
                                }
                                else
                                {
                                    LambdaHelper.InferTypesFromVarStmt(spf[spfnum].parameters[kk].type, en as SyntaxTree.function_lambda_definition, this);
                                    exprs[kk] = convert_strong(en);
                                    kk++;
                                }
                            }    
                        }
                        // SSM 21.05.14 end
                        LambdaHelper.processingLambdaParametersForTypeInference--;
                    }
                    //lroman//
                    #endregion
					
                    expr_node = convertion_data_and_alghoritms.create_full_function_call(exprs, si, mcloc,
                        context.converted_type, context.top_function, proc_wait);
                }
                else
                {
                    function_node fn = convertion_data_and_alghoritms.select_function(exprs, si, subloc2, syntax_nodes_parameters);
                    base_function_call bbffcc = create_not_static_method_call(fn, exp2, subloc2, proc_wait);
                    bbffcc.parameters.AddRange(exprs);
                    expr_node = bbffcc;
                }
            }

            /*if ((proc_wait==false)&&(expr_node.type==null))
            {
                throw new FunctionExpectedProcedureMeet((function_node)dn,get_location(_method_call));
            }*/

            switch (mot)
            {
                case motivation.expression_evaluation:
                    {
                        return_value(expr_node);
                        return;
                    }
                case motivation.semantic_node_reciving:
                    {
                        return_semantic_value(expr_node);
                        return;
                    }
            	case motivation.address_reciving:
            		{
                        AddError(get_location(_method_call), "LEFT_SIDE_CANNOT_BE_ASSIGNED_TO");
                        return;
            		}
                default:
                    {
                        //throw new CompilerInternalError("Can not recive address from method call");//!
                        AddError(get_location(_method_call), "EXPECTED_VARIABLE");
                        return;
                    }
            }
            //throw new CompilerInternalError("Error in creation method call");

        }
コード例 #3
0
 public typeof_operator_as_constant(typeof_operator typeof_operator, location loc)
     :
     base(typeof_operator.type, loc)
 {
     _typeof_operator = typeof_operator;
 }
コード例 #4
0
        public override void visit(SyntaxTree.new_expr _new_expr)
        {
            type_node tn = ret.visit(_new_expr.type);
            //if (tn == SystemLibrary.SystemLibrary.void_type)
            //	AddError(new VoidNotValid(get_location(_new_expr.type)));
            check_for_type_allowed(tn,get_location(_new_expr.type));
            location loc = get_location(_new_expr);
            expressions_list exprs = null;
            var lambdas_are_in_parameters = false;
            var syntax_nodes_parameters = _new_expr.params_list == null
                                              ? new List<expression>()
                                              : _new_expr.params_list.expressions;

            if (_new_expr.params_list != null)
            {
                exprs = new expressions_list();
                foreach (SyntaxTree.expression en in _new_expr.params_list.expressions)
                {
                    if (en is SyntaxTree.function_lambda_definition)
                    {
                        lambdas_are_in_parameters = true;
                        ((SyntaxTree.function_lambda_definition)en).lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing;
                    }
                    exprs.AddElement(convert_strong(en));
                }
            }
            else
                exprs = new expressions_list();
            if (_new_expr.new_array)
            {
                //if (exprs.Count == 1)
                {
                    //new typename[size]
                    type_node atn = convertion_data_and_alghoritms.type_constructor.create_unsized_array(tn, context.converted_namespace, exprs.Count, loc);
                    //тип элементов
                    typeof_operator to = new typeof_operator(tn, loc);
                    List<expression_node> lst = new List<expression_node>();
                    //размер
                    for (int i=0; i<exprs.Count; i++)
                    {
                    	expression_node expr = exprs[i];
                    	expr = convertion_data_and_alghoritms.convert_type(expr, SystemLibrary.SystemLibrary.integer_type);
                    	if (expr is int_const_node && (expr as int_const_node).constant_value < 0)
                    		AddError(expr.location, "NEGATIVE_ARRAY_LENGTH_({0})_NOT_ALLOWED", (expr as int_const_node).constant_value);
                    	lst.Add(expr);
                    }
                    //это вызов спецфункции
                    expression_node retv = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.NewArrayProcedureDecl, loc, to, new int_const_node(exprs.Count,loc));
                    base_function_call cnfc = retv as base_function_call;
                    foreach (expression_node e in lst)
                    	cnfc.parameters.AddElement(e);
                    if (_new_expr.array_init_expr != null)
                    {
                    	if (exprs.Count > 1)
                    	{
                    		foreach (expression_node expr in lst)
                    		if (!(expr is int_const_node))
                                AddError(expr.location, "CONSTANT_EXPRESSION_EXPECTED");
                    		if (_new_expr.array_init_expr.elements == null)
                                AddError(get_location(_new_expr.array_init_expr), "ARRAY_CONST_EXPECTED");
                    		_new_expr.array_init_expr = get_possible_array_const(_new_expr.array_init_expr,atn) as SyntaxTree.array_const;
                    		expression_node e = convert_strong(_new_expr.array_init_expr);
                    		if (e is array_initializer)
                    		{
                    			array_initializer tmp = e as array_initializer;
                    			for (int i=0; i<exprs.Count; i++)
                    			{
                    				int len = (exprs[i] as int_const_node).constant_value;
                    				if (!(e is array_initializer) || (e as array_initializer).element_values.Count != len)
                                        AddError(e.location, "ARRAY_CONST_{0}_ELEMENTS_EXPECTED", len);
                    				e = (e as array_initializer).element_values[0];
                    			}
                    			cnfc.parameters.AddElement(ConvertArrayInitializer(atn,tmp));
                    		}
                    	}
                    	else
                    	{
                    		expression_node expr = lst[0];
                    		if (!(expr is int_const_node))
                                AddError(expr.location, "CONSTANT_EXPRESSION_EXPECTED");
                    		int len = (expr as int_const_node).constant_value;
                            if (_new_expr.array_init_expr.elements == null)
                            {
                                if (len != 0)
                                    AddError(get_location(_new_expr.array_init_expr), "ARRAY_CONST_{0}_ELEMENTS_EXPECTED", len);
                            }
                    		else if (_new_expr.array_init_expr.elements.expressions.Count != len)
                                AddError(get_location(_new_expr.array_init_expr), "ARRAY_CONST_{0}_ELEMENTS_EXPECTED", len);
                    		_new_expr.array_init_expr = get_possible_array_const(_new_expr.array_init_expr,atn) as SyntaxTree.array_const;
                    		if (_new_expr.array_init_expr.elements != null)
                            foreach (SyntaxTree.expression e in _new_expr.array_init_expr.elements.expressions)
                    			cnfc.parameters.AddElement(convertion_data_and_alghoritms.convert_type(clip_expression_if_need(convert_strong(e),tn),tn));
                    	}
                    }
                    //явное преобразования для того чтобы тип задать
                    function_node fn = convertion_data_and_alghoritms.get_empty_conversion(retv.type, atn, false);
                    retv = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, retv);
                    return_value(retv);
                    return;
                }
                
            }
            return_value(create_constructor_call(tn, exprs, get_location(_new_expr.type), new Tuple<bool, List<expression>>(lambdas_are_in_parameters, syntax_nodes_parameters)));
        }
コード例 #5
0
 private base_function_call CreateTypeCheckCall(definition_node func, type_node tp)
 {
     if (func is common_namespace_function_node)
     {
         common_namespace_function_call cnfc = new common_namespace_function_call(
             func as common_namespace_function_node, null);
         expression_node ex = new typeof_operator(tp, null);
         cnfc.parameters.AddElement(ex);
         return cnfc;
     }
     else
     {
         compiled_static_method_call cnfc = new compiled_static_method_call(
             func as compiled_function_node, null);
         expression_node ex = new typeof_operator(tp, null);
         cnfc.parameters.AddElement(ex);
         return cnfc;
     }
 }