Пример #1
0
 private void IncreaseNumAssField(class_field_reference fld)
 {
     FldInfo vi = helper.GetField(fld.field);
     if (vi == null) 
         return;
     vi.num_use++;
     vi.cur_ass++;
     
     if (vi.cur_use > 0) vi.cur_use--;
 }
Пример #2
0
 private void VisitClassFieldReference(class_field_reference en)
 {
     VisitExpression(en.obj);
     IncreaseNumUseField(en);
 }
		private void VisitClassFieldReference(class_field_reference expr)
		{
			VisitExpression(expr.obj);
			WriteFieldReference(expr.field);
		}
Пример #4
0
 private void IncreaseNumUseField(class_field_reference fld)
 {
     FldInfo vi = helper.GetField(fld.field);
     if (vi == null) return;
     vi.num_use++;
     vi.cur_use++;
     //if (vi.cur_ass == 0) warns.Add(new UseWithoutAssign(lvr.var.name, lvr.location));
 }
        private expression_node make_dec_call(SymbolInfo si, SyntaxTree.expression_list parameters, location loc)
        {
        	if (parameters == null) throw new NoFunctionWithSameParametresNum(loc,false,si.sym_info as function_node);
        	if (parameters.expressions.Count == 1 || parameters.expressions.Count == 2)
        	{
        		expression_node param0 = convert_strong(parameters.expressions[0]);
        		if (!param0.is_addressed)
        		{
        			bool is_pascal_array_ref = false;
                    if (param0.semantic_node_type == semantic_node_type.common_method_call)
                    {
                        common_method_call cmc = (common_method_call)param0;
                        internal_interface ii = cmc.obj.type.get_internal_interface(internal_interface_kind.bounded_array_interface);
                        if (ii != null)
                        {
                            if (cmc.function_node.name == compiler_string_consts.get_val_pascal_array_name)
                            {
                                bounded_array_interface bai = (bounded_array_interface)ii;
                                class_field cf = bai.int_array;
                                expression_node left = new class_field_reference(cf, cmc.obj, cmc.location);
                                expression_node right = cmc.parameters[0];
                                //right = convert_type(right, SystemLibrary.SystemLibrary.integer_type);
                                right = convertion_data_and_alghoritms.convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type);
                                right = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, right,
                                    new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value), cmc.location));
                                param0 = new simple_array_indexing(left, right, cmc.type, cmc.location);
                                is_pascal_array_ref = true;

                            }
                        }
                        if (!is_pascal_array_ref)
                        {
							throw new ThisExpressionCanNotBePassedAsVarParameter(param0);
                    	}
        				
        			}
                    else if (param0 is compiled_function_call)
                    {
                    	compiled_function_call cfc = param0 as compiled_function_call;
                    	if ((cfc.function_node.return_value_type == SystemLibrary.SystemLibrary.char_type && cfc.function_node.cont_type == SystemLibrary.SystemLibrary.string_type
                    	      && cfc.function_node == cfc.function_node.cont_type.default_property_node.get_function))
                    	{
                    		expressions_list exl = new expressions_list();
                            exl.AddElement(cfc.obj);
                            exl.AddElement(cfc.parameters[0]);
                            basic_function_call bfc2 = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc);
                            bfc2.parameters.AddElement(param0);
                            expression_node _param1 = null;
                            if (parameters.expressions.Count == 2) 
        					{
        						_param1 = convert_strong(parameters.expressions[1]);
        					}
                            if (_param1 != null)
                            	bfc2.parameters.AddElement(convertion_data_and_alghoritms.convert_type(_param1,SystemLibrary.SystemLibrary.integer_type));
                            else
                            	bfc2.parameters.AddElement(new int_const_node(1,null));
                            expressions_list el = new expressions_list();
                            el.AddElement(convertion_data_and_alghoritms.convert_type(bfc2,SystemLibrary.SystemLibrary.ushort_type));
                            function_node chr_func = convertion_data_and_alghoritms.select_function(el, SystemLibrary.SystemLibInitializer.ChrUnicodeFunction.SymbolInfo, loc);
                            exl.AddElement(convertion_data_and_alghoritms.create_simple_function_call(chr_func, loc, el.ToArray()));
                            function_node fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.StringDefaultPropertySetProcedure.SymbolInfo, loc);
                            expression_node ret = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, exl.ToArray());
                            return ret;
                    	}
                    	else
                    	{
                    		throw new ThisExpressionCanNotBePassedAsVarParameter(param0);
                    	}
                    }
                    else throw new ThisExpressionCanNotBePassedAsVarParameter(param0);
        		}
        		else
        			check_on_loop_variable(param0);
        		expression_node param1 = null;
        		int type_flag = 0;
        		bool is_uint=false;
        		bool is_enum=false;
        		if (parameters.expressions.Count == 2) 
        		{
        			param1 = convert_strong(parameters.expressions[1]);
        			param1 = convertion_data_and_alghoritms.convert_type(param1,SystemLibrary.SystemLibrary.integer_type);
        		}
        		basic_function_call ass = null;
        		basic_function_call bfc = null;
        		if (param0.type == SystemLibrary.SystemLibrary.integer_type)
        		{
        			ass = new basic_function_call(SystemLibrary.SystemLibrary.int_assign as basic_function_node,loc);
        			bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc);
        		}
        		else if (param0.type == SystemLibrary.SystemLibrary.char_type)
        		{
        			ass = new basic_function_call(SystemLibrary.SystemLibrary.char_assign as basic_function_node,loc);
        			bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc);
        		}
        		else if (param0.type == SystemLibrary.SystemLibrary.byte_type)
        		{
        			ass = new basic_function_call(SystemLibrary.SystemLibrary.byte_assign as basic_function_node,loc);
        			bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc);
        		}
        		else if (param0.type == SystemLibrary.SystemLibrary.sbyte_type)
        		{
        			ass = new basic_function_call(SystemLibrary.SystemLibrary.sbyte_assign as basic_function_node,loc);
        			bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc);
        		}
        		else if (param0.type == SystemLibrary.SystemLibrary.short_type)
        		{
        			ass = new basic_function_call(SystemLibrary.SystemLibrary.short_assign as basic_function_node,loc);
        			bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc);
        		}
        		else if (param0.type == SystemLibrary.SystemLibrary.ushort_type)
        		{
        			ass = new basic_function_call(SystemLibrary.SystemLibrary.ushort_assign as basic_function_node,loc);
        			bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc);
        		}
        		else if (param0.type == SystemLibrary.SystemLibrary.uint_type)
        		{
        			ass = new basic_function_call(SystemLibrary.SystemLibrary.uint_assign as basic_function_node,loc);
        			bfc = new basic_function_call(SystemLibrary.SystemLibrary.uint_sub as basic_function_node,loc);
        			type_flag = 2;
        			is_uint = true;
        		}
        		else if (param0.type == SystemLibrary.SystemLibrary.int64_type)
        		{
        			ass = new basic_function_call(SystemLibrary.SystemLibrary.long_assign as basic_function_node,loc);
        			bfc = new basic_function_call(SystemLibrary.SystemLibrary.long_sub as basic_function_node,loc);
        			type_flag = 1;
        		}
        		else if (param0.type == SystemLibrary.SystemLibrary.uint64_type)
        		{
        			ass = new basic_function_call(SystemLibrary.SystemLibrary.ulong_assign as basic_function_node,loc);
        			bfc = new basic_function_call(SystemLibrary.SystemLibrary.ulong_sub as basic_function_node,loc);
        			type_flag = 2;
        		}
        		else if (param0.type == SystemLibrary.SystemLibrary.bool_type)
        		{
        			if (param1 == null)
        			{
        				ass = new basic_function_call(SystemLibrary.SystemLibrary.bool_assign as basic_function_node,loc);
        				bfc = new basic_function_call(SystemLibrary.SystemLibrary.bool_not as basic_function_node,loc);
        				type_flag = 4;
        			}
        			else
        			{
        				basic_function_call mod_expr = new basic_function_call(SystemLibrary.SystemLibrary.int_mod as basic_function_node,loc);
        				mod_expr.parameters.AddElement(convertion_data_and_alghoritms.convert_type(param1,SystemLibrary.SystemLibrary.integer_type));
        				mod_expr.parameters.AddElement(new int_const_node(2,loc));
        				basic_function_call condition = new basic_function_call(SystemLibrary.SystemLibrary.int_eq as basic_function_node,loc);
        				condition.parameters.AddElement(mod_expr);
        				condition.parameters.AddElement(new int_const_node(0,loc));
        				basic_function_call not_expr = new basic_function_call(SystemLibrary.SystemLibrary.bool_not as basic_function_node,loc);
        				not_expr.parameters.AddElement(param0);
        				question_colon_expression qce = new question_colon_expression(condition, param0, not_expr, loc);
        				ass = new basic_function_call(SystemLibrary.SystemLibrary.bool_assign as basic_function_node,loc);
        				ass.parameters.AddElement(param0);
        				ass.parameters.AddElement(qce);
        				type_flag = 5;
        			}
        		}
        		else if (param0.type.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.diap_type || param0.type.IsEnum)
        		{
        			ass = new basic_function_call(SystemLibrary.SystemLibrary.int_assign as basic_function_node,loc);
        			bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc);
        			if (param0.type.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.diap_type)
        			{
        				type_node bt = param0.type.base_type;
        				if (bt == SystemLibrary.SystemLibrary.int64_type) type_flag = 1;
        				else if (bt == SystemLibrary.SystemLibrary.uint64_type) type_flag = 2;
        				else if (bt == SystemLibrary.SystemLibrary.uint_type) 
        				{
        					type_flag =2;
        					is_uint = true;
        				}
        				else if (bt.IsEnum) is_enum = true;
        			}
        			else if (param0.type.IsEnum) is_enum = true;
        		}
        		else throw new NoFunctionWithSameArguments(loc,false);
                if (type_flag != 5)
                {
                    if (param1 != null)
                        switch (type_flag)
                        {
                            case 0: param1 = convertion_data_and_alghoritms.convert_type(param1, SystemLibrary.SystemLibrary.integer_type); break;
                            case 3:
                            case 1: param1 = convertion_data_and_alghoritms.convert_type(param1, SystemLibrary.SystemLibrary.int64_type); break;
                            case 2: param1 = convertion_data_and_alghoritms.convert_type(param1, SystemLibrary.SystemLibrary.uint64_type); break;
                        }
                    //bfc.parameters.AddElement(param0);
                    if (param0.type != SystemLibrary.SystemLibrary.char_type && !is_enum && param0.type != SystemLibrary.SystemLibrary.bool_type)
                        switch (type_flag)
                        {
                            case 0: bfc.parameters.AddElement(convertion_data_and_alghoritms.convert_type(param0, SystemLibrary.SystemLibrary.integer_type)); break;
                            case 3:
                            case 1: bfc.parameters.AddElement(convertion_data_and_alghoritms.convert_type(param0, SystemLibrary.SystemLibrary.int64_type)); break;
                            case 2: bfc.parameters.AddElement(convertion_data_and_alghoritms.convert_type(param0, SystemLibrary.SystemLibrary.uint64_type)); break;
                        }
                    else bfc.parameters.AddElement(param0);
                    if (param1 == null)
                    {
                        if (type_flag == 0 || type_flag == 3)
                            bfc.parameters.AddElement(new int_const_node(1, null));
                        else if (type_flag == 1)
                            bfc.parameters.AddElement(new long_const_node(1, null));
                        else if (type_flag == 2)
                            bfc.parameters.AddElement(new ulong_const_node(1, null));
                    }
                    else bfc.parameters.AddElement(param1);
                    ass.parameters.AddElement(param0);
                    if (is_uint)
                        ass.parameters.AddElement(convertion_data_and_alghoritms.convert_type(bfc, SystemLibrary.SystemLibrary.uint_type));
                    else
                        ass.parameters.AddElement(bfc);
                }
        		return ass;
        	}
        	
        	throw new NoFunctionWithSameParametresNum(loc,false,si.sym_info as function_node);
        }
        private addressed_expression create_class_field_reference(expression_node en, definition_node dn, SyntaxTree.ident id_right)
        {
            try_convert_typed_expression_to_function_call(ref en);
            if (dn.semantic_node_type == semantic_node_type.class_field)
            {
                class_field cf = (class_field)dn;
                if (cf.polymorphic_state == SemanticTree.polymorphic_state.ps_static)
                {
                    AddError(new CanNotReferanceToStaticFieldWithExpression(cf, get_location(id_right), en));
                }
                class_field_reference cfr = new class_field_reference(cf, en, get_location(id_right));
                //return_value(cfr);
                return cfr;
            }
            if (dn.semantic_node_type == semantic_node_type.compiled_variable_definition)
            {
                compiled_variable_definition cfd = (compiled_variable_definition)dn;
                if (cfd.polymorphic_state == SemanticTree.polymorphic_state.ps_static)
                {
                    AddError(new CanNotReferanceToStaticFieldWithExpression(cfd, get_location(id_right), en));
                }
                compiled_variable_reference cfr2 = new compiled_variable_reference(cfd, en, get_location(id_right));
                //return_value(cfr2);
                return cfr2;
            }
#if (DEBUG)
            throw new CompilerInternalError("Invalid variable kind");
#endif
            return null;
        }
        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");

        }
        private expression_node make_dispose_call(SymbolInfo si, SyntaxTree.expression_list parameters, location loc)
        {
            if (parameters == null)
            {
                AddError(new NoFunctionWithSameParametresNum(loc, false, si.sym_info as function_node));
                return null;
            }
            if (parameters.expressions.Count == 1)
            {
                expression_node param0 = convert_strong(parameters.expressions[0]);
                if (!param0.type.IsPointer || param0.type == SystemLibrary.SystemLibrary.pointer_type)
                    AddError(new NoFunctionWithSameArguments(loc, true));
                if (!param0.is_addressed)
                {
                    bool is_pascal_array_ref = false;
                    if (param0.semantic_node_type == semantic_node_type.common_method_call)
                    {
                        common_method_call cmc = (common_method_call)param0;
                        internal_interface ii = cmc.obj.type.get_internal_interface(internal_interface_kind.bounded_array_interface);
                        if (ii != null)
                        {
                            if (cmc.function_node.name == compiler_string_consts.get_val_pascal_array_name)
                            {
                                bounded_array_interface bai = (bounded_array_interface)ii;
                                class_field cf = bai.int_array;
                                expression_node left = new class_field_reference(cf, cmc.obj, cmc.location);
                                expression_node right = cmc.parameters[0];
                                //right = convert_type(right, SystemLibrary.SystemLibrary.integer_type);
                                right = convertion_data_and_alghoritms.convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type);
                                right = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, right,
                                    new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value), cmc.location));
                                param0 = new simple_array_indexing(left, right, cmc.type, cmc.location);
                                is_pascal_array_ref = true;
                            }
                        }
                        if (!is_pascal_array_ref)
                        {
                            AddError(new ThisExpressionCanNotBePassedAsVarParameter(param0));
                            return null;
                        }

                    }
                    else
                    {
                        AddError(new ThisExpressionCanNotBePassedAsVarParameter(param0));
                        return null;
                    }
                }
                function_node fn = si.sym_info as function_node;
                common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node, loc);
                cnfc.parameters.AddElement(param0);
                return cnfc;

            }
            else
            {
                AddError(new NoFunctionWithSameParametresNum(loc, false, si.sym_info as function_node));
                return null;
            }
        }
 private void check_field_reference_for_assign(class_field_reference expr, location loc)
 {
 	if (expr.obj is namespace_constant_reference || expr.obj is function_constant_reference)
         AddError(loc, "LEFT_SIDE_CANNOT_BE_ASSIGNED_TO");
 	else if (expr.obj is class_field_reference) check_field_reference_for_assign(expr.obj as class_field_reference,loc);
 	else if (expr.obj is simple_array_indexing) check_expression_for_assign((expr.obj as simple_array_indexing).simple_arr_expr,loc);
 }
 internal function_node GenerateGetMethodForField(common_property_node cpn, string AcessorName, class_field cf, location loc)
 {
     SymbolInfo exist_si = context.find_only_in_namespace(AcessorName);
     if (exist_si != null && exist_si.sym_info.general_node_type != general_node_type.function_node)
     {
         AddError(loc, "CAN_NOT_GENERATE_ACCESSOR_{0}", AcessorName);
     }
     while (exist_si != null)
     {
         if (((function_node)(exist_si.sym_info)).parameters.Count == 0)
         {
             AddError(loc, "CAN_NOT_GENERATE_ACCESSOR_{0}", AcessorName);
         }
         exist_si = exist_si.Next;
     }
     common_method_node cmn = new common_method_node(
         AcessorName, loc, cf.cont_type,
         cf.polymorphic_state, context.get_field_access_level(), null);
     cpn.common_comprehensive_type.methods.AddElement(cmn);
     cmn.return_value_type = cf.type;
     cmn.is_overload = true;
     expression_node var_ref;
     if (cf.polymorphic_state == SemanticTree.polymorphic_state.ps_common)
     {
         var_ref = new class_field_reference(cf, new this_node(cf.type, loc), loc);
     }
     else
     {
         var_ref = new static_class_field_reference(cf, loc);
     }
     cmn.function_code = new return_node(var_ref, loc);
     cf.cont_type.scope.AddSymbol(AcessorName, new SymbolInfo(cmn));
     return cmn;
 }
        private void indexer_as_expression_index(expression_node expr, SyntaxTree.expression_list parameters,
            motivation mot, location loc)
        {
            try_convert_typed_expression_to_function_call(ref expr);

            // SSM 10.01.16 Tuple t[i]
            var ent = expr.type as compiled_type_node;

            if (ent== null)
            {
                var eeee = expr.type as compiled_generic_instance_type_node;
                if (eeee!= null)
                    ent = eeee.original_generic as compiled_type_node;
            }

            if (ent != null)
            {
                var t = ent.compiled_type;
                if (t.FullName.StartsWith("System.Tuple"))
                {
                    expression eee = parameters.expressions[0];

                    if (parameters.expressions.Count > 1)
                        AddError(get_location(eee), "TUPLE_CAN_HAVE_ONLY_ONE_INDEX");

                    var cn = convert_strong_to_constant_node(eee);

                    var v = cn as int_const_node;

                    if (v != null)
                    {
                        if (v.constant_value<0 || v.constant_value >= t.GetGenericArguments().Count())
                            AddError(cn.location, "TUPLE_INDEX_OUT_OF_RANGE_{0}", t.GetGenericArguments().Count()-1);
                        var dn = new dot_node(new semantic_addr_value(expr), new ident("Item" + (v.constant_value + 1).ToString(), eee.source_context),new SourceContext(loc.begin_line_num,loc.begin_column_num,loc.end_line_num,loc.end_column_num));
                        visit(dn);
                        return;
                    }
                    else AddError(cn.location, "TUPLE_INDEX_MUST_BE_INTEGER_CONSTANT");
                }
            }
            // end SSM 09.01.16 Tuple t[i]

            if (expr.type.type_special_kind == SemanticTree.type_special_kind.array_kind)
            {
                internal_interface ii = expr.type.get_internal_interface(internal_interface_kind.unsized_array_interface);
                array_internal_interface aii = (array_internal_interface)ii;
                int rank = aii.rank;
                //TODO: Многомерные массивы.
                expression_node ind_expr = convert_strong(parameters.expressions[0]);
                ind_expr = additional_indexer_convertion(ind_expr, expr.type);
                simple_array_indexing sai = new simple_array_indexing(expr, ind_expr, aii.element_type, loc);
                if (rank == 1)
                for (int i = 1; i < parameters.expressions.Count; i++)
                {
                    ii = sai.type.get_internal_interface(internal_interface_kind.unsized_array_interface);
                    location lloc = get_location(parameters.expressions[i]);
                    if (ii == null)
                    {
                        AddError(lloc, "{0}_DIMENSIONAL_ARRAY_CAN_NOT_HAVE_{1}_AND_MORE_INDEXING", i, i+1);
                    }
                    aii = (array_internal_interface)ii;
                    ind_expr = convert_strong(parameters.expressions[i]);
                    ind_expr = additional_indexer_convertion(ind_expr, sai.type);
                    sai = new simple_array_indexing(sai, ind_expr, aii.element_type, lloc);
                }
                else
                {
                    if (rank != parameters.expressions.Count)
                        AddError(get_location(parameters), "{0}_DIMENSIONAL_ARRAY_CAN_NOT_HAVE_{1}_AND_MORE_INDEXING", rank, rank + 1);
                	List<expression_node> lst = new List<expression_node>();
                	for (int i = 0; i < parameters.expressions.Count; i++)
                	{
                    	location lloc = get_location(parameters.expressions[i]);
                    	ind_expr = convert_strong(parameters.expressions[i]);
                    	ind_expr = additional_indexer_convertion(ind_expr, sai.type);
                    	lst.Add(ind_expr);
                	}
                	sai = new simple_array_indexing(expr, lst[0], aii.element_type, get_location(parameters));
                	sai.expr_indices = lst.ToArray();
                }
                switch (mot)
                {
                    case motivation.address_reciving:
                        {
                            return_addressed_value(sai);
                            break;
                        }
                    case motivation.expression_evaluation:
                        {
                            return_value(sai);
                            break;
                        }
                    case motivation.semantic_node_reciving:
                        {
                            return_semantic_value(sai);
                            break;
                        }
                }
                return;
            }
            else if (expr.type.type_special_kind == SemanticTree.type_special_kind.short_string)
            {
            	if (parameters.expressions.Count != 1)
                    AddError(loc, "INVALID_PARAMETER_COUNT_IN_INDEXER");
            	expression_node ind_expr = convert_strong(parameters.expressions[0]);
            	ind_expr = additional_indexer_convertion(ind_expr, expr.type);
            	//expression_node en = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.GetCharInShortStringProcedure.sym_info as function_node,loc,ind_expr,new int_const_node((expr.type as short_string_type_node).Length,null));
            	switch (mot)
                {
                    case motivation.address_reciving:
                        {
                            simple_array_indexing sai = new simple_array_indexing(expr, ind_expr, SystemLibrary.SystemLibrary.char_type, loc);
                            return_addressed_value(sai);
                            //return_addressed_value(convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.SetCharInShortStringProcedure.sym_info as function_node,loc,expr,ind_expr) as common_namespace_function_call);
                            break;
                        }
                    case motivation.expression_evaluation:
                        {
            				return_value(convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.GetCharInShortStringProcedure.sym_info as function_node,loc,expr,ind_expr,new int_const_node((expr.type as short_string_type_node).Length,null)));
                            break;
                        }
                    case motivation.semantic_node_reciving:
                        {
            				return_semantic_value(convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.GetCharInShortStringProcedure.sym_info as function_node,loc,expr,ind_expr,new int_const_node((expr.type as short_string_type_node).Length,null)));
                            break;
                        }
                }
                return;
            	
            }
            /*else if (expr.type.type_special_kind == SemanticTree.type_special_kind.array_wrapper)
            {
            	internal_interface ii = expr.type.get_internal_interface(internal_interface_kind.bounded_array_interface);
                array_internal_interface aii = (array_internal_interface)ii;
                //TODO: Многомерные массивы.
                expression_node ind_expr = convert_strong(parameters.expressions[0]);
                ind_expr = additional_indexer_convertion(ind_expr, expr.type);
                simple_array_indexing sai = new simple_array_indexing(expr, ind_expr, aii.element_type, loc);
                for (int i = 1; i < parameters.expressions.Count; i++)
                {
                    ii = sai.type.get_internal_interface(internal_interface_kind.bounded_array_interface);
                    location lloc = get_location(parameters.expressions[i]);
                    if (ii == null)
                    {
                        throw new NDimensionalArrayCanNotHaveNPlusOneIndexer(lloc, expr, i);
                    }
                    aii = (array_internal_interface)ii;
                    ind_expr = convert_strong(parameters.expressions[i]);
                    ind_expr = create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, ind_expr,
                                            new int_const_node(ii.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value),cmc.location));
                    ind_expr = additional_indexer_convertion(ind_expr, sai.type);
                    sai = new simple_array_indexing(sai, ind_expr, aii.element_type, lloc);
                }
                switch (mot)
                {
                    case motivation.address_reciving:
                        {
                            return_addressed_value(sai);
                            break;
                        }
                    case motivation.expression_evaluation:
                        {
                            return_value(sai);
                            break;
                        }
                    case motivation.semantic_node_reciving:
                        {
                            return_semantic_value(sai);
                            break;
                        }
                }
                return;
                
                 if (factparams[i].semantic_node_type == semantic_node_type.common_method_call)
                            {
                                common_method_call cmc = (common_method_call)factparams[i];
                                internal_interface ii = cmc.obj.type.get_internal_interface(internal_interface_kind.bounded_array_interface);
                                if (ii != null)
                                {
                                    if (cmc.function_node.name == compiler_string_consts.get_val_pascal_array_name)
                                    {
                                        bounded_array_interface bai = (bounded_array_interface)ii;
                                        class_field cf = bai.int_array;
                                        expression_node left = new class_field_reference(cf, cmc.obj, cmc.location);
                                        expression_node right = cmc.parameters[0];
                                        //right = convert_type(right, SystemLibrary.SystemLibrary.integer_type);
                                        right = convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type);
                                        right = create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, right,
                                            new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value),cmc.location));
                                        factparams[i] = new simple_array_indexing(left, right, cmc.type, cmc.location);
                                        is_pascal_array_ref = true;
                                    }
                                }
                            }
            }*/
            if (expr.type.default_property_node == null)
            {
                if (expr.type.semantic_node_type != semantic_node_type.delegated_method)
                {
                    AddError(loc, "NO_DEFAULT_PROPERTY_TO_TYPE_{0}", expr.type.PrintableName);
                }
                else
                {
                    AddError(loc, "NO_DEFAULT_PROPERTY_TO_FUNCTION_TYPE");
                }
            }

            if (expr.type.default_property_node.polymorphic_state == SemanticTree.polymorphic_state.ps_static)
            {
                AddError(new CanNotReferenceToStaticPropertyWithExpression(expr.type.default_property_node, loc, expr.type));
            }
            non_static_property_reference nspr = new non_static_property_reference(expr.type.default_property_node, expr, loc);
            indexer_as_property_indexes(nspr, parameters, mot, loc);
            //eto vrode rabotaet normalno. no imet v vidu
            if (expr.type.type_special_kind == SemanticTree.type_special_kind.array_wrapper)
            {
            	expression_node en = ret.get_expression();
                if (en is non_static_property_reference)
                {
                    non_static_property_reference cmc = (non_static_property_reference)en;
                    internal_interface ii = cmc.expression.type.get_internal_interface(internal_interface_kind.bounded_array_interface);
                    if (ii != null)
                    {
                        //if (cmc.function_node.name == compiler_string_consts.get_val_pascal_array_name)
                        {
                            bounded_array_interface bai = (bounded_array_interface)ii;
                            class_field cf = bai.int_array;
                            expression_node left = new class_field_reference(cf, cmc.expression, cmc.location);
                            expression_node right = cmc.fact_parametres[0];
                            //right = convert_type(right, SystemLibrary.SystemLibrary.integer_type);
                            right = convertion_data_and_alghoritms.convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type);
                            right = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, right,
                                                new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value), cmc.location));
                            en = new simple_array_indexing(left, right, cmc.type, cmc.location);
                            //is_pascal_array_ref = true;
                        }
                    }
                }
                else
                {
                    common_method_call cmc = (common_method_call)en;
                    internal_interface ii = cmc.obj.type.get_internal_interface(internal_interface_kind.bounded_array_interface);
                    if (ii != null)
                    {
                        //if (cmc.function_node.name == compiler_string_consts.get_val_pascal_array_name)
                        {
                            bounded_array_interface bai = (bounded_array_interface)ii;
                            class_field cf = bai.int_array;
                            expression_node left = new class_field_reference(cf, cmc.obj, cmc.location);
                            expression_node right = cmc.parameters[0];
                            //right = convert_type(right, SystemLibrary.SystemLibrary.integer_type);
                            right = convertion_data_and_alghoritms.convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type);
                            right = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, right,
                                                new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value), cmc.location));
                            en = new simple_array_indexing(left, right, cmc.type, cmc.location);
                            //is_pascal_array_ref = true;
                        }
                    }
                }
                return_value(en);
            }
            
            return;
        }
        /// <summary>
        /// Возвращает список преобразований типов для вызова метода.
        /// </summary>
        /// <param name="factparams">Список фактических параметров.</param>
        /// <param name="formalparams">Список формальных параметров.</param>
        /// <param name="is_alone_method_defined">Для единственного метода у которого типы параметров совпадают, но в качестве var параметра мы передаем константное значение мы можем сгенерировать более подробное сообщение об ошибке.</param>
        /// <returns>Список преобразований типов.</returns>
        internal possible_type_convertions_list get_conversions(expressions_list factparams,
			parameter_list formalparams,bool is_alone_method_defined, location locg)
		{
			//TODO:Явно указывать capacity при создании.
            possible_type_convertions_list tc = new possible_type_convertions_list();
			
			possible_type_convertions ptc;

            if (factparams.Count>formalparams.Count)
            {
                if ( (formalparams.Count==0) || (!(formalparams[formalparams.Count-1].is_params)) )
                {
                    return null;
                }
            }

            type_node for_par_type = null;
            array_internal_interface aii=null;
            if (formalparams.Count > 0)
            {
                parameter pr=formalparams[formalparams.Count - 1];
                if (pr.is_params && 
                    //это для возможности вызова сразу с массивом[], типа просто не обращаем внимаение на params
                    !(factparams.Count == formalparams.Count && factparams[factparams.Count - 1].type == formalparams[formalparams.Count - 1].type))
                {
                    //TODO: Добавить проверку на правильность.
                    aii = (array_internal_interface)
                        pr.type.get_internal_interface(internal_interface_kind.unsized_array_interface);
                    for_par_type = aii.element_type;

                    tc.snl = new statement_node_list();

                    location loc=null;
                    if (factparams.Count > 0) loc = factparams[factparams.Count-1].location;
                    //var_definition_node vdn=syntax_tree_visitor.context.add_var_definition_in_entry_scope(get_temp_arr_name(),loc);
                    var_definition_node vdn = null;
                    if (syntax_tree_visitor.context.converted_func_stack.size > 0)
                    {
                        common_function_node cfn = syntax_tree_visitor.context.converted_func_stack.first();
                        if (cfn.is_generic_function)
                        {
                            vdn = syntax_tree_visitor.context.add_var_definition(get_temp_arr_name(), loc);
                        }
                        else
                            vdn = syntax_tree_visitor.context.add_var_definition_in_entry_scope(get_temp_arr_name(), loc);
                        
                    }
                    else if (syntax_tree_visitor.context.converted_type != null)
                        vdn = syntax_tree_visitor.context.add_field(get_temp_arr_name(), loc, pr.type, polymorphic_state.ps_static);
                    else
                        vdn = syntax_tree_visitor.context.add_var_definition_in_entry_scope(get_temp_arr_name(), loc);
                    syntax_tree_visitor.context.close_var_definition_list(pr.type,null);
                    
                    expression_node fst=null;
                    /*switch (syntax_tree_visitor.context.converting_block())
                    {
                        case block_type.function_block:
                            {
                                fst=new local_variable_reference((local_variable)vdn,0,loc);
                                break;
                            }
                        case block_type.namespace_block:
                            {
                                fst=new namespace_variable_reference((namespace_variable)vdn,loc);
                                break;
                            }
                    }*/
                    switch (vdn.semantic_node_type)
                    {
                        case semantic_node_type.local_variable:
                            {
                                fst = new local_variable_reference((local_variable)vdn, 0, loc);
                                break;
                            }
                        case semantic_node_type.namespace_variable:
                            {
                                fst = new namespace_variable_reference((namespace_variable)vdn, loc);
                                break;
                            }
                        case semantic_node_type.local_block_variable:
                            {
                                fst = new local_block_variable_reference((local_block_variable)vdn, loc);
                                break;
                            }
                        case semantic_node_type.class_field:
                            {
                                class_field cf = vdn as class_field;
                                cf.polymorphic_state = polymorphic_state.ps_static;
                                fst = new static_class_field_reference(cf, loc);
                                break;
                            }
                        default:
                            throw new CompilerInternalError("Invalid node type");
                    }

                    tc.var_ref = fst;

                    int del=factparams.Count-formalparams.Count+1;
                    int_const_node icn=new int_const_node(del,loc);

                    expression_node bfc = create_simple_function_call(SystemLibrary.SystemLibrary.resize_func,
                        loc, fst, icn);
                    tc.snl.AddElement(bfc);
                    /*if (factparams.Count == 0)
                    {
                    	possible_type_convertions ptci=new possible_type_convertions();
						ptci.first=null;
						ptci.second=null;
						ptci.from=null;
                    	ptci.to = for_par_type;
						tc.AddElement(ptci);
                    }*/
                }
            }
			
			for(int i=0;i<factparams.Count;i++)
			{
                type_node formal_param_type = null;
                if ((for_par_type!=null)&&(i >= formalparams.Count-1))
                {
                    formal_param_type = for_par_type;
                }
                else
                {
                    formal_param_type = formalparams[i].type;
                }
                if (possible_equal_types(factparams[i].type, formal_param_type))
				{
					if ((i<formalparams.Count)&&(formalparams[i].parameter_type==SemanticTree.parameter_type.var))
					{
                        bool is_pascal_array_ref = false;
                        bool is_ok = false;
						if (factparams[i].is_addressed==false)
						{
                            if (factparams[i].semantic_node_type == semantic_node_type.common_method_call)
                            {
                                common_method_call cmc = (common_method_call)factparams[i];
                                internal_interface ii = cmc.obj.type.get_internal_interface(internal_interface_kind.bounded_array_interface);
                                if (ii != null)
                                {
                                    if (cmc.function_node.name == compiler_string_consts.get_val_pascal_array_name)
                                    {
                                        bounded_array_interface bai = (bounded_array_interface)ii;
                                        class_field cf = bai.int_array;
                                        expression_node left = new class_field_reference(cf, cmc.obj, cmc.location);
                                        expression_node right = cmc.parameters[0];
                                        //right = convert_type(right, SystemLibrary.SystemLibrary.integer_type);
                                        right = convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type);
                                        right = create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, right,
                                            new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value),cmc.location));
                                        factparams[i] = new simple_array_indexing(left, right, cmc.type, cmc.location);
                                        is_pascal_array_ref = true;
                                    }
                                }
                            }
                            if (!is_pascal_array_ref)
                            {
                                //Если мы попали сюда, то мы пытаемся передать по ссылке значение,
                                //которое не мохет быть передано по ссылке. Например, передать
                                //по ссылки из одной функции в другую константный параметр.
                                if (is_alone_method_defined)
                                {
                                    if (syntax_tree_visitor.assign_is_converting)
                                    {
                                        AddError(factparams[i].location, "CAN_NOT_ASSIGN_TO_LEFT_PART");
                                    }
                                    else
                                    {
                                        if (formalparams[i] is common_parameter && (formalparams[i] as common_parameter).concrete_parameter_type == concrete_parameter_type.cpt_const /*&& factparams[i] is common_parameter_reference*/)
                                        {
                                            is_ok = true;
                                        }
                                        else if (formalparams[i] is common_parameter && (formalparams[i] as common_parameter).concrete_parameter_type == concrete_parameter_type.cpt_const)
                                            ;
                                        //throw new ThisExpressionCanNotBePassedAsConstParameter(factparams[i].location);
                                        else if (is_string_getter(factparams[i]))
                                        {
                                            if (factparams[i] is compiled_function_call)
                                                factparams[i] = make_unmanaged_string_getter(factparams[i] as compiled_function_call);
                                            else
                                                factparams[i] = make_unmanaged_shortstring_getter(factparams[i] as base_function_call);
                                            is_ok = true;
                                        }

                                        else
                                            AddError(new ThisExpressionCanNotBePassedAsVarParameter(factparams[i]));
                                    }
                                }
                                else if (is_string_getter(factparams[i]))
                                {
                                    if (factparams[i] is compiled_function_call)
                                        factparams[i] = make_unmanaged_string_getter(factparams[i] as compiled_function_call);
                                    else
                                        factparams[i] = make_unmanaged_shortstring_getter(factparams[i] as base_function_call);
                                    is_ok = true;
                                }

                                if (!is_ok)
                                    return null;
                            }
						}
					}
					//Разобраться: может лучше добавлять null к списку.
					possible_type_convertions ptci=new possible_type_convertions();
					ptci.first=null;
					ptci.second=null;
					ptci.from=factparams[i].type;
                    ptci.to = formal_param_type;
					tc.AddElement(ptci);

                    if ((for_par_type != null) && (i >= formalparams.Count - 1))
                    {
                        expression_node to = new simple_array_indexing(tc.var_ref,//factparams[formalparams.Count - 1],
                            new int_const_node(i - formalparams.Count + 1, factparams[i].location), aii.element_type, factparams[i].location);
                        expression_node from = factparams[i];
                        statement_node stat = syntax_tree_visitor.find_operator(compiler_string_consts.assign_name, to, from, factparams[i].location);
                        tc.snl.AddElement(stat);
                    }

					continue;
				}
				if ((i<formalparams.Count)&&(formalparams[i].parameter_type==SemanticTree.parameter_type.var))
				{
					return null;
				}
				else
				{
                    ptc = type_table.get_convertions(factparams[i].type, formal_param_type);
					if (ptc.first==null)
					{
                        if (type_table.is_derived(formal_param_type, factparams[i].type))
						{
							possible_type_convertions ptci=new possible_type_convertions();
							ptci.first=null;
							ptci.second=null;
							ptci.from=factparams[i].type;
                            ptci.to = formal_param_type;
							tc.AddElement(ptci);

                            if ((for_par_type != null) && (i >= formalparams.Count - 1))
                            {
                                expression_node to = new simple_array_indexing(tc.var_ref,//factparams[formalparams.Count - 1],
                                    new int_const_node(i - formalparams.Count + 1, factparams[i].location), aii.element_type, factparams[i].location);
                                expression_node from = factparams[i];
                                statement_node stat = syntax_tree_visitor.find_operator(compiler_string_consts.assign_name, to, from, factparams[i].location);
                                tc.snl.AddElement(stat);
                            }

						}
						else
						{
                            if (is_alone_method_defined)
                            {
                                AddError(new CanNotConvertTypes(factparams[i], factparams[i].type, formal_param_type, locg));
                            }
							return null;
                            
						}
					}
					else
					{
						tc.AddElement(ptc);
                        if ((for_par_type != null) && (i >= formalparams.Count - 1))
                        {
                            expression_node to = new simple_array_indexing(tc.var_ref,//factparams[formalparams.Count - 1],
                                new int_const_node(i - formalparams.Count + 1, factparams[i].location), aii.element_type, factparams[i].location);
                            expression_node from = create_simple_function_call(ptc.first.convertion_method,
                                factparams[i].location, factparams[i]);
                            statement_node stat = syntax_tree_visitor.find_operator(compiler_string_consts.assign_name, to, from, factparams[i].location);
                            tc.snl.AddElement(stat);
                        }
					}
				}
			}
            if (tc.snl != null)
            foreach (statement_node sn in tc.snl)
                sn.location = null;
			return tc;
		}
 private void add_equal_operator_if_need()
 {
 	SymbolInfo si = _ctn.find_in_type(compiler_string_consts.eq_name);
 	if (si.sym_info is common_method_node)
 		return;
 	SymbolTable.ClassMethodScope scope = convertion_data_and_alghoritms.symbol_table.CreateClassMethodScope(_cmn.scope,_ctn.scope);
 	common_method_node cmn = new common_method_node(compiler_string_consts.GetNETOperName(compiler_string_consts.eq_name),SystemLibrary.SystemLibrary.bool_type,null,_ctn,
 	                                                SemanticTree.polymorphic_state.ps_static,SemanticTree.field_access_level.fal_public,scope);
 	cmn.IsOperator = true;
 	common_parameter prm1 = new common_parameter("a",_ctn,SemanticTree.parameter_type.value,cmn,concrete_parameter_type.cpt_none,null,null);
 	common_parameter prm2 = new common_parameter("b",_ctn,SemanticTree.parameter_type.value,cmn,concrete_parameter_type.cpt_none,null,null);
 	cmn.parameters.AddElement(prm1);
 	cmn.parameters.AddElement(prm2);
 	statements_list body = new statements_list(null);
 	foreach (class_field cf in _ctn.fields)
 	{
 		expression_node left = new class_field_reference(cf,new common_parameter_reference(prm1,0,null),null);
 		expression_node right = new class_field_reference(cf,new common_parameter_reference(prm2,0,null),null);
 		expression_node cond = SystemLibrary.SystemLibrary.syn_visitor.find_operator(compiler_string_consts.eq_name,
 		                                                                            left,right,null);
 		basic_function_call bfc = new basic_function_call(SystemLibrary.SystemLibrary.bool_not as basic_function_node,null);
 		bfc.parameters.AddElement(cond);
 		if_node if_stmt = new if_node(bfc,new return_node(new bool_const_node(false,null),null),null,null);
 		body.statements.AddElement(if_stmt);
 	}
 	body.statements.AddElement(new return_node(new bool_const_node(true,null),null));
 	cmn.function_code = body;
 	cmn.is_overload = true;
 	_ctn.methods.AddElement(cmn);
 	_ctn.Scope.AddSymbol(compiler_string_consts.eq_name,new SymbolInfo(cmn));
 }
        public common_event add_event_definition(string name, location loc, type_node tn, SemanticTree.polymorphic_state ps, bool is_abstract)
        {
            class_field cf = new class_field(name + "$", tn, converted_type, ps, _fal, loc);
            common_event ce = new common_event(name, tn, converted_type, null, null, null, _fal, ps, loc);
            //add
            common_method_node add_meth = new common_method_node(compiler_string_consts.GetAddHandler(name), null, this.converted_type,
                                                                 ps, SemanticTree.field_access_level.fal_public, null);
            common_parameter cp = new common_parameter("value", tn, SemanticTree.parameter_type.value, add_meth, concrete_parameter_type.cpt_none, null, null);
            add_meth.parameters.AddElement(cp);
            expression_node fld_ref = null;
            if (!cf.IsStatic) fld_ref = new class_field_reference(cf, new this_node(converted_type, null), null);
            else fld_ref = new static_class_field_reference(cf, null);
            expression_node en = this.syntax_tree_visitor.convertion_data_and_alghoritms.type_constructor.delegate_add_assign_compile_time_executor
                (null, new expression_node[2] { fld_ref, new common_parameter_reference(cp, 0, null) });

            if (!is_abstract)
            {
                add_meth.function_code = new statements_list(null);
                (add_meth.function_code as statements_list).statements.AddElement(en);
            }
            converted_type.scope.AddSymbol(add_meth.name, new SymbolInfo(add_meth));
            //remove
            common_method_node remove_meth = new common_method_node(compiler_string_consts.GetRemoveHandler(name), null, this.converted_type,
                                                                 ps, SemanticTree.field_access_level.fal_public, null);

            cp = new common_parameter("value", tn, SemanticTree.parameter_type.value, add_meth, concrete_parameter_type.cpt_none, null, null);
            remove_meth.parameters.AddElement(cp);
            en = this.syntax_tree_visitor.convertion_data_and_alghoritms.type_constructor.delegate_sub_assign_compile_time_executor
                (null, new expression_node[2] { fld_ref, new common_parameter_reference(cp, 0, null) });
            if (!is_abstract)
            {
                remove_meth.function_code = new statements_list(null);
                (remove_meth.function_code as statements_list).statements.AddElement(en);
            }
            converted_type.scope.AddSymbol(remove_meth.name, new SymbolInfo(remove_meth));
            this.converted_type.methods.AddElement(add_meth);
            this.converted_type.methods.AddElement(remove_meth);
            ce.set_add_method(add_meth);
            ce.set_remove_method(remove_meth);
            ce.field = cf;
            this.converted_type.events.AddElement(ce);
            if (!is_abstract)
                this.converted_type.fields.AddElement(cf);
            converted_type.scope.AddSymbol(name, new SymbolInfo(ce));
            return ce;
        }
Пример #15
0
		private type_node create_array_type(ordinal_type_interface oti_indexer, type_node element_type,common_namespace_node _cmn, location loc)
		{
			int arr_length = oti_indexer.ordinal_type_to_int(oti_indexer.upper_value) -
				oti_indexer.ordinal_type_to_int(oti_indexer.lower_value) + 1;

			if (arr_length <= 0)
			{
				throw new SimpleSemanticError(loc, "NEGATIVE_ARRAY_LENGTH_({0})_NOT_ALLOWED", arr_length);
			}

			simple_array sa = new simple_array(element_type, arr_length);
			//sa.length = arr_length;
			//sa.element_type = element_type;

			SymbolTable.Scope top_scope = null;
			if (_cmn != null)
			{
				top_scope = _cmn.scope;
			}
			string name = get_pascal_array_name();
			//if (_cmn.namespace_name != null)
			//    name = _cmn.namespace_name + name;
			common_type_node ctn = new common_type_node(null, name, SemanticTree.type_access_level.tal_public,
			                                            _cmn, convertion_data_and_alghoritms.symbol_table.CreateClassScope(top_scope, null), loc);

			ctn.SetBaseType(SystemLibrary.SystemLibrary.object_type);
			//DarkStar Add
			//loc не нужно мне это!  и некому не нужно!
			//loc = null;
			
			//ctn.internal_is_value = true;

			class_constant_definition cdn1 = new class_constant_definition(compiler_string_consts.lower_array_const_name,
			                                                               oti_indexer.lower_value, loc, ctn, SemanticTree.field_access_level.fal_public);
			ctn.scope.AddSymbol(cdn1.name, new SymbolInfo(cdn1));

			class_constant_definition cdn2 = new class_constant_definition(compiler_string_consts.upper_array_const_name,
			                                                               oti_indexer.upper_value, loc, ctn, SemanticTree.field_access_level.fal_public);
			ctn.scope.AddSymbol(cdn2.name, new SymbolInfo(cdn2));

			class_field int_arr = new class_field(compiler_string_consts.internal_array_name, sa, ctn,
			                                      SemanticTree.polymorphic_state.ps_common, SemanticTree.field_access_level.fal_public,loc);
			ctn.scope.AddSymbol(int_arr.name, new SymbolInfo(int_arr));
			ctn.fields.AddElement(int_arr);

			SystemLibrary.SystemLibrary.init_reference_type(ctn);

			ctn.const_defs.AddElement(cdn1);
			ctn.const_defs.AddElement(cdn2);

			common_method_node get_func = new common_method_node(compiler_string_consts.get_val_pascal_array_name,
			                                                     element_type, /*loc*/new location(0xFFFFFF, 0, 0xFFFFFF, 0, loc.doc), ctn, SemanticTree.polymorphic_state.ps_common, SemanticTree.field_access_level.fal_private,
			                                                     convertion_data_and_alghoritms.symbol_table.CreateScope(ctn.scope));
			common_parameter get_param = new common_parameter(compiler_string_consts.unary_param_name,
			                                                  oti_indexer.lower_value.type, SemanticTree.parameter_type.value, get_func, concrete_parameter_type.cpt_none,
			                                                  null, loc);
			get_func.parameters.AddElement(get_param);

			common_parameter_reference cpr = new common_parameter_reference(get_param, 0, loc);
			expression_node en1 = convertion_data_and_alghoritms.create_simple_function_call(oti_indexer.value_to_int,
			                                                                                 loc, cpr);
			expression_node en2 = new int_const_node(oti_indexer.ordinal_type_to_int(oti_indexer.lower_value), loc);
			expression_node sub_expr = convertion_data_and_alghoritms.create_simple_function_call(
				SystemLibrary.SystemLibrary.int_sub, loc, en1, en2);

			this_node thisnode = new this_node(ctn, loc);

			class_field_reference cfr1 = new class_field_reference(int_arr, thisnode, loc);

			expression_node index_expr = new simple_array_indexing(cfr1, sub_expr, element_type, loc);

			statement_node sn = new return_node(index_expr, /*loc*/new location(0xFFFFFF, 0, 0xFFFFFF, 0, loc.doc));

			get_func.function_code = sn;

			common_method_node set_func = new common_method_node(compiler_string_consts.set_val_pascal_array_name,
			                                                     null, /*loc*/new location(0xFFFFFF, 0, 0xFFFFFF, 0, loc.doc), ctn, SemanticTree.polymorphic_state.ps_common, SemanticTree.field_access_level.fal_private,
			                                                     convertion_data_and_alghoritms.symbol_table.CreateScope(ctn.scope));
			common_parameter set_ind = new common_parameter(compiler_string_consts.left_param_name,
			                                                oti_indexer.lower_value.type, SemanticTree.parameter_type.value, set_func, concrete_parameter_type.cpt_none,
			                                                null, loc);
			set_func.parameters.AddElement(set_ind);
			common_parameter set_val = new common_parameter(compiler_string_consts.right_param_name,
			                                                element_type, SemanticTree.parameter_type.value, set_func, concrete_parameter_type.cpt_none, null, loc);
			set_func.parameters.AddElement(set_val);

			common_parameter_reference cpr2 = new common_parameter_reference(set_ind, 0, loc);
			expression_node en3 = convertion_data_and_alghoritms.create_simple_function_call(oti_indexer.value_to_int,
			                                                                                 loc, cpr2);
			expression_node en4 = new int_const_node(oti_indexer.ordinal_type_to_int(oti_indexer.lower_value), loc);
			expression_node sub_expr2 = convertion_data_and_alghoritms.create_simple_function_call(
				SystemLibrary.SystemLibrary.int_sub, loc, en3, en4);

			class_field_reference cfr2 = new class_field_reference(int_arr, thisnode, loc);

			expression_node index_expr2 = new simple_array_indexing(cfr2, sub_expr2, element_type,loc);

			SymbolInfo si = element_type.find_in_type(compiler_string_consts.assign_name);
			if (si == null)
			{
				throw new NotSupportedError(loc);
				throw new CompilerInternalError("Varable of this type can not be assigned");
			}
			if (si.sym_info.general_node_type != general_node_type.function_node)
			{
				throw new CompilerInternalError("Invalid assign operator");
			}

			expression_node val_ref = new common_parameter_reference(set_val, 0, loc);

			function_node assign = (function_node)si.sym_info;
			statement_node assign_call = convertion_data_and_alghoritms.create_simple_function_call(assign,
			                                                                                        /*loc*/new location(0xFFFFFF, 0, 0xFFFFFF, 0, loc.doc), index_expr2, val_ref);

			set_func.function_code = assign_call;

			ctn.methods.AddElement(get_func);
			ctn.methods.AddElement(set_func);

			common_property_node cpn = new common_property_node(compiler_string_consts.index_property_pascal_array_name,
			                                                    ctn, element_type, get_func, set_func, loc, SemanticTree.field_access_level.fal_public, SemanticTree.polymorphic_state.ps_common);

			common_parameter prop_cp = new common_parameter(compiler_string_consts.unary_param_name, oti_indexer.lower_value.type,
			                                                SemanticTree.parameter_type.value, null, concrete_parameter_type.cpt_none, null, loc);
			cpn.parameters.AddElement(prop_cp);

			ctn.properties.AddElement(cpn);

			ctn.default_property = cpn;

			if (_cmn != null)
			{
				_cmn.types.AddElement(ctn);
			}

			bounded_array_interface bai = new bounded_array_interface(oti_indexer, element_type, cpn, oti_indexer.lower_value.type, int_arr);
			ctn.add_internal_interface(bai);
			ctn.type_special_kind = SemanticTree.type_special_kind.array_wrapper;

            if (element_type.type_special_kind != SemanticTree.type_special_kind.array_wrapper)
            {
                ctn.ImplementingInterfaces.Add(compiled_type_node.get_type_node(NetHelper.NetHelper.FindType(compiler_string_consts.IEnumerableInterfaceName)));
                common_method_node en_cmn = new common_method_node(compiler_string_consts.GetEnumeratorMethodName, compiled_type_node.get_type_node(NetHelper.NetHelper.FindType(compiler_string_consts.IEnumeratorInterfaceName)), null, ctn, SemanticTree.polymorphic_state.ps_virtual, SemanticTree.field_access_level.fal_public, null);

                compiled_function_node en_fnc = NetHelper.NetHelper.FindName(NetHelper.NetHelper.FindType(compiler_string_consts.IEnumerableInterfaceName), compiler_string_consts.GetEnumeratorMethodName).sym_info as compiled_function_node;
                statements_list sl = new statements_list(null);
                sl.statements.AddElement(new return_node(
                    new compiled_function_call(en_fnc, new class_field_reference(int_arr, new this_node(ctn, null), null), null), null));
                en_cmn.function_code = sl;
                en_cmn.newslot_awaited = true;
                ctn.methods.AddElement(en_cmn);

                if (!element_type.IsPointer)
                {
                    List<type_node> generic_args = new List<type_node>();
                    generic_args.Add(element_type);
                    type_node en_tn = compiled_type_node.get_type_node(NetHelper.NetHelper.FindType(compiler_string_consts.IGenericEnumerableInterfaceName)).get_instance(generic_args);
                    ctn.ImplementingInterfaces.Add(en_tn);

                    en_cmn = new common_method_node(compiler_string_consts.GetEnumeratorMethodName, compiled_type_node.get_type_node(NetHelper.NetHelper.FindType(compiler_string_consts.IGenericEnumeratorInterfaceName)).get_instance(generic_args), null, ctn, SemanticTree.polymorphic_state.ps_virtual, SemanticTree.field_access_level.fal_public, null);
                    //en_fnc = en_tn.find_in_type("GetEnumerator").sym_info as function_node;//NetHelper.NetHelper.FindName(NetHelper.NetHelper.FindType(compiler_string_consts.IGenericEnumerableInterfaceName), compiler_string_consts.GetEnumeratorMethodName).sym_info as compiled_function_node;
                    SymbolInfo en_si = en_tn.find_in_type("GetEnumerator");
                    if (en_si.Next != null && (en_si.Next.sym_info as function_node).return_value_type.is_generic_type_instance)
                        en_si = en_si.Next;
                    function_node en_fnc_inst = en_si.sym_info as function_node; ;//.get_instance(generic_args, true, loc);
                    sl = new statements_list(null);
                    if (en_fnc_inst is compiled_function_node)
                        sl.statements.AddElement(new return_node(
                            new compiled_function_call(en_fnc_inst as compiled_function_node, new class_field_reference(int_arr, new this_node(ctn, null), null), null), null));
                    else
                        sl.statements.AddElement(new return_node(
                            new common_method_call(en_fnc_inst as common_method_node, new class_field_reference(int_arr, new this_node(ctn, null), null), null), null));
                    en_cmn.function_code = sl;
                    en_cmn.newslot_awaited = true;
                    ctn.methods.AddElement(en_cmn);
                }
            }
			
			//= operation
			SymbolTable.ClassMethodScope scope = convertion_data_and_alghoritms.symbol_table.CreateClassMethodScope(_cmn.scope,ctn.scope);
        	common_method_node cmn_eq = new common_method_node(compiler_string_consts.GetNETOperName(compiler_string_consts.eq_name),SystemLibrary.SystemLibrary.bool_type,null,ctn,
        	                                                SemanticTree.polymorphic_state.ps_static,SemanticTree.field_access_level.fal_public,scope);
        	cmn_eq.IsOperator = true;
        	common_parameter prm1 = new common_parameter("a",ctn,SemanticTree.parameter_type.value,cmn_eq,concrete_parameter_type.cpt_none,null,null);
        	common_parameter prm2 = new common_parameter("b",ctn,SemanticTree.parameter_type.value,cmn_eq,concrete_parameter_type.cpt_none,null,null);
        	cmn_eq.parameters.AddElement(prm1);
        	cmn_eq.parameters.AddElement(prm2);
        	statements_list body = new statements_list(null);
        	local_variable vdn = new local_variable("$i",SystemLibrary.SystemLibrary.integer_type,cmn_eq,null);//this.convertion_data_and_alghoritms.syntax_tree_visitor.context.create_for_temp_variable(SystemLibrary.SystemLibrary.integer_type, null);
        	cmn_eq.var_definition_nodes_list.AddElement(vdn);
        	expression_node var_ref = new local_variable_reference(vdn,0,null);//this.convertion_data_and_alghoritms.syntax_tree_visitor.create_variable_reference(vdn,null);
        	basic_function_call cond = new basic_function_call(SystemLibrary.SystemLibrary.int_sm as basic_function_node,null);
        	cond.parameters.AddElement(var_ref);
        	cond.parameters.AddElement(new int_const_node(arr_length,null));
        	while_node while_stmt = new while_node(cond,null);
        	statements_list while_body = new statements_list(null);
        	while_stmt.body = while_body;
        	simple_array_indexing left_sar = new simple_array_indexing(new class_field_reference(int_arr, new common_parameter_reference(prm1,0,null), null),var_ref,element_type,null);
        	simple_array_indexing right_sar = new simple_array_indexing(new class_field_reference(int_arr, new common_parameter_reference(prm2,0,null), null),var_ref,element_type,null);
        	expression_node cond2 = SystemLibrary.SystemLibrary.syn_visitor.find_operator(compiler_string_consts.noteq_name,
        		                                                                            left_sar,right_sar,null);
        	if_node if_stmt = new if_node(cond2,new return_node(new bool_const_node(false,null),null),null,null);
        	while_body.statements.AddElement(if_stmt);
        	while_body.statements.AddElement(new basic_function_call(SystemLibrary.SystemLibrary.int_assign as basic_function_node,null
        	                                                   ,var_ref,new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node,null,var_ref,new int_const_node(1,null))));
        	
        	body.statements.AddElement(while_stmt);
        	body.statements.AddElement(new return_node(new bool_const_node(true,null),null));
        	cmn_eq.function_code = body;
        	cmn_eq.is_overload = true;
        	ctn.methods.AddElement(cmn_eq);
        	ctn.Scope.AddSymbol(compiler_string_consts.eq_name,new SymbolInfo(cmn_eq));
        	
        	//<> operation
			scope = convertion_data_and_alghoritms.symbol_table.CreateClassMethodScope(_cmn.scope,ctn.scope);
        	common_method_node cmn_noteq = new common_method_node(compiler_string_consts.GetNETOperName(compiler_string_consts.noteq_name),SystemLibrary.SystemLibrary.bool_type,null,ctn,
        	                                                SemanticTree.polymorphic_state.ps_static,SemanticTree.field_access_level.fal_public,scope);
        	cmn_noteq.IsOperator = true;
        	prm1 = new common_parameter("a",ctn,SemanticTree.parameter_type.value,cmn_noteq,concrete_parameter_type.cpt_none,null,null);
        	prm2 = new common_parameter("b",ctn,SemanticTree.parameter_type.value,cmn_noteq,concrete_parameter_type.cpt_none,null,null);
        	cmn_noteq.parameters.AddElement(prm1);
        	cmn_noteq.parameters.AddElement(prm2);
        	body = new statements_list(null);
        	vdn = new local_variable("$i",SystemLibrary.SystemLibrary.integer_type,cmn_noteq,null);//this.convertion_data_and_alghoritms.syntax_tree_visitor.context.create_for_temp_variable(SystemLibrary.SystemLibrary.integer_type, null);
        	cmn_noteq.var_definition_nodes_list.AddElement(vdn);
        	var_ref = new local_variable_reference(vdn,0,null);//this.convertion_data_and_alghoritms.syntax_tree_visitor.create_variable_reference(vdn,null);
        	cond = new basic_function_call(SystemLibrary.SystemLibrary.int_sm as basic_function_node,null);
        	cond.parameters.AddElement(var_ref);
        	cond.parameters.AddElement(new int_const_node(arr_length,null));
        	while_stmt = new while_node(cond,null);
        	while_body = new statements_list(null);
        	while_stmt.body = while_body;
        	left_sar = new simple_array_indexing(new class_field_reference(int_arr, new common_parameter_reference(prm1,0,null), null),var_ref,element_type,null);
        	right_sar = new simple_array_indexing(new class_field_reference(int_arr, new common_parameter_reference(prm2,0,null), null),var_ref,element_type,null);
        	cond2 = SystemLibrary.SystemLibrary.syn_visitor.find_operator(compiler_string_consts.noteq_name,
        		                                                                            left_sar,right_sar,null);
        	if_stmt = new if_node(cond2,new return_node(new bool_const_node(true,null),null),null,null);
        	while_body.statements.AddElement(if_stmt);
        	while_body.statements.AddElement(new basic_function_call(SystemLibrary.SystemLibrary.int_assign as basic_function_node,null
        	                                                   ,var_ref,new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node,null,var_ref,new int_const_node(1,null))));
        	
        	body.statements.AddElement(while_stmt);
        	body.statements.AddElement(new return_node(new bool_const_node(false,null),null));
        	cmn_noteq.function_code = body;
        	cmn_noteq.is_overload = true;
        	ctn.methods.AddElement(cmn_noteq);
        	ctn.Scope.AddSymbol(compiler_string_consts.noteq_name,new SymbolInfo(cmn_noteq));
        	
        	//Equals
        	/*scope = convertion_data_and_alghoritms.symbol_table.CreateClassMethodScope(_cmn.scope,ctn.scope);
        	common_method_node cmn_equals = new common_method_node("Equals",SystemLibrary.SystemLibrary.bool_type,null,ctn,
        	                                                SemanticTree.polymorphic_state.ps_virtual,SemanticTree.field_access_level.fal_public,scope);
        	prm1 = new common_parameter("a",SystemLibrary.SystemLibrary.object_type,SemanticTree.parameter_type.value,cmn_equals,concrete_parameter_type.cpt_none,null,null);
        	
        	cmn_equals.parameters.AddElement(prm1);
        	body = new statements_list(null);
        	vdn = new local_variable("$i",ctn,cmn_equals,null);//this.convertion_data_and_alghoritms.syntax_tree_visitor.context.create_for_temp_variable(SystemLibrary.SystemLibrary.integer_type, null);
        	cmn_equals.var_definition_nodes_list.AddElement(vdn);
        	var_ref = new local_variable_reference(vdn,0,null);//this.convertion_data_and_alghoritms.syntax_tree_visitor.create_variable_reference(vdn,null);
        	as_node _as = new as_node(new common_parameter_reference(prm1,0,null),ctn,null);
        	base_function_call ass_bfc = new basic_function_call(SystemLibrary.SystemLibrary.object_type.find(compiler_string_consts.assign_name).sym_info as basic_function_node,null);
        	ass_bfc.parameters.AddElement(var_ref);
        	ass_bfc.parameters.AddElement(_as);
        	body.statements.AddElement(ass_bfc);
        	common_static_method_call csmc = new common_static_method_call(ctn.find_in_type(compiler_string_consts.eq_name).sym_info as common_method_node,null);
        	csmc.parameters.AddElement(new this_node(ctn,null));
        	csmc.parameters.AddElement(var_ref);
        	body.statements.AddElement(new return_node(csmc,null));
        	ctn.methods.AddElement(cmn_equals);
        	ctn.Scope.AddSymbol("Equals",new SymbolInfo(cmn_equals));*/
        	return ctn;
		}