//TODO: Добавить приведение типов.
        public override void visit(SyntaxTree.case_node _case_node)
        {
            convertion_data_and_alghoritms.check_node_parser_error(_case_node);
            switch_node sn = new switch_node(get_location(_case_node));
            expression_node en = convert_strong(_case_node.param);
            if (en is typed_expression) en = convert_typed_expression_to_function_call(en as typed_expression);
            type_node case_expr_type = en.type;

            internal_interface ii = en.type.get_internal_interface(internal_interface_kind.ordinal_interface);
            if (ii == null && en.type != SystemLibrary.SystemLibrary.string_type)
            {
                AddError(new OrdinalOrStringTypeExpected(en.location));
            }
            if (ii != null)
            {
                ordinal_type_interface oti = (ordinal_type_interface)ii;
                en = convertion_data_and_alghoritms.create_simple_function_call(oti.value_to_int, en.location, en);

                sn.condition = en;

                foreach (SyntaxTree.case_variant cv in _case_node.conditions.variants)
                {
                    convertion_data_and_alghoritms.check_node_parser_error(cv);
                    case_variant_node sem_cv = new case_variant_node(get_location(cv));
                    sn.case_variants.AddElement(sem_cv);
                    foreach (SyntaxTree.expression expr in cv.conditions.expressions)
                    {
                        convertion_data_and_alghoritms.check_node_parser_error(expr);
                        SyntaxTree.diapason_expr diap = expr as SyntaxTree.diapason_expr;
                        if (diap == null)
                        {
                            expression_node cn = convert_strong(expr);
                            int_const_node icn = convert_const_to_switch(cn, oti, case_expr_type, get_location(expr));
                            is_case_variant_intersection_with_another(sn, icn, get_location(expr));
                            sem_cv.case_constants.AddElement(icn);
                        }
                        else
                        {
                            convertion_data_and_alghoritms.check_node_parser_error(diap.left);
                            expression_node left = convert_strong(diap.left);
                            /*
                            constant_node cons_left = left as constant_node;
                            if (cons_left==null)
                            {
                                throw new ConstantExpressionExpected(get_location(diap.left));
                            }
                            */
                            int_const_node icn_left = convert_const_to_switch(left, oti, case_expr_type, get_location(diap.left));

                            convertion_data_and_alghoritms.check_node_parser_error(diap.right);
                            expression_node right = convert_strong(diap.right);
                            /*
                            constant_node cons_right = right as constant_node;
                            if (cons_right == null)
                            {
                                throw new ConstantExpressionExpected(get_location(diap.right));
                            }
                            */
                            int_const_node icn_right = convert_const_to_switch(right, oti, case_expr_type, get_location(diap.right));
                            //ssyy
                            if (icn_left.constant_value > icn_right.constant_value)
                            {
                                AddError(get_location(diap.right), "LEFT_RANGE_GREATER_THEN_RIGHT");
                            }
                            //\ssyy
                            case_range_node crn = new case_range_node(icn_left, icn_right, get_location(diap));
                            is_case_range_intersection_with_another(sn, crn, get_location(expr));
                            sem_cv.case_ranges.AddElement(crn);
                        }
                    }
                    context.enter_code_block_with_bind();
                    statement_node stmn = convert_strong(cv.exec_if_true);
                    context.leave_code_block();
                    sem_cv.case_statement = stmn;
                    //sn.case_variants.AddElement(sem_cv);
                }
                context.enter_code_block_with_bind();
                statement_node else_statement = convert_weak(_case_node.else_statement);
                context.leave_code_block();
                sn.default_statement = else_statement;
                return_value(sn);
            }
            else
            {
                if_node main_ifn = null;
                if_node ifn = null;
                compiled_function_node str_eq_meth = SystemLibrary.SystemLibrary.string_type.find_in_type("=").sym_info as compiled_function_node;
                Dictionary<string, string> case_constants = new Dictionary<string, string>();
                foreach (SyntaxTree.case_variant cv in _case_node.conditions.variants)
                {
                    convertion_data_and_alghoritms.check_node_parser_error(cv);
                    location loc = get_location(cv);
                    expression_node eq_node = null;
                    List<compiled_static_method_call> eq_calls = new List<compiled_static_method_call>();
                    foreach (SyntaxTree.expression expr in cv.conditions.expressions)
                    {
                        expression_node cn = convert_strong(expr);
                        if (cn.type != SystemLibrary.SystemLibrary.string_type)
                            AddError(new CanNotConvertTypes(cn, cn.type, SystemLibrary.SystemLibrary.string_type, cn.location));
                        string_const_node scn = convert_string_const_to_switch(cn, cn.location);
                        if (!case_constants.ContainsKey(scn.constant_value))
                            case_constants.Add(scn.constant_value, scn.constant_value);
                        else
                            AddError(cn.location, "CASE_CONSTANT_VARIANT_COINCIDE_WITH_ANOTHER");
                        compiled_static_method_call eq_call = new compiled_static_method_call(str_eq_meth, cn.location);
                        eq_call.parameters.AddElement(en);
                        eq_call.parameters.AddElement(cn);
                        eq_calls.Add(eq_call);
                    }
                    foreach (compiled_static_method_call eq_call in eq_calls)
                    {
                        if (eq_node == null)
                            eq_node = eq_call;
                        else
                            eq_node = new basic_function_call(SystemLibrary.SystemLibrary.bool_or as basic_function_node, null, eq_node, eq_call);
                    }
                    context.enter_code_block_with_bind();
                    statement_node stmn = convert_strong(cv.exec_if_true);
                    context.leave_code_block();
                    if (ifn != null)
                    {
                        ifn.else_body = new if_node(eq_node, stmn, null, loc);
                        ifn = ifn.else_body as if_node;
                    }
                    else
                        ifn = new if_node(eq_node, stmn, null, loc);
                    if (main_ifn == null)
                        main_ifn = ifn;
                }
                context.enter_code_block_with_bind();
                statement_node else_statement = convert_weak(_case_node.else_statement);
                context.leave_code_block();
                if (ifn == null)
                {
                    ifn = new if_node(en, new statements_list(null), null, get_location(_case_node));
                    main_ifn = ifn;
                }
                ifn.else_body = else_statement;
                return_value(main_ifn);
            }
        }
 private void is_case_range_intersection_with_another(switch_node sn, case_range_node defined_range, location curloc)
 {
     foreach (case_variant_node cv in sn.case_variants)
     {
         foreach (int_const_node icn in cv.case_constants)
         {
             if ((icn.constant_value >= defined_range.lower_bound.constant_value) &&
                 (icn.constant_value <= defined_range.high_bound.constant_value))
             {
                 AddError(curloc, "CASE_CONSTANT_VARIANT_COINCIDE_WITH_DIAPASON");
             }
         }
         foreach (case_range_node cr in cv.case_ranges)
         {
             if ((cr.lower_bound.constant_value <= defined_range.high_bound.constant_value) &&
                 (cr.lower_bound.constant_value >= defined_range.lower_bound.constant_value))
             {
                 AddError(curloc, "CASE_DIAPASON_VARIANT_INTERSECTION");
             }
             if ((cr.high_bound.constant_value <= defined_range.high_bound.constant_value) &&
                 (cr.high_bound.constant_value >= defined_range.lower_bound.constant_value))
             {
                 AddError(curloc, "CASE_DIAPASON_VARIANT_INTERSECTION");
             }
         }
     }
 }