private base_function_call create_static_method_call_with_params(function_node fn, location loc, type_node tn, bool procedure_allowed, expressions_list parametrs)
 {
     base_function_call bfc = create_static_method_call(fn, loc, tn, procedure_allowed);
     bfc.parameters.AddRange(parametrs);
     return bfc;
 }
        private expression_node find_operator(SyntaxTree.Operators ot, expression_node expr, location loc)
        {
            string name = name_reflector.get_name(ot);
            //#if (DEBUG)
            if (name == null)
            {
                if (ot == PascalABCCompiler.SyntaxTree.Operators.AddressOf)
                {
                    if (expr.is_addressed == false)
                    {
                        AddError(expr.location, "CAN_NOT_GET_ADDRESS_FROM_EXPRESSION");
                    }
                    expression_node res = new get_addr_node(expr, loc);
                    return res;
                }
                if (ot == PascalABCCompiler.SyntaxTree.Operators.Dereference)
                {
                }
                throw new CompilerInternalError("Invalid operator name");
            }
            //#endif
            SymbolInfo si = expr.type.find(name, context.CurrentScope);
            if (si == null || si.sym_info is wrapped_definition_node)
            {
            	AddError(new OperatorCanNotBeAppliedToThisType(name, expr));
            }

            expressions_list pars = new expressions_list();
            pars.AddElement(expr);

            function_node fn = convertion_data_and_alghoritms.select_function(pars, si, loc);
            expr = pars[0];
            if (fn == null)
            {
            	AddError(new OperatorCanNotBeAppliedToThisType(name, expr));
            }
#if (DEBUG)
            convertion_data_and_alghoritms.check_operator(fn);
#endif
            expression_node exp_node = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, expr);
            return exp_node;
        }
 private expression_node make_pred_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 is typed_expression) param0 = convert_typed_expression_to_function_call(param0 as typed_expression);
 		basic_function_call bfc = null;
 		int type_flag = 0;
 		expressions_list el = new expressions_list();
 		el.AddElement(param0);
 		function_node fn = null;
 		try
 		{
 			fn = convertion_data_and_alghoritms.select_function(el,si,loc);
 		}
 		catch(Exception e)
 		{
 			
 		}
 		if (fn != null)
 		{
             if (fn is common_namespace_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
             {
                 compiled_static_method_call cnfc = new compiled_static_method_call(fn as compiled_function_node, loc);
                 cnfc.parameters.AddElement(param0);
                 return cnfc;
             }
 		}
 		else if (param0.type.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.diap_type || param0.type.IsEnum)
 		{
 			el = new expressions_list();
 			el.AddElement(new int_const_node(1,null));
 			fn = convertion_data_and_alghoritms.select_function(el,si,loc);
 			//bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node,loc);
 			//bfc.ret_type = param0.type;
             if (fn is common_namespace_function_node)
             {
                 common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node, loc);
                 cnfc.parameters.AddElement(param0);
                 cnfc.type = param0.type;
                 return cnfc;
             }
             else
             {
                 compiled_static_method_call cnfc = new compiled_static_method_call(fn as compiled_function_node, loc);
                 cnfc.parameters.AddElement(param0);
                 cnfc.type = param0.type;
                 return cnfc;
             }
 		}
 		else AddError(new NoFunctionWithSameArguments(loc,false));
 		bfc.parameters.AddElement(param0);
 		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));
 		return bfc;
 	}
 	AddError(new NoFunctionWithSameParametresNum(loc,false,si.sym_info as function_node));
     return null;
 }
        private expression_node make_read_call(SymbolInfo si, SyntaxTree.expression_list parameters, location loc)
        {

            // вызов read(a,b,c) разбивается на несколько вызовов, последний возвращается узлом, а остальные добавляются здесь в теле            expressions_list exl = new expressions_list();
            expression_node last_call = null;
            expressions_list exl = new expressions_list();
            expression_node file = null;
            bool read_from_file = false;
            bool read_from_text_file = false;
            bool read_from_typed_file = false;
            bool read_from_binary_file = false;
            bool readln_string_file = false;
            if (parameters != null) // если список параметров не пуст
            {
                if (parameters.expressions.Count >= 1)
                {
                    expression_node param0 = convert_strong(parameters.expressions[0]);
                    if (param0.type != null)
                    {
                        if (SystemLibrary.SystemLibInitializer.TextFileType.Found && param0.type == SystemLibrary.SystemLibInitializer.TextFileType.sym_info)
                        {
                            file = param0;
                            read_from_text_file = true;
                        }
                        if (param0.type.type_special_kind == SemanticTree.type_special_kind.typed_file
                            && parameters.expressions.Count > 1                        //это можно внести во внутрь
                            )//и побросать приличные исключения
                        {
                            if (!SystemLibrary.SystemLibInitializer.read_procedure.FromDll)
                            {
                                if (si == SystemLibrary.SystemLibInitializer.read_procedure.SymbolInfo)
                                {
                                    file = param0;
                                    read_from_typed_file = true;
                                }
                            }
                            else if (SystemLibrary.SystemLibInitializer.read_procedure.Equal(si))
                            {
                                file = param0;
                                read_from_typed_file = true;
                            }
                        }
                        if (param0.type.type_special_kind == SemanticTree.type_special_kind.binary_file
                            && parameters.expressions.Count > 1                        //это можно внести во внутрь
                            )//и побросать приличные исключения
                        {
                            if (!SystemLibrary.SystemLibInitializer.read_procedure.FromDll)
                            {
                                if (si == SystemLibrary.SystemLibInitializer.read_procedure.SymbolInfo)
                                {
                                    file = param0;
                                    read_from_binary_file = true;
                                }
                            }
                            else if (SystemLibrary.SystemLibInitializer.read_procedure.Equal(si))
                            {
                                file = param0;
                                read_from_binary_file = true;
                            }
                        }
                    }
                    read_from_file = read_from_text_file || read_from_typed_file || read_from_binary_file;
                }
                bool first_iteration = true;
                
                foreach (SyntaxTree.expression ex in parameters.expressions)
                {
                    if (first_iteration && read_from_file)
                    {
                        first_iteration = false;
                        continue;
                    }
                    if (last_call != null && convertion_data_and_alghoritms.statement_list_stack.size > 0)
                        convertion_data_and_alghoritms.statement_list_stack.top().statements.AddElement(last_call);
                    expression_node en = convert_strong(ex);
                    check_on_loop_variable(en);
                    //if (en.type == null)
                    //throw new CanNotRead(en.location);
                    exl.clear();
                    if (read_from_file)
                        exl.AddElement(file);
                    if (read_from_typed_file)
                    {
                        if (SystemLibrary.SystemLibInitializer.TypedFileReadProcedure == null)
                            AddError(new NotSupportedError(loc));
                        if (en.type != file.type.element_type)
                            AddError(new ExpectedExprHaveTypeTypedFile(file.type.element_type, en.type, true, get_location(ex)));
                        bool is_char_getter = false;
                        if (!en.is_addressed)
                        {
                            if (en is compiled_function_call)
                            {
                                compiled_function_call cfc = en 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))
                                {
                                    en = new simple_array_indexing((en as compiled_function_call).obj, (en as compiled_function_call).parameters[0], SystemLibrary.SystemLibrary.char_type, en.location);
                                    is_char_getter = true;
                                }
                                
                            }
                        }
                        function_node fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.TypedFileReadProcedure.SymbolInfo, loc);
                        expression_node expr = convertion_data_and_alghoritms.create_simple_function_call(fn, get_location(ex), file);
                        //expression_node expr = convertion_data_and_alghoritms.create_full_function_call(exl, SystemLibrary.SystemLibInitializer.TypedFileReadProcedure.SymbolInfo, loc, context.converted_type, context.top_function, true);
                        expr = convertion_data_and_alghoritms.explicit_convert_type(expr, file.type.element_type);
                        if (is_char_getter)
                            expr = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.StringDefaultPropertySetProcedure.sym_info as function_node, loc, (en as simple_array_indexing).simple_arr_expr, (en as simple_array_indexing).ind_expr, expr);
                        else
                            expr = find_operator(compiler_string_consts.assign_name, en, expr, loc);
                        last_call = expr;
                    }
                    else if (read_from_binary_file)
                    {
                        if (SystemLibrary.SystemLibInitializer.BinaryFileReadProcedure == null)
                            AddError(new NotSupportedError(loc));
                        if (!CanUseThisTypeForBinaryFiles(en.type))
                        {
                            AddError(en.location, "CAN_NOT_READ_REFERENCE_DATA_FROM_BINARY_FILE");
                        }
                        exl.AddElement(new typeof_operator(en.type, loc));
                        function_node fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.BinaryFileReadProcedure.SymbolInfo, loc);
                        expression_node expr = convertion_data_and_alghoritms.create_simple_function_call(fn, get_location(ex), exl.ToArray());
                        expr = convertion_data_and_alghoritms.explicit_convert_type(expr, en.type);
                        expr = find_operator(compiler_string_consts.assign_name, en, expr, loc);
                        last_call = expr;
                    }
                    else
                    {
                        exl.AddElement(en);
                        try
                        {
                        	function_node fn = null;
                        	if (en.type.type_special_kind == SemanticTree.type_special_kind.short_string)
                        	{
                        		exl.AddElement(new int_const_node((en.type as short_string_type_node).Length,null));
                        		if (!read_from_file)
                        		last_call = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.read_short_string_procedure.sym_info as function_node,get_location(ex),exl.ToArray());
                        		else
                        		last_call = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.read_short_string_from_file_procedure.sym_info as function_node,get_location(ex),exl.ToArray());
                        	}
                        	else if (en.type.type_special_kind == SemanticTree.type_special_kind.diap_type)
                        	{
                        		exl.remove(en);
                        		en.type = en.type.base_type;
                        		exl.AddElement(en);
                        		fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.read_procedure.SymbolInfo, loc);
                            	last_call = convertion_data_and_alghoritms.create_simple_function_call(fn, get_location(ex), exl.ToArray());
                        	}
                        	else
                        	{
                                if (SystemLibrary.SystemLibInitializer.readln_procedure.Equal(si) && parameters.expressions.Count == 2 && en.type == SystemLibrary.SystemLibrary.string_type)
                                {
                                    fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.readln_procedure.SymbolInfo, loc);
                                    readln_string_file = true;
                                }
                                else
                                    fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.read_procedure.SymbolInfo, loc);
                            	last_call = convertion_data_and_alghoritms.create_simple_function_call(fn, get_location(ex), exl.ToArray());
                        	}
                            //last_call = convertion_data_and_alghoritms.create_full_function_call(exl, SystemLibrary.SystemLibInitializer.read_procedure.SymbolInfo, loc, context.converted_type, context.top_function, true);
                        }
                        catch (NoFunctionWithSameArguments)
                        {
                            AddError(en.location, "CAN_NOT_READ");
                        }
                    }
                    first_iteration = false;
                }
            }
            if ((parameters == null) || (parameters.expressions.Count == 0)) // read(), readln()
            {
                if (SystemLibrary.SystemLibInitializer.read_procedure.Equal(si))
                {
                    if (read_from_file)
                        exl.AddElement(file);
                    function_node fn = convertion_data_and_alghoritms.select_function(exl,
                        SystemLibrary.SystemLibInitializer.read_procedure.SymbolInfo, loc);
                    if (read_from_file)
                        last_call = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, file);
                    else
                        last_call = convertion_data_and_alghoritms.create_simple_function_call(fn, loc);
                }
            }
            if (SystemLibrary.SystemLibInitializer.readln_procedure.Equal(si)) // readln(...)
            {
                if (!readln_string_file)
                {
                    if (last_call != null && convertion_data_and_alghoritms.statement_list_stack.size > 0)
                        convertion_data_and_alghoritms.statement_list_stack.top().statements.AddElement(last_call);
                    exl.clear();

                    if (read_from_file)
                        exl.AddElement(file);

                    function_node fn = convertion_data_and_alghoritms.select_function(exl,
                            SystemLibrary.SystemLibInitializer.readln_procedure.SymbolInfo, loc);
                    if (read_from_file)
                        last_call = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, file);
                    else
                        last_call = convertion_data_and_alghoritms.create_simple_function_call(fn, loc);
                }
            }
            return last_call;
        }
        public override void visit(SyntaxTree.pascal_set_constant _pascal_set_constant)
        {
            //throw new NotSupportedError(get_location(_pascal_set_constant));
            if (SystemLibrary.SystemLibInitializer.TypedSetType == null || SystemLibrary.SystemLibInitializer.CreateSetProcedure == null)
            	AddError(new NotSupportedError(get_location(_pascal_set_constant)));
            expressions_list consts = new expressions_list();
            type_node el_type = null;
            type_node_list types = new type_node_list();
            if (_pascal_set_constant.values != null && _pascal_set_constant.values != null)
                foreach (SyntaxTree.expression e in _pascal_set_constant.values.expressions)
                {
            		if (e is SyntaxTree.nil_const)
                        ErrorsList.Add(new SimpleSemanticError(get_location(e), "NIL_IN_SET_CONSTRUCTOR_NOT_ALLOWED"));
            		else
            		if (e is SyntaxTree.diapason_expr)
                    {
                        consts.AddElement(convert_diap_for_set((e as SyntaxTree.diapason_expr), out el_type));
                        if (el_type.IsPointer)
                            ErrorsList.Add(new SimpleSemanticError(get_location(e), "POINTERS_IN_SETS_NOT_ALLOWED"));
                        types.AddElement(el_type);
                    }
                    else
                    {
                        expression_node en = convert_strong(e);
                        if (en is typed_expression) en = convert_typed_expression_to_function_call(en as typed_expression);
                        if (en.type.type_special_kind == SemanticTree.type_special_kind.short_string)
                        	en.type = SystemLibrary.SystemLibrary.string_type;
                        consts.AddElement(en);
                        types.AddElement(en.type);
                    }
                }
            expressions_list consts_copy = new expressions_list();
            consts_copy.AddRange(consts);
            type_node ctn = null;
            if (consts.Count > 0)
            {
                el_type = convertion_data_and_alghoritms.select_base_type(types);
                ctn = context.create_set_type(el_type, get_location(_pascal_set_constant));

            }
            else ctn = SystemLibrary.SystemLibInitializer.TypedSetType.sym_info as type_node;
            function_node fn = convertion_data_and_alghoritms.select_function(consts, SystemLibrary.SystemLibInitializer.CreateSetProcedure.SymbolInfo, (SystemLibrary.SystemLibInitializer.CreateSetProcedure.sym_info is common_namespace_function_node)?(SystemLibrary.SystemLibInitializer.CreateSetProcedure.sym_info as common_namespace_function_node).loc:null);
            if (fn is common_namespace_function_node)
            {
                common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node, get_location(_pascal_set_constant));
                add_set_initializer(cnfc, consts_copy);
                cnfc.ret_type = ctn;
                for (int i = 0; i < consts.Count; i++)
                    cnfc.parameters.AddElement(consts[i]);
                return_value(cnfc);
            }
            else
            {
                compiled_static_method_call cnfc = new compiled_static_method_call(fn as compiled_function_node, get_location(_pascal_set_constant));
                add_set_initializer(cnfc, consts_copy);
                cnfc.ret_type = ctn;
                for (int i = 0; i < consts.Count; i++)
                    cnfc.parameters.AddElement(consts[i]);
                return_value(cnfc);
            }
            //return_value(new common_namespace_function_call_as_constant(cnfc,cnfc.location));
        }
 private void ConvertPointersForWriteFromDll(expressions_list exprs)
 {
     for (int i = 0; i < exprs.Count; ++i)
     {
         if (exprs[i].type.IsPointer)
         {
             if (SystemLibrary.SystemLibInitializer.PointerOutputConstructor == null)
             {
                 SymbolInfo si = (SystemLibrary.SystemLibInitializer.PointerOutputType.sym_info as compiled_type_node).find_in_type(compiler_string_consts.default_constructor_name);
                 compiled_constructor_node cnode = null;
                 do
                 {
                     cnode = si.sym_info as compiled_constructor_node;
                     if (cnode.parameters.Count != 1)
                     {
                         cnode = null;
                         si = si.Next;
                     }
                 }
                 while (cnode == null);
                 SystemLibrary.SystemLibInitializer.PointerOutputConstructor = cnode;
             }
             compiled_constructor_call cnc = new compiled_constructor_call(SystemLibrary.SystemLibInitializer.PointerOutputConstructor as compiled_constructor_node, exprs[i].location);
             //common_namespace_function_call cnfc = new common_namespace_function_call(
             //    SystemLibrary.SystemLibInitializer.PointerToStringFunction.sym_info as common_namespace_function_node,
             //    exprs[i].location);
             cnc.parameters.AddElement(exprs[i]);
             exprs[i] = cnc;
         }
     }
 }
        private void make_attributes_for_declaration(SyntaxTree.unit_module un, common_unit_node cun)
        {
            if (cun.attributes != null)
            {
                Hashtable ht = new Hashtable();
                foreach (SyntaxTree.simple_attribute_list sal in un.attributes.attributes)
                    for (int j = 0; j < sal.attributes.Count; j++)
                    {
                        SyntaxTree.attribute attr = sal.attributes[j];
                        attribute_converted = true;
                        type_node tn = convert_strong(attr.type);
                        bool is_attr = false;
                        type_node tmp = tn;
                        while (tmp.base_type != null && !is_attr)
                        {
                            is_attr = tmp.base_type == SystemLibrary.SystemLibrary.attribute_type;
                            tmp = tmp.base_type;
                        }
                        if (!is_attr)
                            AddError(get_location(attr), "CLASS_{0}_NOT_ATTRIBUTE", tn.name);
                        bool allowMultiple = false;
                        AttributeTargets targets = get_usage_attrs(tn, out allowMultiple);
                        if (ht.Contains(tn) && !allowMultiple)
                        {
                            AddError(get_location(attr), "DUPLICATE_ATTRIBUTE_{0}_APPLICATION", tn.name);
                        }
                        else
                            ht[tn] = tn;
                        SemanticTree.attribute_qualifier_kind qualifier = SemanticTree.attribute_qualifier_kind.none_kind;
                        if (attr.qualifier != null)
                            if (j == 0)
                            {
                                if (string.Compare(attr.qualifier.name, "return", true) == 0)
                                {
                                    if (context.top_function == null)
                                        AddError(get_location(attr), "ATTRIBUTE_APPLICABLE_ONLY_TO_METHOD");
                                    if (context.top_function.return_value_type == null || context.top_function.return_value_type == SystemLibrary.SystemLibrary.void_type)
                                        AddError(get_location(attr), "EXPECTED_RETURN_VALUE_FOR_ATTRIBUTE");
                                    throw new NotSupportedError(get_location(attr.qualifier));
                                    qualifier = SemanticTree.attribute_qualifier_kind.return_kind;
                                }
                                else
                                    throw new NotSupportedError(get_location(attr.qualifier));
                            }
                            else
                                AddError(get_location(attr.qualifier), "ATTRIBUTE_QUALIFIER_MUST_BE_FIRST");
                        check_for_usage_attribute(cun, targets, tn.name, get_location(attr), qualifier);

                        attribute_converted = false;
                        SyntaxTree.expression_list cnstr_args = new SyntaxTree.expression_list();
                        if (attr.arguments != null)
                        {
                            foreach (SyntaxTree.expression e in attr.arguments.expressions)
                            {
                                if (e is SyntaxTree.bin_expr && (e as SyntaxTree.bin_expr).operation_type == SyntaxTree.Operators.Equal
                                    && (e as SyntaxTree.bin_expr).left is SyntaxTree.ident)
                                {
                                    break;
                                }
                                else
                                {
                                    cnstr_args.expressions.Add(e);
                                }
                            }
                        }
                        expressions_list args = new expressions_list();
                        for (int i = 0; i < cnstr_args.expressions.Count; i++)
                        {
                            constant_node cn = convert_strong_to_constant_node(cnstr_args.expressions[i]);
                            check_for_strong_constant(cn, get_location(cnstr_args.expressions[i]));
                            args.AddElement(cn);
                        }

                        base_function_call bfc = create_constructor_call(tn, args, get_location(attr));
                        attribute_node attr_node = new attribute_node(bfc.simple_function_node, tn, get_location(un));
                        foreach (expression_node en in bfc.parameters)
                        {
                            constant_node cn = convert_strong_to_constant_node(en, en.type);
                            check_for_strong_constant(cn, en.location);
                            attr_node.args.Add(cn);
                        }
                        if (attr.arguments != null)
                        {
                            for (int i = cnstr_args.expressions.Count; i < attr.arguments.expressions.Count; i++)
                            {
                                SyntaxTree.expression e = attr.arguments.expressions[i];
                                if (!(e is SyntaxTree.bin_expr && (e as SyntaxTree.bin_expr).operation_type == SyntaxTree.Operators.Equal
                                      && (e as SyntaxTree.bin_expr).left is SyntaxTree.ident))
                                {
                                    AddError(get_location(e), "EXPECTED_ATTRIBUTE_INITIALIZER");
                                }
                                else
                                {
                                    SyntaxTree.ident id = (e as SyntaxTree.bin_expr).left as SyntaxTree.ident;
                                    SymbolInfo si = tn.find(id.name);
                                    definition_node dn = context.check_name_node_type(id.name, si, get_location(id), general_node_type.property_node, general_node_type.variable_node);
                                    type_node mem_tn = null;
                                    if (dn is property_node)
                                    {
                                        property_node pn = dn as property_node;
                                        attr_node.prop_names.Add(pn);
                                        if (pn.set_function == null)
                                            AddError(new ThisPropertyCanNotBeWrited(pn, get_location(id)));
                                        if (pn.set_function.parameters.Count != 1)
                                            AddError(get_location(id), "INDEX_PROPERTY_INITIALIZING_NOT_VALID");
                                        mem_tn = pn.set_function.parameters[0].type;
                                    }
                                    else if (dn is var_definition_node)
                                    {
                                        attr_node.field_names.Add(dn as var_definition_node);
                                        mem_tn = (dn as var_definition_node).type;
                                    }
                                    else
                                    {
                                        throw new CompilerInternalError("Bad general node type for attribute initializer");
                                    }
                                    //SyntaxTree.assign tmp_ass = new SyntaxTree.assign(id,(e as SyntaxTree.bin_expr).right,SyntaxTree.Operators.Assignment);
                                    //tmp_ass.source_context = e.source_context;
                                    //basic_function_call tmp_bfc = convert_strong(tmp_ass) as basic_function_call;
                                    constant_node cn = convert_strong_to_constant_node((e as SyntaxTree.bin_expr).right, mem_tn);
                                    check_for_strong_constant(cn, get_location((e as SyntaxTree.bin_expr).right));
                                    if (dn is property_node)
                                        attr_node.prop_initializers.Add(cn);
                                    else
                                        attr_node.field_initializers.Add(cn);
                                }
                            }
                        }
                        attr_node.qualifier = qualifier;
                        cun.attributes.AddElement(attr_node);
                        if (cun.namespaces.Count > 0)
                            cun.namespaces[0].attributes.AddElement(attr_node);
                    }
            }
        }
 public override void visit(SyntaxTree.format_expr _format_expr)
 {
     if (_format_expr.expr == null || _format_expr.format1 == null)
         AddError(get_location(_format_expr), "BAD_CONSTRUCTED_FORMAT_EXPRESSION");
     //TODO: Добавить проверки.
     if (!SemanticRules.AllowUseFormatExprAnywhere && !is_format_allowed)
         AddError(get_location(_format_expr.expr), "FORMAT_EXPRESSION_CAN_USE_ONLY_IN_THESE_PROCEDURES");
     expression_node expr = convert_strong(_format_expr.expr);
     if (expr is typed_expression)
         expr = convert_typed_expression_to_function_call(expr as typed_expression);
     expression_node par1 = convert_strong(_format_expr.format1);
     par1 = convertion_data_and_alghoritms.convert_type(par1, SystemLibrary.SystemLibrary.integer_type);
     expression_node par2 = convert_weak(_format_expr.format2);
     if (par2 != null)
     {
         if (expr.type != SystemLibrary.SystemLibrary.double_type && expr.type != SystemLibrary.SystemLibrary.float_type)
         {
             AddError(expr.location, "REAL_TYPE_IN_DOUBLE_COLON_EXPRESSION_EXPECTED");
         }
         par2 = convertion_data_and_alghoritms.convert_type(par2, SystemLibrary.SystemLibrary.integer_type);
     }
     expressions_list exl = new expressions_list();
     exl.AddElement(expr);
     exl.AddElement(par1);
     if (par2 != null)
     {
         exl.AddElement(par2);
     }
     location loc = get_location(_format_expr);
     if (!SystemUnitAssigned)
         AddError( new NotSupportedError(loc));
     function_node fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.format_function.SymbolInfo,
         loc);
     expression_node ret = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, exl.ToArray());
     return_value(ret);
 }
Exemple #9
0
        /// <summary>
        /// Обрабатывает случай, когда левая часть присваивания свойство.
        /// </summary>
        /// <returns>True - обработка прошла, иначе False.</returns>
        private bool ProcessAssignToPropertyIfPossible(assign _assign, addressed_expression to, location loc,
                                                       expression_node from)
        {
            //проверка на обращение к полю записи возвращенной из функции с целью присваивания
            //нужно чтобы пользователь не мог менять временный обьект
            if (to.semantic_node_type == semantic_node_type.static_property_reference ||
                to.semantic_node_type == semantic_node_type.non_static_property_reference)
            {
                property_node pn;
                if (to.semantic_node_type == semantic_node_type.static_property_reference)
                {
                    pn = (to as static_property_reference).property;
                }
                else
                {
                    pn = (to as non_static_property_reference).property;
                }

                var ot = MapCompositeAssignmentOperatorToSameBinaryOperator(_assign);
                var oper_ass_in_prop = ot != Operators.Undefined;

                if (_assign.operator_type == Operators.Assignment || oper_ass_in_prop)
                {
                    if (oper_ass_in_prop)
                    {
                        if (pn.get_function == null)
                        {
                            AddError(loc, "THIS_PROPERTY_{0}_CAN_NOT_BE_READED", pn.name);
                        }
                        base_function_call prop_expr;
                        if (to.semantic_node_type == semantic_node_type.non_static_property_reference)
                        {
                            prop_expr = create_not_static_method_call(pn.get_function,
                                                                      (to as non_static_property_reference).expression, loc, false);
                            prop_expr.parameters.AddRange((to as non_static_property_reference).fact_parametres);
                        }
                        else
                        {
                            prop_expr = create_static_method_call(pn.get_function, loc, pn.comprehensive_type, false);
                            prop_expr.parameters.AddRange((to as static_property_reference).fact_parametres);
                        }
                        from = find_operator(ot, prop_expr, from, loc);
                    }

                    if (to.semantic_node_type == semantic_node_type.static_property_reference)
                    {
                        static_property_reference spr = (static_property_reference)to;
                        if (spr.property.set_function == null)
                        {
                            AddError(loc, "THIS_PROPERTY_{0}_CAN_NOT_BE_WRITED", spr.property.name);
                        }
                        check_property_params(spr, loc);
                        function_node set_func = spr.property.set_function;
                        from = convertion_data_and_alghoritms.convert_type(from, spr.property.property_type);
                        spr.fact_parametres.AddElement(from);
                        base_function_call bfc = create_static_method_call(set_func, loc,
                                                                           spr.property.comprehensive_type,
                                                                           true);
                        bfc.parameters.AddRange(spr.fact_parametres);
                        return_value((statement_node)bfc);
                    }
                    else if (to.semantic_node_type == semantic_node_type.non_static_property_reference)
                    {
                        non_static_property_reference nspr = (non_static_property_reference)to;
                        check_property_params(nspr, loc);
                        from = convertion_data_and_alghoritms.convert_type(from, nspr.property.property_type);
                        nspr.fact_parametres.AddElement(from);

                        //Обработка s[i]:='c'
                        if (SystemUnitAssigned)
                        {
                            if (nspr.property.comprehensive_type == SystemLibrary.SystemLibrary.string_type)
                            {
                                if (nspr.property == SystemLibrary.SystemLibrary.string_type.default_property_node)
                                {
                                    if (SystemLibInitializer.StringDefaultPropertySetProcedure != null)
                                    {
                                        expressions_list exl = new expressions_list();
                                        exl.AddElement(nspr.expression);
                                        exl.AddElement(nspr.fact_parametres[0]);
                                        exl.AddElement(from);
                                        function_node fn = convertion_data_and_alghoritms.select_function(exl,
                                                                                                          SystemLibInitializer.StringDefaultPropertySetProcedure
                                                                                                          .SymbolInfo, loc);
                                        expression_node ret =
                                            convertion_data_and_alghoritms.create_simple_function_call(fn, loc,
                                                                                                       exl.ToArray());
                                        return_value((statement_node)ret);
                                        return(true);
                                    }
                                }
                            }
                        }

                        if (nspr.property.set_function == null)
                        {
                            AddError(loc, "THIS_PROPERTY_{0}_CAN_NOT_BE_WRITED", nspr.property.name);
                        }
                        function_node      set_func = nspr.property.set_function;
                        base_function_call bfc      = create_not_static_method_call(set_func, nspr.expression, loc,
                                                                                    true);
                        bfc.parameters.AddRange(nspr.fact_parametres);
                        return_value((statement_node)bfc);
                    }
                    return(true);
                }
            }
            return(false);
        }
        public expression_node find_operator(string name, expression_node left, expression_node right, location loc)
        {
            //if (!CheckExpressionType(left))
            //    return SystemLibrary.SystemLibrary.get_empty_method_call(left.location);
            //if (!CheckExpressionType(right))
            //    return SystemLibrary.SystemLibrary.get_empty_method_call(right.location);
            //string name=name_reflector.get_name(ot);
#if (DEBUG)
            if (name == null)
            {
                throw new CompilerInternalError("Invalid operator name");
            }
#endif

            if (right.semantic_node_type == semantic_node_type.null_const_node)
            {
            	if ( !type_table.is_with_nil_allowed(left.type) && !left.type.IsPointer)
                    AddError(right.location, "NIL_WITH_VALUE_TYPES_NOT_ALLOWED");
            	right = null_const_node.get_const_node_with_type(left.type, (null_const_node)right);
            }

            type_node left_type = left.type;
            type_node right_type = right.type;
			
            /*if (left.type == SystemLibrary.SystemLibrary.uint64_type || right.type == SystemLibrary.SystemLibrary.uint64_type)
            	if (name == compiler_string_consts.plus_name || name == compiler_string_consts.minus_name || name == compiler_string_consts.mul_name || name == compiler_string_consts.idiv_name || name == compiler_string_consts.mod_name)
            	{
                    expression_node expr = right.type != SystemLibrary.SystemLibrary.uint64_type ? right : left;
                    if (!(expr is constant_node))
                    {
                        type_node tn = expr.type;
                        if (tn == SystemLibrary.SystemLibrary.short_type || tn == SystemLibrary.SystemLibrary.sbyte_type || tn == SystemLibrary.SystemLibrary.integer_type || tn == SystemLibrary.SystemLibrary.int64_type)
                            throw new OperatorCanNotBeAppliedToThisTypes(name, left, right, loc);
                    }
            	}
            */

            if (left_type.semantic_node_type == semantic_node_type.delegated_method)
            {
                delegated_methods dm1 = (delegated_methods)left_type;
                if (dm1.empty_param_method != null)
                {
                    if (dm1.empty_param_method.simple_function_node.return_value_type != null)
                    {
                        left_type = dm1.empty_param_method.simple_function_node.return_value_type;
                    }
                }
            }

            if (right_type.semantic_node_type == semantic_node_type.delegated_method && name != compiler_string_consts.plusassign_name && name != compiler_string_consts.minusassign_name)
            {
                delegated_methods dm2 = (delegated_methods)right_type;
                if (dm2.empty_param_method != null)
                {
                    if (dm2.empty_param_method.simple_function_node.return_value_type != null)
                    {
                        right_type = dm2.empty_param_method.simple_function_node.return_value_type;
                    }
                }
            }
			
            //zdes ne vse verno. += odnostoronnjaa operacija, a += b pochemu esli tipy ne ravny, += ishetsja v tipe b???
            //TODO: Посмотреть.
            //TODO: Не find а find_in_type.
            //SymbolInfo si=left_type.find(name, context.CurrentScope);
            SymbolInfo si = left_type.find_in_type(name, left_type.Scope);
            SymbolInfo added_symbols = null;
            SymbolInfo si2 = null;
            if (left_type != right_type && !one_way_operation(name))
            {
                //SymbolInfo si2 = right_type.find(name, context.CurrentScope);
                if (si != null)
                    si = si.copy();
                si2 = right_type.find_in_type(name, right_type.Scope);
                if ((si != null) && (si2 != null))
                {
                    //Важная проверка. Возможно один и тот же оператор с одними и теми же типами определен в двух разных классах.
                    //Возможно она занимает много времени, но, наверное, от нее нельзя отказаться.
                    function_node_list funcs = new function_node_list();
                    SymbolInfo sic = si;
                    SymbolInfo sic_last = null;
                    while (sic != null)
                    {
                        if (sic.sym_info.general_node_type != general_node_type.function_node)
                        {
                            BasePCUReader.RestoreSymbols(sic, name);
                        }
#if (DEBUG)
                        if (sic.sym_info.general_node_type != general_node_type.function_node)
                        {
                            throw new CompilerInternalError("Expected operator.");
                        }
#endif
                        
                        function_node fn = ((function_node)(sic.sym_info));
                        if (convertion_data_and_alghoritms.is_exist_eq_method_in_list(fn, funcs) != null)
                        {
                            break;
                        }
                        funcs.AddElement(fn);
                        sic_last = sic;
                        sic = sic.Next;
                    }
                    sic = si2;
                    //TODO: Разобраться с зацикливанием.
                    function_node_list fnl = new function_node_list();
                    while (sic != null)
                    {
                        if (sic.sym_info.general_node_type != general_node_type.function_node)
                        {
                            BasePCUReader.RestoreSymbols(sic, name);
                        }
#if (DEBUG)
                        if (sic.sym_info.general_node_type != general_node_type.function_node)
                        {
                            throw new CompilerInternalError("Expected operator.");
                        }
#endif
                        fnl.AddElement(((function_node)(sic.sym_info)));
                        sic = sic.Next;
                    }
                    added_symbols = sic_last;
                    foreach (function_node fnode in fnl)
                    {
                        function_node eq_func = convertion_data_and_alghoritms.find_eq_method_in_list(fnode, funcs);
                        if (eq_func != null)
                        {
                            //TODO: Проверить правильно ли это будет работать.
                            if (eq_func != fnode)
                            {
                                basic_function_node bbfn1 = fnode as basic_function_node;
                                basic_function_node bbfn2 = eq_func as basic_function_node;
                                if ((bbfn1 != null) && (bbfn2 != null))
                                {
                                    if (bbfn1.basic_function_type != bbfn2.basic_function_type)
                                    {
                                        AddError(new TwoOperatorsCanBeCalled(eq_func, fnode, left, right));
                                    }
                                    //sic = sic.Next;
                                    continue;
                                }
                                else
                                {
                                	if (left.type.type_special_kind == SemanticTree.type_special_kind.set_type && right.type.type_special_kind == SemanticTree.type_special_kind.set_type
                                	   || left.type.type_special_kind == SemanticTree.type_special_kind.set_type &&  right.type.type_special_kind == SemanticTree.type_special_kind.base_set_type
                                	  || left.type.type_special_kind == SemanticTree.type_special_kind.base_set_type &&  right.type.type_special_kind == SemanticTree.type_special_kind.set_type
                                	 || left.type.type_special_kind == SemanticTree.type_special_kind.base_set_type &&  right.type.type_special_kind == SemanticTree.type_special_kind.base_set_type
                                	|| left.type == SystemLibrary.SystemLibrary.string_type && right.type.type_special_kind == SemanticTree.type_special_kind.short_string
                               		 || right.type == SystemLibrary.SystemLibrary.string_type && left.type.type_special_kind == SemanticTree.type_special_kind.short_string
                               		|| left.type.type_special_kind == SemanticTree.type_special_kind.short_string && right.type.type_special_kind == SemanticTree.type_special_kind.short_string)
                                	{
                                		//if (left.type.find_in_type(name) !=null)
                                	}
                                	else
                                	AddError(new TwoOperatorsCanBeCalled(eq_func, fnode, left, right));
                                }
                            }
                        }
                        sic_last.Next = new SymbolInfo(fnode);
                        sic_last = sic_last.Next;
                    }
                    /*while (sic!=null)
                    {
#if (DEBUG)
                        if (sic.sym_info.general_node_type!=general_node_type.function_node)
                        {
                            throw new CompilerInternalError("Expected operator.");
                        }
#endif
                        function_node fn=((function_node)(sic.sym_info));
                        function_node eq_func=convertion_data_and_alghoritms.find_eq_method_in_list(fn,funcs);
                        if (eq_func!=null)
                        {
                            basic_function_node bbfn1=fn as basic_function_node;
                            basic_function_node bbfn2=eq_func as basic_function_node;
                            if ((bbfn1!=null)&&(bbfn2!=null))
                            {
                                if (bbfn1.basic_function_type!=bbfn2.basic_function_type)
                                {
                                    throw new TwoOperatorsCanBeCalled(eq_func,fn,left,right);
                                }
                                sic=sic.Next;
                                continue;
                            }
                            else
                            {
                                throw new TwoOperatorsCanBeCalled(eq_func,fn,left,right);
                            }
                        }
                        //TODO: Разобраться с зацикливанием.
                        sic_last.Next = sic;
                        sic_last = sic;
                        sic=sic.Next;
                    }*/
                    //sic_last.Next=si2;
                }
                else
                {
                    if ((si == null) && (si2 != null))
                    {
                        si = si2;
                    }
                }
            }
            //if (si == null)
            {
                if (/*si2 == null && */left_type.semantic_node_type == semantic_node_type.delegated_method && right_type.semantic_node_type == semantic_node_type.delegated_method)
                {
                    SymbolInfo saved_si = si;
                    SymbolInfo saved_si2 = si2;
                    base_function_call bfc = ((left as typed_expression).type as delegated_methods).proper_methods[0];
                    left = convertion_data_and_alghoritms.explicit_convert_type(left, CreateDelegate(bfc.simple_function_node));
                    si = left.type.find_in_type(name);
                    bfc = ((right as typed_expression).type as delegated_methods).proper_methods[0];
                    right = convertion_data_and_alghoritms.explicit_convert_type(right, CreateDelegate(bfc.simple_function_node));
                    si2 = right.type.find_in_type(name);
                    if (saved_si != null)
                        si.Next = saved_si;
                    else
                        saved_si = si;
                    if (saved_si2 != null)
                        si2.Next = saved_si2;
                    else
                        saved_si2 = si2;
                    if (saved_si == null)
                        AddError(new OperatorCanNotBeAppliedToThisTypes(name, left, right, loc));
                }
                else if (si == null)
                    AddError(new OperatorCanNotBeAppliedToThisTypes(name, left, right, loc));
            }

            expressions_list pars = null;
            function_node fnsel = null;
            SymbolInfo tmp_si = si;
            while (tmp_si != null)
            {
                if (tmp_si.sym_info is wrapped_definition_node)
                    BasePCUReader.RestoreSymbols(tmp_si, name);
                tmp_si = tmp_si.Next;
            }
            pars = new expressions_list();
            pars.AddElement(left);
            pars.AddElement(right);

            fnsel = convertion_data_and_alghoritms.select_function(pars, si, loc);
            //function_node fnsel=convertion_data_and_alghoritms.select_function(pars,si,loc);
            CheckSpecialFunctionCall(si, pars,loc);
            //TODO: А это зачем? Можно передать в create_simple_function_call pars.
            left = pars[0];
            right = pars[1];
            if (fnsel == null)
            {
                AddError(new OperatorCanNotBeAppliedToThisTypes(name, left, right, loc));
            }
            if (added_symbols != null)
                added_symbols.Next = null;
            
            if (SystemUnitAssigned && in_check_range_region() && name == compiler_string_consts.assign_name && is_range_checkable(left.type) && is_range_checkable(right.type))
            {
            	ordinal_type_interface oti = left.type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface;
            	if (left.type != SystemLibrary.SystemLibrary.char_type && left.type != SystemLibrary.SystemLibrary.uint64_type && !(oti.lower_value is ulong_const_node))
            	if(!(oti.lower_value is enum_const_node) && !(oti.lower_value is char_const_node))
            		right = convertion_data_and_alghoritms.convert_type(convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.CheckRangeFunction.sym_info as common_namespace_function_node, null, convertion_data_and_alghoritms.convert_type(right,SystemLibrary.SystemLibrary.int64_type), convertion_data_and_alghoritms.convert_type(oti.lower_value,SystemLibrary.SystemLibrary.int64_type),convertion_data_and_alghoritms.convert_type(oti.upper_value,SystemLibrary.SystemLibrary.int64_type)),right.type);
            	else if (oti.lower_value is enum_const_node)
            	{
            		right = convertion_data_and_alghoritms.explicit_convert_type(convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.CheckRangeFunction.sym_info as common_namespace_function_node, null, convertion_data_and_alghoritms.explicit_convert_type(right,SystemLibrary.SystemLibrary.int64_type),
            		                                                                                                               convertion_data_and_alghoritms.explicit_convert_type(oti.lower_value,SystemLibrary.SystemLibrary.int64_type),convertion_data_and_alghoritms.explicit_convert_type(oti.upper_value,SystemLibrary.SystemLibrary.int64_type)),right.type);
            	}
            	else if (oti.lower_value is char_const_node)
            	right = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.CheckCharRangeFunction.sym_info as common_namespace_function_node, null, right, oti.lower_value,oti.upper_value);	
            }
            expression_node exp_node = convertion_data_and_alghoritms.create_simple_function_call(fnsel, loc, left, right);
            return exp_node;
        }
        /// <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;
		}
        /// <summary>
        /// Этот метод вызывается если мы встречаем простой вызов функии, например f(1).
        /// Он определяет является ли эта функция методом класса, вложенной функцией и т.д. и создает соответствующее обращение.
        /// Например, для метода класса он добавляет this, а для вложенной функции вычисляет статическую глубину.
        /// </summary>
        /// <param name="exprs">Список параметров.</param>
        /// <param name="si">Список методов.</param>
        /// <param name="loc">Расположение вызова.</param>
        /// <param name="converted_type">Тип в котором мы находимся. null, если мы вне типа.</param>
        /// <param name="top_function">Функция в которой мы находимся.</param>
        /// <param name="allow_procedure">Может ли это быть вызов процедуры. false если вызов стоит в выражении или правой части опреатора присваивания.</param>
        /// <returns>Возвращает узел вызова метода.</returns>
		public expression_node create_full_function_call(expressions_list exprs,SymbolInfo si,location loc,
			common_type_node converted_type,common_function_node top_function,bool allow_procedure)
		{
			function_node fn=select_function(exprs,si,loc);

            /*
            if (fn.compile_time_executor != null)
            {
                expression_node ex = fn.compile_time_executor(loc, exprs.ToArray());
                if (ex != null)
                {
                    return ex;
                }
            }
            */
            //allow_procedure = true;
			if ((!allow_procedure)&&(fn.return_value_type==null))
			{
                throw new SimpleSemanticError(loc, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", fn.name);
			}

			expression_node expr_node=null;
			switch (fn.semantic_node_type)
			{
				case semantic_node_type.basic_function_node:
				case semantic_node_type.common_namespace_function_node:
				{
					expr_node=create_simple_function_call(fn,loc,exprs.ToArray());
					break;
				}
				case semantic_node_type.common_method_node:
				case semantic_node_type.compiled_function_node:
				{
					SemanticTree.IClassMemberNode icmn=(SemanticTree.IClassMemberNode)fn;
					if (icmn.polymorphic_state==SemanticTree.polymorphic_state.ps_static)
					{
						expr_node=create_simple_function_call(fn,loc,exprs.ToArray());
						break;
					}
                    //expression_node tn = new this_node(converted_type,loc);
					base_function_call cmc=null;
					switch (fn.semantic_node_type)
					{
						case semantic_node_type.common_method_node:
						{
                            //ssyy добавил
                            if (((common_method_node)fn).is_constructor)
                            {
                                common_constructor_call ccc = new common_constructor_call((common_method_node)fn, loc);
                                //(ssyy) По-видимому, здесь всегда можно присваивать false, так как при создании нового объекта мы сюда не заходим...
                                ccc._new_obj_awaited = false;
                                if (!syntax_tree_visitor.context.allow_inherited_ctor_call)
                                {
                                    throw new SimpleSemanticError(loc, "INHERITED_CONSTRUCTOR_CALL_MUST_BE_FIRST");
                                }
                                cmc = ccc;
                            }
                            else
                            //\ssyy
                            {
                                cmc = new common_method_call((common_method_node)fn, syntax_tree_visitor.GetCurrentObjectReference(((common_method_node)fn).cont_type.Scope, fn, loc), loc);
                                (cmc as common_method_call).virtual_call = !syntax_tree_visitor.inherited_ident_processing;
                            }
							break;
						}
						case semantic_node_type.compiled_function_node:
						{
                            cmc = new compiled_function_call((compiled_function_node)fn, syntax_tree_visitor.GetCurrentObjectReference(((compiled_function_node)fn).cont_type.Scope, fn, loc), loc);
                            (cmc as compiled_function_call).virtual_call = !syntax_tree_visitor.inherited_ident_processing;
							break;
						}
					}
					cmc.parameters.AddRange(exprs);
					expr_node=cmc;
					break;
				}
				case semantic_node_type.common_in_function_function_node:
				{
					common_in_function_function_node cffn=(common_in_function_function_node)fn;
					common_in_function_function_call cffc=new common_in_function_function_call(cffn,
						symtab.GetRelativeScopeDepth(cffn.function.scope,top_function.scope),loc);
					cffc.parameters.AddRange(exprs);
					expr_node=cffc;
					break;
				}
                //ssyy добавил
                case semantic_node_type.compiled_constructor_node:
                {
                    compiled_constructor_node ccn = fn as compiled_constructor_node;
                    if (ccn == null)
                    {
                        throw new CompilerInternalError("compiled_constructor_node expected");
                    }
                    compiled_constructor_call ccc = new compiled_constructor_call(ccn, loc);
                    ccc.parameters.AddRange(exprs);
                    ccc._new_obj_awaited = false;
                    if (!syntax_tree_visitor.context.allow_inherited_ctor_call)
                    {
                        throw new SimpleSemanticError(loc, "INHERITED_CONSTRUCTOR_CALL_MUST_BE_FIRST");
                    }
                    expr_node = ccc;
                    break;
                }
                case semantic_node_type.indefinite_definition_node:
                {
                    indefinite_function_call ifc = new indefinite_function_call(fn, loc);
                    ifc.parameters.AddRange(exprs);
                    expr_node = ifc;
                    break;
                }
                //\ssyy
				default:
				{
                    throw new NotSupportedError(loc);
				}
			}
			return expr_node;
		}
		//Первый параметр - выходной. Он содержит выражения с необходимыми преобразованиями типов.
        public function_node select_function(expressions_list parameters, SymbolInfo functions, location loc, List<SyntaxTree.expression> syntax_nodes_parameters = null)
		{
			if (functions==null)
			{
				AddError(new NoFunctionWithThisName(loc));
			}

            function_node_list set_of_possible_functions = new function_node_list();

            bool is_alone_method_defined = (functions.Next == null);
            function_node first_function = functions.sym_info as function_node;
            bool _is_assigment = first_function.name == compiler_string_consts.assign_name;
            basic_function_node _tmp_bfn = functions.sym_info as basic_function_node;

            List<function_node> indefinits = new List<function_node>();

			while(functions!=null)
			{
#if (DEBUG)
				if (functions.sym_info.general_node_type!=general_node_type.function_node && functions.sym_info.general_node_type != general_node_type.property_node)
				{
					throw new CompilerInternalError("Function name is used to define another kind of object.");
				}
#endif
                function_node fn = null;
                if (functions.sym_info.general_node_type == general_node_type.property_node)
                {
                    fn = (functions.sym_info as property_node).get_function;
                }
                else
                fn=(function_node)functions.sym_info;

                if (fn.node_kind == node_kind.indefinite)
                {
                    indefinits.Add(fn);
                }
				else if (fn.node_kind==SemanticTree.node_kind.common)
				{
					common_function_node cfn=(common_function_node)fn;
					if ((parameters.Count>=cfn.parameters.Count-cfn.num_of_default_variables)&&
					    (parameters.Count<=cfn.parameters.Count) || parameters.Count == 0 && cfn.parameters.Count == 1 && cfn.parameters[0].is_params)
					{
						if (is_exist_eq_method_in_list(fn,set_of_possible_functions) != null)
						{
                            //!!!!!!!!!!!!!
                            //DS TODO
                            //Это нужно чтобы была возможность создавать операторы = := ..., т.к. всегда они добавляюся автоматом
                            //Надо сначало просматривать заголовки и добавлять такие операторы только если нужно.
                            if (set_of_possible_functions.Count > 0)
                                if (set_of_possible_functions[0] is basic_function_node)
                                {
                                    set_of_possible_functions.remove(set_of_possible_functions[0]);
                                    set_of_possible_functions.AddElement(fn);
                                }
                            //!!!!!!!!!!!!!
							
                            functions=functions.Next;
							continue;
						}
						set_of_possible_functions.AddElement(fn);
					}
				}
				else
				{
                    //TODO: Здесь нужно поправить, если создавать возможность вызова метода с параметрами по умолчанию из откомпилированной dll.
					if (parameters.Count==fn.parameters.Count)
					{
                        function_node func = null;
                        if ((func=is_exist_eq_method_in_list(fn,set_of_possible_functions)) != null)
						{
                            if (!eq_type_nodes(fn.return_value_type, func.return_value_type))
                            {
                                set_of_possible_functions[set_of_possible_functions.IndexOf(func)] = fn;
                                
                            }
                            functions = functions.Next;
                            continue;
						}
						set_of_possible_functions.AddElement(fn);
					}
				}
                if (parameters.Count > fn.parameters.Count)
                {
                    if (fn.parameters.Count > 0)
                    {
                        if ((fn.parameters[fn.parameters.Count - 1]).is_params)
                        {
                            //+DS ms0105
                            if (is_exist_eq_method_in_list(fn, set_of_possible_functions) != null)
                            {
                                functions = functions.Next;
                                continue;
                            }
                            //-DS
                            set_of_possible_functions.AddElement(fn);
                        }
                    }
                }
                else if ((parameters.Count == 0 && fn.parameters.Count == 1) && fn.parameters[0].is_params && !set_of_possible_functions.Contains(fn))
                    set_of_possible_functions.AddElement(fn);
                else if (fn.num_of_default_parameters != 0 && parameters.Count >= fn.parameters.Count - fn.num_of_default_parameters)
                {
                    if (!set_of_possible_functions.Contains(fn))
                        set_of_possible_functions.AddElement(fn);
                }
                else if (parameters.Count == 1 && fn is common_namespace_function_node && (fn as common_namespace_function_node).ConnectedToType != null && fn.parameters.Count == 2 && fn.parameters[1].is_params)
                    set_of_possible_functions.AddElement(fn);
                functions=functions.Next;
			}

			if (set_of_possible_functions.Count==0 && indefinits.Count == 0)
			{
                AddError(new NoFunctionWithSameParametresNum(loc, is_alone_method_defined, first_function));
			}

            //(ssyy) Инициализируем is_alone_defined
            FailedWhileTryingToCompileLambdaBodyWithGivenParametersException lastFailedWhileTryingToCompileLambdaBodyWithGivenParametersException = null;

            if (set_of_possible_functions.Count == 1 && indefinits.Count == 0)
            {
                is_alone_method_defined = true;
            }

            //(ssyy) Инстанцируем дженерики
            for (int i = set_of_possible_functions.Count - 1; i > -1; --i)
            {
                function_node func = set_of_possible_functions[i];
                if (func.is_generic_function)
                {
                    try
                    {

                        function_node inst = generic_convertions.DeduceFunction(func, parameters,
                                                                                is_alone_method_defined, loc, syntax_nodes_parameters);
                        if (inst == null)
                        {
                            set_of_possible_functions.remove_at(i);
                        }
                        else
                        {
                            set_of_possible_functions[i] = inst;
                        }
                    }
                    catch (FailedWhileTryingToCompileLambdaBodyWithGivenParametersException exc) //lroman Отлавливаем последнее исключение, которое возникло при попытке скомпилировать тело лямбды с заданными типами параметров
                    {
                        set_of_possible_functions.remove_at(i);
                        lastFailedWhileTryingToCompileLambdaBodyWithGivenParametersException = exc;
                    }
                }
            }

            if (lastFailedWhileTryingToCompileLambdaBodyWithGivenParametersException != null
                && set_of_possible_functions.Count == 0
                && indefinits.Count == 0)
            {
                throw lastFailedWhileTryingToCompileLambdaBodyWithGivenParametersException.ExceptionOnCompileBody;  // Если перебрали все, но ничто не подошло, то кидаем последнее исключение
            }

            if (set_of_possible_functions.Count == 0 && indefinits.Count == 0)
            {
                AddError(loc, "CAN_NOT_CALL_ANY_GENERIC_FUNCTION_{0}_WITH_THESE_PARAMETERS", first_function.name);
            }

            possible_type_convertions_list_list tcll = new possible_type_convertions_list_list();

			for(int i=0;i<set_of_possible_functions.Count;i++)
			{
				possible_type_convertions_list tc=get_conversions(parameters,set_of_possible_functions[i].parameters,
					is_alone_method_defined,loc);
				tcll.AddElement(tc);
			}

			int j=0;
			while(j<set_of_possible_functions.Count)
			{
				if (tcll[j]==null && set_of_possible_functions[j].node_kind != node_kind.indefinite)
				{
					tcll.remove_at(j);
					set_of_possible_functions.remove_at(j);
				}
				else
				{
					j++;
				}
			}

			if (set_of_possible_functions.Count==0 && indefinits.Count == 0)
			{
                if (_is_assigment && parameters.Count == 2)
                    AddError(new CanNotConvertTypes(parameters[1], parameters[1].type, parameters[0].type, parameters[1].location));
                if (_tmp_bfn != null && parameters.Count == 2)
                    AddError(new OperatorCanNotBeAppliedToThisTypes(_tmp_bfn.name, parameters[0], parameters[1],loc));
				AddError(new NoFunctionWithSameArguments(loc,is_alone_method_defined));
			}

			bool remove=true;
			
			while(remove)
			{
				if (set_of_possible_functions.Count==1)
				{
					check_single_possible_convertion(loc,tcll[0]);
					convert_function_call_expressions(set_of_possible_functions[0],parameters,tcll[0]);
					return set_of_possible_functions[0];
				}
				remove=false;

                var i = 0;
                while (i < set_of_possible_functions.Count-1)
                {
                    j = i+1;
                    while (j < set_of_possible_functions.Count)
                    {
                        method_compare mc = compare_methods(set_of_possible_functions[i],
                            set_of_possible_functions[j], tcll[i], tcll[j]);
                        if (mc == method_compare.greater_method)
                        {
                            tcll.remove_at(j);
                            set_of_possible_functions.remove_at(j);
                            remove = true;
                        }
                        else if (mc == method_compare.less_method)
                        {
                            tcll[i] = tcll[j];
                            set_of_possible_functions[i] = set_of_possible_functions[j];
                            tcll.remove_at(j);
                            set_of_possible_functions.remove_at(j);
                            remove = true;
                        }
                        else
                        {
                            j++;
                        }
                    }
                    i++;
                }

            }

            // TODO: Исправить этот алгоритм, сделав каждый с каждым - вроде исправил - см. выше
            /*j = 1;
				while(j<set_of_possible_functions.Count)
				{
                    method_compare mc = compare_methods(set_of_possible_functions[0],
                        set_of_possible_functions[j], tcll[0], tcll[j]);
					if (mc==method_compare.greater_method)
					{
						tcll.remove_at(j);
						set_of_possible_functions.remove_at(j);
						remove=true;
					}
					else if (mc==method_compare.less_method)
					{
						tcll[0]=tcll[j];
						set_of_possible_functions[0]=set_of_possible_functions[j];
						tcll.remove_at(j);
						set_of_possible_functions.remove_at(j);
						remove=true;
					}
					else
					{
						j++;
					}
				}
			}*/

            /*remove=true;
            while (remove)
            {
                if (set_of_possible_functions.Count == 1)
                {
                    check_single_possible_convertion(loc, tcll[0]);
                    convert_function_call_expressions(set_of_possible_functions[0], parameters, tcll[0]);
                    return set_of_possible_functions[0];
                }
                remove = false;
                j = 1;
                while (j < set_of_possible_functions.Count)
                {

                }
            }*/
			//Тут некоторое дублирование кода, но сюда программа не должна никогда зайти.
			//Должен быть выполнен if выше.
			//Но пусть пока повисит. Потом нужно разобраться и убрать.
			/*if (set_of_possible_functions.Count==1)
			{
				check_single_possible_conversion(func_call,tcll[0]);
				func_call.function=set_of_possible_functions[0];
				convert_function_call_expressions(func_call,tcll[0]);
				func_call.type=func_call.function.return_value_type;
				return func_call;
			}*/

            //Тупая заглушка для примитивных типов. иначе не работает +=, у нас лишком много неявных приведений
            //в дальнейшем может вызвать странное поведение, это надо проверить
            if (set_of_possible_functions.Count == 2 && indefinits.Count == 0)
                if (set_of_possible_functions[0] is basic_function_node && set_of_possible_functions[1] is basic_function_node)
                    return set_of_possible_functions[0];

            if (indefinits.Count > 0)
            {
                if (indefinits.Count == 1 && set_of_possible_functions.Count == 0)
                {
                    return indefinits[0];
                }
                indefinits.AddRange(set_of_possible_functions);
                return new indefinite_functions_set(indefinits);
            }

            bool exist_indefinite_parameter = false;
            foreach (expression_node par in parameters)
            {
                if (par.type.depended_from_indefinite)
                {
                    exist_indefinite_parameter = true;
                    break;
                }
            }
            if (exist_indefinite_parameter)
            {
                indefinits.AddRange(set_of_possible_functions);
                return new indefinite_functions_set(indefinits);
            }
			
            AddError(new SeveralFunctionsCanBeCalled(loc,set_of_possible_functions));
            return null;
		}
		private void convert_function_call_expressions(function_node fn,expressions_list exprs,
			possible_type_convertions_list ptcal)
		{
			/*if (SystemLibrary.SystemLibrary.syn_visitor.SystemUnitAssigned && fn.name != compiler_string_consts.assign_name && !SystemLibrary.SystemLibrary.syn_visitor.one_way_operation(fn.name) && SystemLibrary.SystemLibrary.syn_visitor.in_check_range_region())
            {
				for (int i=0; i<exprs.Count; i++)
				{
					if (exprs[i] is statements_expression_node)
						break;
					expression_node right = exprs[i];
					if (fn.parameters.Count <= i)
						break;
					if (fn.parameters[i].parameter_type == parameter_type.var)
						continue;
					type_node left_type = fn.parameters[i].type;
					
					if (SystemLibrary.SystemLibrary.syn_visitor.is_range_checkable(left_type) && SystemLibrary.SystemLibrary.syn_visitor.is_range_checkable(exprs[i].type))
					{
						ordinal_type_interface oti = left_type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface;
            			if (left_type != SystemLibrary.SystemLibrary.char_type) 
            			if(!(oti.lower_value is enum_const_node) && !(oti.lower_value is char_const_node))
            			right = SystemLibrary.SystemLibrary.syn_visitor.convertion_data_and_alghoritms.convert_type(SystemLibrary.SystemLibrary.syn_visitor.convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.CheckRangeFunction.sym_info as common_namespace_function_node, null, SystemLibrary.SystemLibrary.syn_visitor.convertion_data_and_alghoritms.convert_type(right,SystemLibrary.SystemLibrary.int64_type), 
            				                                                                                                                                                                                               SystemLibrary.SystemLibrary.syn_visitor.convertion_data_and_alghoritms.convert_type(oti.lower_value,SystemLibrary.SystemLibrary.int64_type),SystemLibrary.SystemLibrary.syn_visitor.convertion_data_and_alghoritms.convert_type(oti.upper_value,SystemLibrary.SystemLibrary.int64_type)),right.type);
            			else if (oti.lower_value is enum_const_node)
            			{
            				right = SystemLibrary.SystemLibrary.syn_visitor.convertion_data_and_alghoritms.explicit_convert_type(SystemLibrary.SystemLibrary.syn_visitor.convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.CheckRangeFunction.sym_info as common_namespace_function_node, null, SystemLibrary.SystemLibrary.syn_visitor.convertion_data_and_alghoritms.explicit_convert_type(right,SystemLibrary.SystemLibrary.int64_type),
            		                                                                                                               SystemLibrary.SystemLibrary.syn_visitor.convertion_data_and_alghoritms.explicit_convert_type(oti.lower_value,SystemLibrary.SystemLibrary.int64_type),SystemLibrary.SystemLibrary.syn_visitor.convertion_data_and_alghoritms.explicit_convert_type(oti.upper_value,SystemLibrary.SystemLibrary.int64_type)),right.type);
            			}
            			else if (oti.lower_value is char_const_node)
            			right = SystemLibrary.SystemLibrary.syn_visitor.convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.CheckCharRangeFunction.sym_info as common_namespace_function_node, null, right, oti.lower_value,oti.upper_value);
					
					}
					exprs[i] = right;
				}
            }*/
			for(int i=0;i<exprs.Count;i++)
			{
                if ((ptcal.snl != null) && (i >= fn.parameters.Count - 1))
                {
                    //statement_list_stack.top().statements.AddRange(ptcal.snl);
                    statements_expression_node sre = new statements_expression_node(ptcal.snl, ptcal.var_ref, ptcal.var_ref.location);
                    exprs.remove_range(fn.parameters.Count - 1, exprs.Count - fn.parameters.Count);
                    //exprs.AddElement(ptcal.var_ref);
                    //exprs[i] = ptcal.var_ref;
                    exprs[i] = sre;
                    break;
                }
                if ((ptcal[i]==null)||(ptcal[i].first==null)||exprs[i] is null_const_node)
				{
					continue;
				}
                expression_node[] temp_arr = new expression_node[1];
                temp_arr[0] = exprs[i];
                if (ptcal[i].first.convertion_method is compiled_constructor_node)
                    exprs[i] = create_compiled_construcor_call(ptcal[i].first.convertion_method as compiled_constructor_node, get_location(exprs[i]), temp_arr);
                else
                    exprs[i] = create_simple_function_call(ptcal[i].first.convertion_method, get_location(exprs[i]), temp_arr);
			}
            //TODO: Можно сделать параметры по умолчанию для откомпилированных функций.
            if ((exprs.Count < fn.parameters.Count) && (fn.node_kind == SemanticTree.node_kind.common))
            {
                if (exprs.Count == 0 && fn.parameters != null && fn.parameters.Count == 1 && fn.parameters[0].is_params ||
                    exprs.Count == 1 && fn.parameters != null && fn is common_namespace_function_node && (fn as common_namespace_function_node).ConnectedToType != null &&
                    fn.parameters.Count == 2 && fn.parameters[1].is_params)
                {
                    statements_expression_node sre = new statements_expression_node(ptcal.snl, ptcal.var_ref, ptcal.var_ref.location);
                    //exprs.remove_range(fn.parameters.Count - 1, exprs.Count - fn.parameters.Count);
                    //exprs.AddElement(ptcal.var_ref);
                    //exprs[i] = ptcal.var_ref;
                    exprs.AddElement(sre);
                }
                common_function_node cfn = (common_function_node)fn;
                for (int j = exprs.Count; j < cfn.parameters.Count; j++)
                {
                    common_parameter cp = (common_parameter)cfn.parameters[j];
                    if (cp.default_value != null)
                        exprs.AddElement(cp.default_value);
                }
            }
            else if ((exprs.Count < fn.parameters.Count) && (fn.node_kind == SemanticTree.node_kind.compiled))
            {
                if (exprs.Count == 0 && fn.parameters != null && fn.parameters.Count == 1 && fn.parameters[0].is_params)
                {
                    statements_expression_node sre = new statements_expression_node(ptcal.snl, ptcal.var_ref, ptcal.var_ref.location);
                    exprs.AddElement(sre);
                }
                //compiled_function_node cfn = (compiled_function_node)fn;
                for (int j = exprs.Count; j < fn.parameters.Count; j++)
                {
                    compiled_parameter cp = (compiled_parameter)fn.parameters[j];
                    if (cp.default_value != null)
                        exprs.AddElement(cp.default_value);
                }
            }
			
		}
        private base_function_call_list convert_functions_to_calls(expression_node obj, function_node_list fnl, location loc, bool is_static)
        {
            base_function_call_list ret = new base_function_call_list();
            foreach (function_node fnode in fnl)
            {
                base_function_call bfc = null;
                switch (fnode.semantic_node_type)
                {
                    case semantic_node_type.common_namespace_function_node:
                        {
                            common_namespace_function_node cmfn = fnode as common_namespace_function_node;
                            common_namespace_function_call cnfc = new common_namespace_function_call(cmfn, loc);
                            if (cmfn.ConnectedToType != null)
                                cnfc.parameters.AddElement(obj);
                            if (cmfn.is_generic_function && !cmfn.is_generic_function_instance && cmfn.ConnectedToType != null && cmfn.parameters.Count == 1)
                            {
                                expressions_list parameters = new expressions_list();
                                parameters.AddElement(obj);
                                function_node inst = null;
                                try
                                {
                                    inst = generic_convertions.DeduceFunction(cmfn, parameters, true, loc);
                                }
                                catch
                                {
                                    continue;
                                }
                                cnfc = new common_namespace_function_call((common_namespace_function_node)inst, loc);
                                if (cmfn.ConnectedToType != null)
                                    cnfc.parameters.AddElement(obj);
                            }
                            /*if (cmfn.parameters.Count >= 1 && cmfn.parameters[cmfn.parameters.Count - 1].is_params)
                            {
                                convertion_data_and_alghoritms.select_function(cnfc.parameters, new SymbolInfo(cmfn), loc);
                                
                            }*/
                            bfc = cnfc;
                            break;
                        }
                    case semantic_node_type.basic_function_node:
                        {
                            //Может здесь стоит и выругаться, но я не буду пока этого делать.
                            break;
                        }
                    case semantic_node_type.common_in_function_function_node:
                        {
                            common_in_function_function_node ciffn = fnode as common_in_function_function_node;
                            int depth = convertion_data_and_alghoritms.symbol_table.GetRelativeScopeDepth(ciffn.scope,
                                context.top_function.scope);
                            common_in_function_function_call ciffc = new common_in_function_function_call(ciffn, depth, loc);
                            bfc = ciffc;
                            break;
                        }
                    case semantic_node_type.common_method_node:
                        {
                            common_method_node cmn = fnode as common_method_node;
                            //Если cmn конструктор - то плохо, но его не должно сюда попасть.
                            if (cmn.polymorphic_state != SemanticTree.polymorphic_state.ps_static)
                            {
                                if (!is_static)
                                {
                                    if (obj == null)
                                        obj = GetCurrentObjectReference(cmn.cont_type.Scope, cmn, loc);//new this_node(context.converted_type, loc);
                                    common_method_call cmc = new common_method_call(cmn, obj, loc);
                                    cmc.virtual_call = !inherited_ident_processing;
                                    bfc = cmc;
                                }
                                //ssyy!!! Мне сложно понять предназначение данного кода, но, по-видимому,
                                //следует его переписать так.
                                else if (cmn.is_constructor)
                                {
                                    if (cmn.parameters.Count == 0)
                                    {
                                    	if (cmn.cont_type.IsAbstract)
                                            AddError(loc, "ABSTRACT_CONSTRUCTOR_{0}_CALL", cmn.cont_type.name);
                                    	ret.clear();
                                        ret.AddElement(new common_constructor_call(cmn, loc));
                                        return ret;
                                    }
                                }
                            }
                            else
                            {
                                if (is_static)
                                {
                                    common_static_method_call csmc = new common_static_method_call(cmn, loc);
                                    bfc = csmc;
                                }
                            }
                            break;
                        }
                    case semantic_node_type.compiled_function_node:
                        {
                            compiled_function_node cfn = fnode as compiled_function_node;
                            if (cfn.cont_type.Scope == null && cfn is compiled_function_node)
                        	(cfn.cont_type as compiled_type_node).init_scope();
                            
                            if (cfn.polymorphic_state == SemanticTree.polymorphic_state.ps_static)
                            {
                                //ispravleno ibond
                            	//if (is_static)
                                {

                                    if (cfn.is_generic_function && !cfn.is_generic_function_instance && cfn.ConnectedToType != null && cfn.parameters.Count == 1)
                                    {
                                        expressions_list parameters = new expressions_list();
                                        parameters.AddElement(obj);
                                        function_node inst = null;
                                        try
                                        {
                                            inst = generic_convertions.DeduceFunction(cfn, parameters, true, loc);
                                        }
                                        catch
                                        {
                                            continue;
                                        }
                                        if (inst is common_namespace_function_node)
                                            bfc = new common_namespace_function_call((common_namespace_function_node)inst, loc);
                                        else if (inst is compiled_function_node)
                                            bfc = new compiled_static_method_call((compiled_function_node)inst, loc);
                                        else
                                            bfc = new compiled_static_method_call(cfn, loc);
                                    }
                                    else
                                    {
                                        compiled_static_method_call csmc = new compiled_static_method_call(cfn, loc);
                                        bfc = csmc;
                                        
                                    }
                                    if (cfn.ConnectedToType != null)
                                        bfc.parameters.AddElement(obj);
                                }
                            }
                            else
                            {
                                if (!is_static)
                                {
                                    if (obj == null)
                                        obj = GetCurrentObjectReference(cfn.cont_type.Scope, cfn, loc);//new this_node(context.converted_type, loc);
                                    compiled_function_call cfc = new compiled_function_call(cfn, obj, loc);
                                    cfc.virtual_call = !inherited_ident_processing;
                                    bfc = cfc;
                                }
                            }
                            break;
                        }
                    case semantic_node_type.compiled_constructor_node:
                        {
                            //Этот код мы вроде не должны вызывать, но если он все-же вызовется.
                            compiled_constructor_node ccn = fnode as compiled_constructor_node;
                            compiled_constructor_call ccc = new compiled_constructor_call(ccn, loc);
                            bfc = ccc;
                            break;
                        }
                    default:
                        {
                            throw new CompilerInternalError("Undefined method type.");
                        }
                }
                if (bfc != null)
                {
                    ret.AddElement(bfc);
                }
            }
            return ret;
        }
        internal expression_node get_init_call_for_short_string(var_definition_node vdn)
        {
            location loc = (vdn.type as short_string_type_node).loc;

            type_node tn = vdn.type;
            //vdn.type = SystemLibrary.SystemLibInitializer.ShortStringType.TypeNode;
			vdn.type = SystemLibrary.SystemLibrary.string_type;
            int Length = (tn as short_string_type_node).Length;

            expression_node var_ref = create_variable_reference(vdn, loc);
            expressions_list exl = new expressions_list();
            exl.AddElement(var_ref);
            exl.AddElement(new int_const_node(Length, loc));
            expression_node expr = null;
            //if (SystemLibrary.SystemLibInitializer.ShortStringTypeInitProcedure != null)
            //convertion_data_and_alghoritms.create_full_function_call(exl, SystemLibrary.SystemLibInitializer.ShortStringTypeInitProcedure.SymbolInfo, null, context.converted_type, context.top_function, true);

            vdn.type = tn;

            return expr;
        }
 private expression_node inherited_message_value_reciving(SyntaxTree.inherited_message _ident)
 {
 	SymbolInfo si = find_in_base(_ident);
 	bool constr = false;
     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(_ident), "CANNOT_CALL_ABSTRACT_METHOD");
     	constr = (si.sym_info as common_method_node).is_constructor;
     }
     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(_ident), "CANNOT_CALL_ABSTRACT_METHOD");
     }
     else if (si.sym_info is compiled_constructor_node)
     {
     	constr = true;
     }
     location loc = get_location(_ident);
     function_node fn = si.sym_info as function_node;
     base_function_call bfc = null;
     common_function_node cfn = context.converted_func_stack.first();
     int depth = context.converted_func_stack.size-1;
     if (!constr)
     {
     	if (fn.polymorphic_state != SemanticTree.polymorphic_state.ps_static)
     	{
     		bfc = create_not_static_method_call(fn,new this_node(context.converted_type,loc),loc,true);
     		if (bfc is common_method_call)
     			(bfc as common_method_call).virtual_call = false;
     		else 
     			(bfc as compiled_function_call).virtual_call = false;
     	}
     	else if (fn is common_method_node)
     		bfc = create_static_method_call(fn,loc,(fn as common_method_node).cont_type,true);
     	else if (fn is compiled_function_node)
     		bfc = create_static_method_call(fn,loc,(fn as compiled_function_node).cont_type,true);
     	else
     		throw new NotSupportedError(loc);
     }
     else
     {
     	if (!context.allow_inherited_ctor_call)
             AddError(loc, "INHERITED_CONSTRUCTOR_CALL_MUST_BE_FIRST");
     	expressions_list exprs = new expressions_list();
     	foreach (common_parameter cp in cfn.parameters)
     	{
     		exprs.AddElement(new common_parameter_reference(cp,depth,loc));
     	}
     	if (fn is common_method_node)
     	{
     		common_constructor_call ccc = create_constructor_call((fn as common_method_node).cont_type,exprs,loc) as common_constructor_call;
     		ccc._new_obj_awaited = false;
     		return ccc;
     	}
     	else if (fn is compiled_constructor_node)
     	{
     		compiled_constructor_call ccc = create_constructor_call((fn as compiled_constructor_node).compiled_type,exprs,loc) as compiled_constructor_call;
     		ccc._new_obj_awaited = false;
     		return ccc;
     	}
     	else
     	throw new NotSupportedError(loc);
     }
     
     foreach (common_parameter cp in cfn.parameters)
     {
     	bfc.parameters.AddElement(new common_parameter_reference(cp,depth,loc));
     }
     return bfc;
 }
 private void add_set_initializer(expression_node cnfc, expressions_list exprs)
 {
     set_intls[cnfc] = exprs;
 }
        public override void visit(SyntaxTree.assign _assign)
        {
        	internal_is_assign = true;
        	addressed_expression to = convert_address_strong(_assign.to);
        	internal_is_assign = false;
            if (to == null)
            	AddError(get_location(_assign.to), "CAN_NOT_ASSIGN_TO_LEFT_PART");


            #region Вывод параметров лямбда-выражения
            var fld1 = _assign.from as SyntaxTree.function_lambda_definition;
            if (fld1 != null)
            {
                MaybeConvertFunctionLambdaDefinitionToProcedureLambdaDefinition(fld1);
                LambdaHelper.InferTypesFromVarStmt(to.type, _assign.from as SyntaxTree.function_lambda_definition, this);  //lroman//
            }
            
            #endregion
			

            //(ssyy) Вставляю проверки прямо сюда, т.к. запарился вылавливать другие случаи.
            bool flag=false;
            general_node_type node_type = general_node_type.constant_definition;
            if (convertion_data_and_alghoritms.check_for_constant_or_readonly(to, out flag, out node_type))
            {
            	if (flag)
                    AddError(to.location, "CAN_NOT_ASSIGN_TO_CONSTANT_OBJECT");
            	else
            		AddError(new CanNotAssignToReadOnlyElement(to.location,node_type));
            }

            //expression_node from = convert_strong(_assign.from);
            /// SSM исправление Саушкина 10.03.16
            expression_node from;
            var fromAsLambda = _assign.from as function_lambda_definition;
            if (fromAsLambda != null)
            {
                var lambdaVisitMode = fromAsLambda.lambda_visit_mode;
                fromAsLambda.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing;
                from = convert_strong(_assign.from);
                fromAsLambda.lambda_visit_mode = lambdaVisitMode;
            }
            else
            {
                from = convert_strong(_assign.from);
            }
            /// end

            //SSM 4.04.16
            if (to.type is undefined_type)
                to.type = from.type;

            if (stflambda.Count>0) // мы находимся внутри лямбды - возможно, вложенной
            {
                var fld = stflambda.Peek();
                if (_assign.to is ident && (_assign.to as ident).name.ToLower()=="result" && fld.RealSemTypeOfResExpr == null) // если это - первое присваивание Result
                {
                    fld.RealSemTypeOfResExpr = from.type;
                    fld.RealSemTypeOfResult = to.type;
                }
                    
            }

            location loc = get_location(_assign);
			bool oper_ass_in_prop = false;
			
            //проверка на обращение к полю записи возвращенной из функции с целью присваивания
            //нужно чтобы пользователь не мог менять временный обьект
            if (to.semantic_node_type == semantic_node_type.static_property_reference ||
                to.semantic_node_type == semantic_node_type.non_static_property_reference)
            {
                property_node pn = null;
                base_function_call prop_expr = null;
                if (to.semantic_node_type == semantic_node_type.static_property_reference)
                	pn = (to as static_property_reference).property;
                else
                	pn = (to as non_static_property_reference).property;
               
                PascalABCCompiler.SyntaxTree.Operators ot = PascalABCCompiler.SyntaxTree.Operators.Undefined;
            	switch (_assign.operator_type)
                {
                    case PascalABCCompiler.SyntaxTree.Operators.AssignmentAddition:
                		ot = PascalABCCompiler.SyntaxTree.Operators.Plus;
                		oper_ass_in_prop = true;
                		break;
                    case PascalABCCompiler.SyntaxTree.Operators.AssignmentBitwiseAND:
                		ot = PascalABCCompiler.SyntaxTree.Operators.BitwiseAND;
                		oper_ass_in_prop = true;
                		break;
                    case PascalABCCompiler.SyntaxTree.Operators.AssignmentBitwiseLeftShift:
                		ot = PascalABCCompiler.SyntaxTree.Operators.BitwiseLeftShift;
                		oper_ass_in_prop = true;
                		break;
                    case PascalABCCompiler.SyntaxTree.Operators.AssignmentBitwiseOR:
                		ot = PascalABCCompiler.SyntaxTree.Operators.BitwiseOR;
                		oper_ass_in_prop = true;
                		break;
                    case PascalABCCompiler.SyntaxTree.Operators.AssignmentBitwiseRightShift:
                		ot = PascalABCCompiler.SyntaxTree.Operators.BitwiseRightShift;
                		oper_ass_in_prop = true;
                		break;
                    case PascalABCCompiler.SyntaxTree.Operators.AssignmentBitwiseXOR:
                		ot = PascalABCCompiler.SyntaxTree.Operators.BitwiseXOR;
                		oper_ass_in_prop = true;
                		break;
                    case PascalABCCompiler.SyntaxTree.Operators.AssignmentDivision:
                		ot = PascalABCCompiler.SyntaxTree.Operators.Division;
                		oper_ass_in_prop = true;
                		break;
                    case PascalABCCompiler.SyntaxTree.Operators.AssignmentModulus:
                		ot = PascalABCCompiler.SyntaxTree.Operators.ModulusRemainder;
                		oper_ass_in_prop = true;
                		break;
                    case PascalABCCompiler.SyntaxTree.Operators.AssignmentMultiplication:
                		ot = PascalABCCompiler.SyntaxTree.Operators.Multiplication;
                		oper_ass_in_prop = true;
                		break;
                    case PascalABCCompiler.SyntaxTree.Operators.AssignmentSubtraction:
                        ot = PascalABCCompiler.SyntaxTree.Operators.Minus;
                        oper_ass_in_prop = true;
                		break;
                }
            	if (oper_ass_in_prop)
            	{
            		if (pn.get_function == null)
                	AddError(new ThisPropertyCanNotBeReaded(pn,loc));
            		if (to.semantic_node_type == semantic_node_type.non_static_property_reference)
            		{
                		prop_expr = create_not_static_method_call(pn.get_function,(to as non_static_property_reference).expression,loc,false);
                		prop_expr.parameters.AddRange((to as non_static_property_reference).fact_parametres);
            		}
            		else
            		{
            			prop_expr = create_static_method_call(pn.get_function,loc,pn.comprehensive_type,false);
            			prop_expr.parameters.AddRange((to as static_property_reference).fact_parametres);
            		}
                	from = find_operator(ot,prop_expr,from,loc);
            	}
            }
            else
            if (to is class_field_reference)
            {
                if ((to as class_field_reference).obj.type.type_special_kind == SemanticTree.type_special_kind.record &&
                    (to as class_field_reference).obj is base_function_call)
            	{
                    //исключим ситуацию обращения к массиву
                    if (!(((to as class_field_reference).obj is common_method_call) &&
                    ((to as class_field_reference).obj as common_method_call).obj.type.type_special_kind == SemanticTree.type_special_kind.array_wrapper))
                        AddError(loc, "LEFT_SIDE_CANNOT_BE_ASSIGNED_TO");
            	}
            	//else check_field_reference_for_assign(to as class_field_reference,loc);
            }
            else if (context.is_in_cycle() && !SemanticRules.AllowChangeLoopVariable && to.semantic_node_type == semantic_node_type.namespace_variable_reference)
            {
            	if (context.is_loop_variable((to as namespace_variable_reference).var))
                    AddError(to.location, "CANNOT_ASSIGN_TO_LOOP_VARIABLE");
            }
            else if (context.is_in_cycle() && !SemanticRules.AllowChangeLoopVariable && to.semantic_node_type == semantic_node_type.local_variable_reference)
            {
            	if (context.is_loop_variable((to as local_variable_reference).var))
                    AddError(to.location, "CANNOT_ASSIGN_TO_LOOP_VARIABLE");
            }
            else if (context.is_in_cycle() && !SemanticRules.AllowChangeLoopVariable && to.semantic_node_type == semantic_node_type.local_block_variable_reference)
            {
            	if (context.is_loop_variable((to as local_block_variable_reference).var))
                    AddError(to.location, "CANNOT_ASSIGN_TO_LOOP_VARIABLE");
            }
            else if (to is simple_array_indexing)
            	if ((to as simple_array_indexing).simple_arr_expr is class_field_reference && ((to as simple_array_indexing).simple_arr_expr as class_field_reference).obj != null &&
            	   ((to as simple_array_indexing).simple_arr_expr as class_field_reference).obj is constant_node)
                    AddError(loc, "LEFT_SIDE_CANNOT_BE_ASSIGNED_TO");
            if ((to.semantic_node_type == semantic_node_type.static_event_reference)
                    || (to.semantic_node_type == semantic_node_type.nonstatic_event_reference))
            {
                statement_node event_assign = null;
                if (_assign.operator_type == PascalABCCompiler.SyntaxTree.Operators.Assignment)
                {
                    //throw new CanNotAssignToEvent();
                }
                static_event_reference ser = (static_event_reference)to;
                expression_node right_del = convertion_data_and_alghoritms.convert_type(from, ser.en.delegate_type);
                switch (_assign.operator_type)
                {
                    case PascalABCCompiler.SyntaxTree.Operators.AssignmentAddition:
                        {
                            if (to.semantic_node_type == semantic_node_type.static_event_reference)
                            {
                                event_assign = convertion_data_and_alghoritms.create_simple_function_call(
                                    ser.en.add_method, loc, right_del);
                            }
                            else
                            {
                                if (ser.en.semantic_node_type == semantic_node_type.compiled_event)
                                {
                                    nonstatic_event_reference nser = (nonstatic_event_reference)ser;
                                    compiled_function_node cfn = (compiled_function_node)ser.en.add_method;
                                    compiled_function_call tmp_event_assign = new compiled_function_call(cfn, nser.obj, loc);
                                    tmp_event_assign.parameters.AddElement(right_del);
                                    event_assign = tmp_event_assign;
                                }
                                else if (ser.en.semantic_node_type == semantic_node_type.common_event)
                                {
                                    nonstatic_event_reference nser = (nonstatic_event_reference)ser;
                                    common_method_node cfn = (common_method_node)ser.en.add_method;
                                    common_method_call tmp_event_assign = new common_method_call(cfn, nser.obj, loc);
                                    tmp_event_assign.parameters.AddElement(right_del);
                                    event_assign = tmp_event_assign;
                                }
                            }
                            break;
                        }
                    case PascalABCCompiler.SyntaxTree.Operators.AssignmentSubtraction:
                        {
                            if (to.semantic_node_type == semantic_node_type.static_event_reference)
                            {
                                event_assign = convertion_data_and_alghoritms.create_simple_function_call(
                                    ser.en.remove_method, loc, right_del);
                            }
                            else
                            {
                                if (ser.en.semantic_node_type == semantic_node_type.compiled_event)
                                {
                                    nonstatic_event_reference nser = (nonstatic_event_reference)ser;
                                    compiled_function_node cfn = (compiled_function_node)ser.en.remove_method;
                                    compiled_function_call tmp_event_assign = new compiled_function_call(cfn, nser.obj, loc);
                                    tmp_event_assign.parameters.AddElement(right_del);
                                    event_assign = tmp_event_assign;
                                }
                                else if (ser.en.semantic_node_type == semantic_node_type.common_event)
                                {
                                    nonstatic_event_reference nser = (nonstatic_event_reference)ser;
                                    common_method_node cfn = (common_method_node)ser.en.remove_method;
                                    common_method_call tmp_event_assign = new common_method_call(cfn, nser.obj, loc);
                                    tmp_event_assign.parameters.AddElement(right_del);
                                    event_assign = tmp_event_assign;
                                }
                            }
                            break;
                        }
                    default:
                        {
                            AddError(loc, "ASSIGN_TO_EVENT");
                            //throw new CanNotApplyThisOperationToEvent

                            break;
                        }
                }
                return_value(event_assign);
                return;
            }

            if (_assign.operator_type == PascalABCCompiler.SyntaxTree.Operators.Assignment || oper_ass_in_prop)
            {
                if (to.semantic_node_type == semantic_node_type.static_property_reference)
                {
                    static_property_reference spr = (static_property_reference)to;
                    if (spr.property.set_function == null)
                    {
                    	AddError(new ThisPropertyCanNotBeWrited(spr.property, loc));
                    }
                    check_property_params(spr, loc);
                    function_node set_func = spr.property.set_function;
                    from = convertion_data_and_alghoritms.convert_type(from, spr.property.property_type);
                    spr.fact_parametres.AddElement(from);
                    base_function_call bfc = create_static_method_call(set_func, loc, spr.property.comprehensive_type,
                        true);
                    bfc.parameters.AddRange(spr.fact_parametres);
                    return_value((statement_node)bfc);
                    return;
                }
                else if (to.semantic_node_type == semantic_node_type.non_static_property_reference)
                {
                    non_static_property_reference nspr = (non_static_property_reference)to;
                    check_property_params(nspr, loc);
                    from = convertion_data_and_alghoritms.convert_type(from, nspr.property.property_type);
                    nspr.fact_parametres.AddElement(from);

                    //Обработка s[i]:='c'
                    if (SystemUnitAssigned)
                        if (nspr.property.comprehensive_type == SystemLibrary.SystemLibrary.string_type)
                        {
                            if (nspr.property == SystemLibrary.SystemLibrary.string_type.default_property_node)
                            {
                                if (SystemLibrary.SystemLibInitializer.StringDefaultPropertySetProcedure != null)
                                {
                                    expressions_list exl = new expressions_list();
                                    exl.AddElement(nspr.expression);
                                    exl.AddElement(nspr.fact_parametres[0]);
                                    exl.AddElement(from);
                                    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_value((statement_node)ret);
                                    return;
                                }
                            }
                        }

                    if (nspr.property.set_function == null)
                    {
                    	AddError(new ThisPropertyCanNotBeWrited(nspr.property, loc));
                    }
                    function_node set_func = nspr.property.set_function;
                    base_function_call bfc = create_not_static_method_call(set_func, nspr.expression, loc,
                        true);
                    bfc.parameters.AddRange(nspr.fact_parametres);
                    return_value((statement_node)bfc);
                    return;
                }
                else if (to is simple_array_indexing && (to as simple_array_indexing).simple_arr_expr.type.type_special_kind == SemanticTree.type_special_kind.short_string)
                {
                	expression_node expr = (to as simple_array_indexing).simple_arr_expr;
                	expression_node ind_expr = (to as simple_array_indexing).ind_expr;
                	from = convertion_data_and_alghoritms.convert_type(from,SystemLibrary.SystemLibrary.char_type);
                	ind_expr = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.SetCharInShortStringProcedure.sym_info as function_node,loc,expr,ind_expr,new int_const_node((expr.type as short_string_type_node).Length,null),from);
                	return_value(find_operator(compiler_string_consts.assign_name, expr, ind_expr, get_location(_assign)));
                	return;
                }
                else if (to.type.type_special_kind == SemanticTree.type_special_kind.short_string)
                {
                    if (from.type is null_type_node)
                        AddError(get_location(_assign), "NIL_WITH_VALUE_TYPES_NOT_ALLOWED");
                    expression_node clip_expr = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as function_node, loc, convertion_data_and_alghoritms.convert_type(from, SystemLibrary.SystemLibrary.string_type), new int_const_node((to.type as short_string_type_node).Length, null));
                    statement_node en = find_operator(compiler_string_consts.assign_name, to, clip_expr, get_location(_assign));
                    return_value(en);
                    return;
                }
                else
                {

                    assign_is_converting = true;
                    statement_node en = find_operator(compiler_string_consts.assign_name, to, from, get_location(_assign));
                    assign_is_converting = false;
                    return_value(en);
                    return;
                }
            }
            else
            {
                assign_is_converting = true;
                statement_node en = find_operator(_assign.operator_type, to, from, get_location(_assign));
                assign_is_converting = false;
                return_value(en);
                return;
            }
            //throw new CompilerInternalError("Undefined assign to type");
        }
        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 base_function_call create_constructor_call(type_node tn, expressions_list exprs, location loc, Tuple<bool, List<SyntaxTree.expression>> lambdas_info = null)
        {
            if (tn.IsInterface)
            {
            	AddError(loc, "INTERFACE_{0}_CONSTRUCTOR_CALL", tn.name);
            }
            if (tn.IsAbstract)
            {
            	AddError(loc, "ABSTRACT_CONSTRUCTOR_{0}_CALL", tn.name);
            }
            SymbolInfo si = tn.find_in_type(TreeConverter.compiler_string_consts.default_constructor_name, context.CurrentScope); //tn.Scope); 
            delete_inherited_constructors(ref si, tn);
            if (si == null)
                AddError(loc, "CONSTRUCTOR_NOT_FOUND");
            function_node fnn = null;
            try
            {
                #region Если встретились лямбды в фактических параметрах, то выбираем нужную функцию из перегруженных, выводим типы, отмечаем флаг в лямбдах, говорящий о том, что мы их реально обходим 
                //lroman//
                if (lambdas_info != null && lambdas_info.Item1)
                {
                    LambdaHelper.processingLambdaParametersForTypeInference++;
                    var syntax_nodes_parameters = lambdas_info.Item2;

                    // SSM 21.05.14 - попытка обработать перегруженные функции с параметрами-лямбдами с различными возвращаемыми значениями
                    function_node_list spf = null;
                    try
                    {
                        function_node fn = convertion_data_and_alghoritms.select_function(exprs, si, loc,
                                                                                          syntax_nodes_parameters);
                        int exprCounter = 0;
                        foreach (SyntaxTree.expression en in syntax_nodes_parameters)
                        {
                            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; // spfnum - первый номер правильно инстанцированной. Пока -1. Если потом встретился второй, то тоже ошибка
                        int GoodVersionsCount = 0;
                        int GoodVersionsCountWithSameResType = 0;
                        for (int i = 0; i < spf.Count; i++)
                        {
                            function_node fn = spf[i];
                            try
                            {
                                int exprCounter = 0;
                                expressions_list exprs1 = new expressions_list();
                                exprs1.AddRange(exprs); // сделали копию

                                foreach (SyntaxTree.expression en in syntax_nodes_parameters)
                                {
                                    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);

                                            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(loc, spf);
                        if (GoodVersionsCount == 0) // было много, но ни одна не подошла из-за лямбд
                        {
                            throw lastmultex;
                            //throw new NoFunctionWithSameArguments(subloc2, false);
                        }

                        var kk = 0;
                        foreach (SyntaxTree.expression en in syntax_nodes_parameters)
                            //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--;

                    fnn = convertion_data_and_alghoritms.select_function(exprs, si, loc);
                }
                    //lroman//
                    #endregion

                else
                {
                    fnn = convertion_data_and_alghoritms.select_function(exprs, si, loc);
                }
            }
            catch (NoFunctionWithSameParametresNum e)
            {
                e.is_constructor = true;
                throw;
            }
            return create_static_method_call_with_params(fnn, loc, tn, false, exprs);
        }
        private void CheckSpecialFunctionCall(SymbolInfo si, expressions_list exprs, location loc)
        {
            if (SystemUnitAssigned)
            {
                bool write_proc = SystemLibrary.SystemLibInitializer.write_procedure.Equal(si);
                if (write_proc && exprs.Count > 1)
                {
                    //возможно это запись в типизированый файл
                    if (exprs[0].type.type_special_kind == SemanticTree.type_special_kind.typed_file)
                    //да, точно это типизированый файл!
                    {
                        //Проверим типы параметров вызова на совпадение с типом элементов файла
                        type_node element_type = exprs[0].type.element_type;
                        for (int i = 1; i < exprs.Count; i++)
                            convertion_data_and_alghoritms.check_convert_type(exprs[i], element_type, exprs[i].location);
                        if (element_type.type_special_kind == SemanticTree.type_special_kind.short_string)
                        {
                        	for (int i=1; i<exprs.Count; i++)
                        	{
                        		//common_namespace_function_call cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as common_namespace_function_node,null);
                        		//cmc.parameters.AddElement(exprs[i]);
                        		//cmc.parameters.AddElement(new int_const_node((element_type as short_string_type_node).Length,null));
                        		expression_node cmc = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as function_node,null,convertion_data_and_alghoritms.convert_type(exprs[i],SystemLibrary.SystemLibrary.string_type),new int_const_node((element_type as short_string_type_node).Length,null));
                        		exprs[i] = cmc;
                        	}
                        }
                        //if (exprs[i].type != element_type)
                        //  throw new ExpectedExprHaveTypeTypedFile(element_type, exprs[i].type, false, get_location(_method_call.parameters.expressions[i]));
                    }
                    else
                        //(ssyy) а может быть, в бинарный!
                        if (exprs[0].type.type_special_kind == SemanticTree.type_special_kind.binary_file)
                        {
                            //(ssyy) действительно, бинарный
                            for (int i = 1; i < exprs.Count; i++)
                            {
                                if (!CanUseThisTypeForBinaryFiles(exprs[i].type))
                                {
                                    AddError(exprs[i].location, "CAN_NOT_WRITE_REFERENCE_DATA_TO_BINARY_FILE");
                                }
                            }
                        }
                        else
                        {
                            if (SystemLibrary.SystemLibInitializer.write_procedure.sym_info is common_namespace_function_node)
                                ConvertPointersForWrite(exprs);
                            else
                                ConvertPointersForWriteFromDll(exprs);
                        }
                }
                else if (write_proc || SystemLibrary.SystemLibInitializer.writeln_procedure.Equal(si))
                {
                    //(ssyy) Преобразуем указатели в строки для вывода write/writeln
                    if (SystemLibrary.SystemLibInitializer.writeln_procedure.sym_info is common_namespace_function_node)
                        ConvertPointersForWrite(exprs);
                    else
                        ConvertPointersForWriteFromDll(exprs);
                }
                else if (SystemLibrary.SystemLibInitializer.IncludeProcedure.Equal(si)
                            || SystemLibrary.SystemLibInitializer.ExcludeProcedure.Equal(si))
                {
                    if (exprs.Count != 2) AddError( new NoFunctionWithSameArguments(loc, true));
                    type_node element_type = exprs[0].type.element_type;
                    if (exprs[0].type.type_special_kind != SemanticTree.type_special_kind.base_set_type && exprs[0].type.type_special_kind != SemanticTree.type_special_kind.set_type)
                    {
                    	AddError( new NoFunctionWithSameArguments(loc, true));
                    }
                    if (element_type != null)
                        convertion_data_and_alghoritms.check_convert_type(exprs[1], element_type, exprs[1].location);
                    else convertion_data_and_alghoritms.check_convert_type(exprs[1], exprs[0].type, exprs[0].location);
                    if (!exprs[0].is_addressed) AddError( new ThisExpressionCanNotBePassedAsVarParameter(exprs[0]));
                }
                else if (SystemLibrary.SystemLibInitializer.InSetProcedure.Equal(si))
                {
                    if (exprs.Count != 2) AddError( new NoFunctionWithSameArguments(loc, true));
                    type_node element_type = exprs[1].type.element_type;
                    if (element_type != null)
                    {
                        //exprs[0] = convertion_data_and_alghoritms.convert_type(exprs[0], element_type, exprs[0].location);
                        convertion_data_and_alghoritms.check_convert_type(exprs[0], element_type, exprs[0].location);
                    }
                    else convertion_data_and_alghoritms.check_convert_type(exprs[0], exprs[1].type, exprs[0].location);
                }
                else if (SystemLibrary.SystemLibInitializer.SetUnionProcedure.Equal(si)
                   || SystemLibrary.SystemLibInitializer.SetIntersectProcedure.Equal(si) || SystemLibrary.SystemLibInitializer.SetSubtractProcedure.Equal(si))
                {
                    if (exprs.Count != 2) AddError( new NoFunctionWithSameArguments(loc, true));
                    convertion_data_and_alghoritms.check_convert_type(exprs[1], exprs[0].type, exprs[1].location);
                }

                if (si == SystemLibrary.SystemLibInitializer.NewProcedure || si == SystemLibrary.SystemLibInitializer.DisposeProcedure)
                {
                    if (exprs[0].type == SystemLibrary.SystemLibrary.pointer_type)
                        AddError(exprs[0].location, "EXPECTED_TYPED_POINTER_IN_PROCEDURE{0}", (si.sym_info as function_node).name);
                }
            }
        }
        public override void visit(SyntaxTree.new_expr _new_expr)
        {
            type_node tn = ret.visit(_new_expr.type);
            //if (tn == SystemLibrary.SystemLibrary.void_type)
            //	AddError(new VoidNotValid(get_location(_new_expr.type)));
            check_for_type_allowed(tn,get_location(_new_expr.type));
            location loc = get_location(_new_expr);
            expressions_list exprs = null;
            var lambdas_are_in_parameters = false;
            var syntax_nodes_parameters = _new_expr.params_list == null
                                              ? new List<expression>()
                                              : _new_expr.params_list.expressions;

            if (_new_expr.params_list != null)
            {
                exprs = new expressions_list();
                foreach (SyntaxTree.expression en in _new_expr.params_list.expressions)
                {
                    if (en is SyntaxTree.function_lambda_definition)
                    {
                        lambdas_are_in_parameters = true;
                        ((SyntaxTree.function_lambda_definition)en).lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing;
                    }
                    exprs.AddElement(convert_strong(en));
                }
            }
            else
                exprs = new expressions_list();
            if (_new_expr.new_array)
            {
                //if (exprs.Count == 1)
                {
                    //new typename[size]
                    type_node atn = convertion_data_and_alghoritms.type_constructor.create_unsized_array(tn, context.converted_namespace, exprs.Count, loc);
                    //тип элементов
                    typeof_operator to = new typeof_operator(tn, loc);
                    List<expression_node> lst = new List<expression_node>();
                    //размер
                    for (int i=0; i<exprs.Count; i++)
                    {
                    	expression_node expr = exprs[i];
                    	expr = convertion_data_and_alghoritms.convert_type(expr, SystemLibrary.SystemLibrary.integer_type);
                    	if (expr is int_const_node && (expr as int_const_node).constant_value < 0)
                    		AddError(expr.location, "NEGATIVE_ARRAY_LENGTH_({0})_NOT_ALLOWED", (expr as int_const_node).constant_value);
                    	lst.Add(expr);
                    }
                    //это вызов спецфункции
                    expression_node retv = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.NewArrayProcedureDecl, loc, to, new int_const_node(exprs.Count,loc));
                    base_function_call cnfc = retv as base_function_call;
                    foreach (expression_node e in lst)
                    	cnfc.parameters.AddElement(e);
                    if (_new_expr.array_init_expr != null)
                    {
                    	if (exprs.Count > 1)
                    	{
                    		foreach (expression_node expr in lst)
                    		if (!(expr is int_const_node))
                                AddError(expr.location, "CONSTANT_EXPRESSION_EXPECTED");
                    		if (_new_expr.array_init_expr.elements == null)
                                AddError(get_location(_new_expr.array_init_expr), "ARRAY_CONST_EXPECTED");
                    		_new_expr.array_init_expr = get_possible_array_const(_new_expr.array_init_expr,atn) as SyntaxTree.array_const;
                    		expression_node e = convert_strong(_new_expr.array_init_expr);
                    		if (e is array_initializer)
                    		{
                    			array_initializer tmp = e as array_initializer;
                    			for (int i=0; i<exprs.Count; i++)
                    			{
                    				int len = (exprs[i] as int_const_node).constant_value;
                    				if (!(e is array_initializer) || (e as array_initializer).element_values.Count != len)
                                        AddError(e.location, "ARRAY_CONST_{0}_ELEMENTS_EXPECTED", len);
                    				e = (e as array_initializer).element_values[0];
                    			}
                    			cnfc.parameters.AddElement(ConvertArrayInitializer(atn,tmp));
                    		}
                    	}
                    	else
                    	{
                    		expression_node expr = lst[0];
                    		if (!(expr is int_const_node))
                                AddError(expr.location, "CONSTANT_EXPRESSION_EXPECTED");
                    		int len = (expr as int_const_node).constant_value;
                            if (_new_expr.array_init_expr.elements == null)
                            {
                                if (len != 0)
                                    AddError(get_location(_new_expr.array_init_expr), "ARRAY_CONST_{0}_ELEMENTS_EXPECTED", len);
                            }
                    		else if (_new_expr.array_init_expr.elements.expressions.Count != len)
                                AddError(get_location(_new_expr.array_init_expr), "ARRAY_CONST_{0}_ELEMENTS_EXPECTED", len);
                    		_new_expr.array_init_expr = get_possible_array_const(_new_expr.array_init_expr,atn) as SyntaxTree.array_const;
                    		if (_new_expr.array_init_expr.elements != null)
                            foreach (SyntaxTree.expression e in _new_expr.array_init_expr.elements.expressions)
                    			cnfc.parameters.AddElement(convertion_data_and_alghoritms.convert_type(clip_expression_if_need(convert_strong(e),tn),tn));
                    	}
                    }
                    //явное преобразования для того чтобы тип задать
                    function_node fn = convertion_data_and_alghoritms.get_empty_conversion(retv.type, atn, false);
                    retv = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, retv);
                    return_value(retv);
                    return;
                }
                
            }
            return_value(create_constructor_call(tn, exprs, get_location(_new_expr.type), new Tuple<bool, List<expression>>(lambdas_are_in_parameters, syntax_nodes_parameters)));
        }
        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);
        }
        internal expression_node get_init_call_for_typed_file(var_definition_node vdn, type_node element_type)
        {
            location loc = (vdn.type as common_type_node).loc;
            if (!SystemUnitAssigned)
                AddError(new NotSupportedError(loc));
            //Когда заработает наследование конструкторов надо вставить это
            /*
            expression_node var_ref = create_variable_reference(vdn, loc);
            expressions_list exl = new expressions_list();
            exl.AddElement(new typeof_operator(element_type, loc));
            base_function_call bfc = create_constructor_call(vdn.type, exl, loc);
            expression_node expr = find_operator(compiler_string_consts.assign_name, var_ref, bfc, loc);
            */

            type_node tn = vdn.type;
            vdn.type = SystemLibrary.SystemLibInitializer.TypedFileType.sym_info as type_node;

            expression_node var_ref = create_variable_reference(vdn, loc);
            expressions_list exl = new expressions_list();
            exl.AddElement(var_ref);
            exl.AddElement(new typeof_operator(element_type, loc));
            List<int> lens = get_short_string_lens(element_type);
            int sz = get_short_string_size(element_type);
            if (sz > 0)
            {
            	exl.AddElement(new int_const_node(get_short_string_size(element_type),null));
            	for (int i=0; i<lens.Count; i++)
            		exl.AddElement(new int_const_node(lens[i],null));
            }
            this.context.save_var_definitions();
            function_node fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.TypedFileInitProcedure.SymbolInfo, loc);
            this.context.restore_var_definitions();
            expression_node expr = convertion_data_and_alghoritms.create_simple_function_call(fn, null, exl.ToArray());

            vdn.type = tn;

            return expr;
        }
 private expressions_list convert_expression_list(List<SyntaxTree.expression> expr_list)
 {
     expressions_list exprs = new expressions_list();
     foreach (SyntaxTree.expression en in expr_list)
         exprs.AddElement(convert_strong(en));
     return exprs;
 }
        internal expression_node get_init_call_for_binary_file(var_definition_node vdn)
        {
            location loc = null;
            if (vdn.type is common_type_node)
                loc = (vdn.type as common_type_node).loc;
            if (!SystemUnitAssigned)
                AddError(new NotSupportedError(loc));
            type_node tn = vdn.type;
            vdn.type = SystemLibrary.SystemLibInitializer.BinaryFileType.sym_info as type_node;

            expression_node var_ref = create_variable_reference(vdn, loc);
            expressions_list exl = new expressions_list();
            exl.AddElement(var_ref);

            function_node fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.BinaryFileInitProcedure.SymbolInfo, loc);
            expression_node expr = convertion_data_and_alghoritms.create_simple_function_call(fn, null, exl.ToArray());

            vdn.type = tn;

            return expr;
        }
 //TODO: Обратить внимание на эту функцию. Ее вызовы не приводят к созданиям узлов преобразования типов.
 private function_node find_function(string name, location loc, params expression_node[] exprs)
 {
     expressions_list exprs_list = new expressions_list();
     exprs_list.AddRange(exprs);
     return find_function(name, loc, exprs_list);
 }
        internal expression_node get_init_call_for_set_as_constr(var_definition_node vdn, expression_node init_value)
        {
            location loc = (vdn.type as common_type_node).loc;
            if (!SystemUnitAssigned)
                AddError(new NotSupportedError(loc));
            //Когда заработает наследование конструкторов надо вставить это
            /*
            expression_node var_ref = create_variable_reference(vdn, loc);
            expressions_list exl = new expressions_list();
            exl.AddElement(new typeof_operator(element_type, loc));
            base_function_call bfc = create_constructor_call(vdn.type, exl, loc);
            expression_node expr = find_operator(compiler_string_consts.assign_name, var_ref, bfc, loc);
            */

            type_node tn = vdn.type;
            vdn.type = SystemLibrary.SystemLibInitializer.TypedSetType.sym_info as type_node;

            expression_node var_ref = create_variable_reference(vdn, loc);
            expressions_list exl = new expressions_list();
            //exl.AddElement(var_ref);
            //exl.AddElement(new typeof_operator(element_type, loc));
            if (tn.element_type == SystemLibrary.SystemLibrary.byte_type)
            {
            	exl.AddElement(new byte_const_node(byte.MinValue,null));
            	exl.AddElement(new byte_const_node(byte.MaxValue,null));
            }
            else if (tn.element_type == SystemLibrary.SystemLibrary.sbyte_type)
            {
            	exl.AddElement(new sbyte_const_node(sbyte.MinValue,null));
            	exl.AddElement(new sbyte_const_node(sbyte.MaxValue,null));
            }
            else if (tn.element_type == SystemLibrary.SystemLibrary.short_type)
            {
            	exl.AddElement(new short_const_node(short.MinValue,null));
            	exl.AddElement(new short_const_node(short.MaxValue,null));
            }
            else if (tn.element_type == SystemLibrary.SystemLibrary.ushort_type)
            {
            	exl.AddElement(new ushort_const_node(ushort.MinValue,null));
            	exl.AddElement(new ushort_const_node(ushort.MaxValue,null));
            }
            else if (tn.element_type.type_special_kind == SemanticTree.type_special_kind.diap_type || tn.element_type.type_special_kind == SemanticTree.type_special_kind.enum_kind)
            {
            	ordinal_type_interface ii = tn.element_type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface;
            	exl.AddElement(ii.lower_value);
            	exl.AddElement(ii.upper_value);
            }
            exl.AddElement(init_value);
            function_node fn = null;
            if (exl.Count > 1)
            {
                fn = convertion_data_and_alghoritms.select_function(exl, (SystemLibrary.SystemLibInitializer.TypedSetType.sym_info as type_node).find_in_type(compiler_string_consts.default_constructor_name), loc);
            }
            else
            {
                fn = convertion_data_and_alghoritms.select_function(exl, (SystemLibrary.SystemLibInitializer.TypedSetType.sym_info as type_node).find_in_type(compiler_string_consts.default_constructor_name), loc);
            }
            //expression_node expr = convertion_data_and_alghoritms.create_simple_function_call(fn, null, exl.ToArray());
            expression_node expr = create_static_method_call_with_params(fn, loc, tn, false, exl);
            vdn.type = tn;

            return expr;
        }
Exemple #30
0
 /*public function_lambda_call_node(type_node ret_type)
 {
     _ret_type = ret_type;
 }*/
 /// <summary>
 /// Конструктор узла.
 /// </summary>
 /// <param name="ret_type">Тип возвращаемого значения функции.</param>
 public function_lambda_call_node(expressions_list parameters, function_lambda_node fln)
 {
     _parameters = parameters;
     _fln = fln;
 }
Exemple #31
0
        public static function_node DeduceFunction(function_node func, expressions_list fact, bool alone, location loc, List<SyntaxTree.expression> syntax_nodes_parameters = null)
        {
            parameter_list formal = func.parameters;
            int formal_count = formal.Count;
            int fact_count = fact.Count;
            int generic_type_params_count = func.generic_parameters_count;
            type_node[] deduced = new type_node[generic_type_params_count];
            List<int> nils = new List<int>();
            int count_params_to_see = fact_count;

            var lambda_syntax_nodes = new Dictionary<string, function_lambda_definition>(); //lroman Получим список фактических параметров-лямбд текущей вызываемой подпрограммы
            if (syntax_nodes_parameters != null
                && syntax_nodes_parameters.Count > 0) //lroman
            {
                lambda_syntax_nodes = syntax_nodes_parameters
                    .OfType<function_lambda_definition>()
                    .ToDictionary(f => f.lambda_name, f => f);
            }

            var lambda_in_parameters = lambda_syntax_nodes.Count > 0; 
            var saved_lambdas_states = SaveLambdasStates(lambda_syntax_nodes.Select(ld => ld.Value)); // Сохраним типы лямбды перед вычислениями

            if (fact_count < formal_count)
            {
                //Сравниваем количества параметров
                parameter par = formal[fact_count];
                if (par.default_value == null && !par.is_params)
                {
                    if (alone)
                        throw new NoFunctionWithSameParametresNum(loc, alone, func);
                    return null;
                }
            }
            else
            {
                type_node last_params_type = null;
                bool last_is_params = false;
                parameter par = null;
                if (formal_count > 0)
                {
                    par = formal[formal_count - 1];
                    last_is_params = par.is_params;
                }
                if (last_is_params)
                {
                    array_internal_interface aii = par.type.get_internal_interface(internal_interface_kind.unsized_array_interface) as array_internal_interface;
                    last_params_type = aii.element_type;
                }
                if (fact_count > formal_count)
                {
                    //Фактических больше, чем формальных. Последний формальный должен быть params...
                    if (last_is_params)
                    {
                        for (int i = formal_count - 1; i < fact_count; ++i)
                        {
                            //Проверяем фактические, попадающие под params...
                            if (!DeduceInstanceTypes(last_params_type, fact[i].type, deduced, nils))
                            {
                                if (alone)
                                    throw new SimpleSemanticError(loc, "GENERIC_FUNCTION_{0}_CAN_NOT_BE_CALLED_WITH_THESE_PARAMETERS", func.name);
                                return null;
                            }
                        }
                        count_params_to_see = formal_count - 1;
                    }
                    else
                    {
                        if (alone)
                            throw new NoFunctionWithSameParametresNum(loc, alone, func);
                        return null;
                    }
                }
            }
            bool need_params_work = (count_params_to_see > 0 && formal[count_params_to_see - 1].is_params);
            if (need_params_work)
            {
                count_params_to_see -= 1;
            }

            var continue_trying_to_infer_types = true; 
            Dictionary<string, delegate_internal_interface> formal_delegates = null; 

            while (continue_trying_to_infer_types) //Продолжаем пытаться вычислить типы до тех пор пока состояние о выведенных типах не будет отличаться от состояния на предыдущей итерации
            {
                var previous_deduce_state = deduced // Текущее состояние выведенных на данный момент типов. Простой список индексов с уже выведенными типами из массива deduced
                        .Select((t, i) => new { Type = t, Index = i })
                        .Where(t => t.Type != null)
                        .Select(t => t.Index)
                        .ToArray();

                for (int i = 0; i < count_params_to_see; ++i)
                {
                    if (!DeduceInstanceTypes(formal[i].type, fact[i].type, deduced, nils))
                    {
                        if (alone)
                            throw new SimpleSemanticError(loc, "GENERIC_FUNCTION_{0}_CAN_NOT_BE_CALLED_WITH_THESE_PARAMETERS", func.name);
                        RestoreLambdasStates(lambda_syntax_nodes.Values.ToList(), saved_lambdas_states);
                        return null;
                    }

                }

                if (lambda_in_parameters)
                {
                    if (formal_delegates == null)
                    {
                        formal_delegates = new Dictionary<string, delegate_internal_interface>();

                        for (int i = 0; i < count_params_to_see; ++i)
                            //Выделим из формальных параметров те, которые соотвтествуют фактическим параметрам-лямбдам
                        {
                            var lambda_func = fact[i].type as delegated_methods;
                            if (lambda_func != null
                                && lambda_func.proper_methods.Count == 1
                                && LambdaHelper.IsLambdaName(lambda_func.proper_methods[0].simple_function_node.name))
                            {
                                formal_delegates.Add(LambdaHelper.GetLambdaNamePartWithoutGenerics(lambda_func.proper_methods[0].simple_function_node.name),
                                                     formal[i].type.get_internal_interface(
                                                         internal_interface_kind.delegate_interface) as
                                                     delegate_internal_interface);
                            }
                        }
                    }

                    foreach (var formal_delegate in formal_delegates)
                        //Перебираем все полученные формальные параемтры, соотвтетсвующие фактическим лямбдам
                    {
                        var lambda_syntax_node = lambda_syntax_nodes[formal_delegate.Key];
                        Exception on_lambda_body_compile_exception;
                            // Исключение которое может возникунть в результате компиляции тела лямбды если мы выберем неправильные типы параметров
                        if (!TryToDeduceTypesInLambda(lambda_syntax_node, formal_delegate.Value, deduced, nils,
                                                      out on_lambda_body_compile_exception))
                            //Пробуем вычислить типы из лямбд
                        {
                            RestoreLambdasStates(lambda_syntax_nodes.Values.ToList(), saved_lambdas_states);

                            if (on_lambda_body_compile_exception != null)
                            {
                                if (alone)
                                {
                                    throw on_lambda_body_compile_exception;
                                }

                                throw new FailedWhileTryingToCompileLambdaBodyWithGivenParametersException(
                                    on_lambda_body_compile_exception);
                            }

                            if (alone)
                            {
                                throw new SimpleSemanticError(loc, "GENERIC_FUNCTION_{0}_CAN_NOT_BE_CALLED_WITH_THESE_PARAMETERS", func.name);
                            }
                            return null;
                        }
                    }
                }
                var current_deduce_state = deduced               //текущее состояние выведенных типов
                    .Select((t, ii) => new {Type = t, Index = ii})
                    .Where(t => t.Type != null)
                    .Select(t => t.Index)
                    .ToArray();

                if (previous_deduce_state.SequenceEqual(current_deduce_state)) // Если ничего с прошлой итерации не изменилось, то дальше нет смысла пробовать выводить. Выходим из цикла
                {
                    continue_trying_to_infer_types = false;
                }
            }

            RestoreLambdasStates(lambda_syntax_nodes.Values.ToList(), saved_lambdas_states);

            if (need_params_work)
            {
                type_node[] tmp_deduced = (type_node[])deduced.Clone();
                List<int> tmp_nils = new List<int>();
                tmp_nils.AddRange(nils);
                if (!DeduceInstanceTypes(formal[count_params_to_see].type, fact[count_params_to_see].type, deduced, nils))
                {
                    //Второй шанс. Учитываем слово params.
                    deduced = tmp_deduced;
                    nils = tmp_nils;
                    if (!DeduceInstanceTypes(formal[count_params_to_see].type.element_type, fact[count_params_to_see].type, deduced, nils))
                    {
                        if (alone)
                            throw new SimpleSemanticError(loc, "GENERIC_FUNCTION_{0}_CAN_NOT_BE_CALLED_WITH_THESE_PARAMETERS", func.name);
                        return null;
                    }
                }
            }
            //Вывели всё, что могли. Теперь проверяем.
            for (int i = 0; i < generic_type_params_count; ++i)
            {
                if (deduced[i] == null)
                {
                    if (alone)
                        throw new SimpleSemanticError(loc, "CAN_NOT_DEDUCE_TYPE_PARAMS_FROM_CALL_{0}", func.name);
                    return null;
                }
            }
            foreach (int num in nils)
            {
                if (!type_table.is_with_nil_allowed(deduced[num]))
                {
                    if (alone)
                        throw new SimpleSemanticError(loc, "GENERIC_FUNCTION_{0}_CAN_NOT_BE_CALLED_WITH_THESE_PARAMETERS", func.name);
                    return null;
                }
            }
            foreach (type_node tt in deduced)
            {
                CompilationErrorWithLocation check_err = generic_parameter_eliminations.check_type_generic_useful(tt, loc);
                if (check_err != null)
                {
                    if (alone)
                        throw check_err;
                    return null;
                }
            }
            //Итак, вывели все параметры. Теперь инстанцируем.
            List<type_node> deduced_list = new List<type_node>(generic_type_params_count);
            deduced_list.AddRange(deduced);
            return func.get_instance(deduced_list, alone, loc);
        }