示例#1
0
        private void ForeachCheckAndConvert(foreach_stmt _foreach_stmt, out expression_node foreachCollection,
                                            out var_definition_node foreachVariable)
        {
            var lambdaSearcher = new LambdaSearcher(_foreach_stmt.in_what);

            if (lambdaSearcher.CheckIfContainsLambdas())
            {
                AddError(new LambdasNotAllowedInForeachInWhatSatetement(get_location(lambdaSearcher.FoundLambda)));
            }

            foreachCollection = convert_strong(_foreach_stmt.in_what);

            expression_node tmp = convert_if_typed_expression_to_function_call(foreachCollection);

            if (tmp.type != null)
            {
                foreachCollection = tmp;
            }

            bool      sys_coll_ienum; // true означает, что мы нашли тип object у интерфейса System.Collections.IEnumerable
            type_node elem_type = null;

            if (!FindIEnumerableElementType(foreachCollection.type, ref elem_type, out sys_coll_ienum))
            {
                AddError(foreachCollection.location, "CAN_NOT_EXECUTE_FOREACH_BY_EXPR_OF_TYPE_{0}", foreachCollection.type.name);
            }

            CheckToEmbeddedStatementCannotBeADeclaration(_foreach_stmt.stmt);

            foreachVariable = FindForeachVariable(_foreach_stmt, elem_type, sys_coll_ienum);
        }
示例#2
0
        private bool IsIList(expression_node en)
        {
            var ii = en.type.ImplementingInterfaces;

            if (ii != null)
            {
                foreach (var itn in ii)
                {
                    System.Type tt = null;
                    if (itn is compiled_type_node ctn)
                    {
                        tt = ctn.compiled_type;
                        if (tt.IsGenericType)
                        {
                            tt = tt.GetGenericTypeDefinition();
                        }
                        if (tt == typeof(System.Collections.Generic.IList <>))
                        {
                            return(true);
                        }
                    }
                    else if (itn is compiled_generic_instance_type_node itnc)
                    {
                        tt = (itnc.original_generic as compiled_type_node).compiled_type;
                        if (tt == typeof(System.Collections.Generic.IList <>))
                        {
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
示例#3
0
        private void VisitAssignment(base_function_call en)
        {
            for (int i = 1; i < en.parameters.Count; i++)
            {
                VisitExpression(en.parameters[i]);
            }
            expression_node p = en.parameters[0];

            switch (p.semantic_node_type)
            {
            case semantic_node_type.local_variable_reference: IncreaseNumAssVar((local_variable_reference)p); break;

            case semantic_node_type.local_block_variable_reference: IncreaseNumAssVar((local_block_variable_reference)p); break;

            case semantic_node_type.namespace_variable_reference: IncreaseNumAssVar((namespace_variable_reference)p); break;

            case semantic_node_type.class_field_reference: VisitExpression((p as class_field_reference).obj); IncreaseNumAssField((class_field_reference)p); break;

            case semantic_node_type.static_class_field_reference: IncreaseNumAssField((static_class_field_reference)p); break;

            case semantic_node_type.common_parameter_reference: IncreaseNumAssParam((common_parameter_reference)p); break;

            case semantic_node_type.deref_node: CheckAssign(((dereference_node)p).deref_expr); break;

            case semantic_node_type.simple_array_indexing: VisitSimpleArrayIndexing((simple_array_indexing)p); break;
            }
        }
示例#4
0
        /// <summary>
        /// Проверяет, подходит ли фаункция для вызова с указанными параметрами
        /// </summary>
        /// <param name="candidate"></param>
        /// <param name="givenParameterTypes">Типы параметров, указанные пользователем</param>
        /// <returns></returns>
        private bool IsSuitableFunction(
            function_node candidate,
            type_node[] givenParameterTypes,
            expression_node patternInstance,
            location deconstructionLocation,
            out type_node[] parameterTypes)
        {
            parameterTypes = new type_node[givenParameterTypes.Length];
            var selfParameter = candidate.is_extension_method ? candidate.parameters.First(IsSelfParameter) : null;

            Debug.Assert(!candidate.is_extension_method || selfParameter != null, "Couldn't find self parameter in extension method");
            var candidateParameterTypes =
                candidate.is_extension_method ?
                candidate.parameters.Where(x => !IsSelfParameter(x)).ToArray() :
                candidate.parameters.ToArray();

            if (candidateParameterTypes.Length != givenParameterTypes.Length)
            {
                return(false);
            }

            // Разрешаем только deconstruct текущего класса, родительские в расчет не берем
            if (candidate is common_method_node commonMethod && !AreTheSameType(patternInstance.type, commonMethod.cont_type))
            {
                return(false);
            }

            var genericDeduceNeeded = candidate.is_extension_method && candidate.is_generic_function;

            type_node[] deducedGenerics = new type_node[candidate.generic_parameters_count];
            if (genericDeduceNeeded)
            {
                // Выводим дженерики по self
                var nils           = new List <int>();
                var deduceSucceded = generic_convertions.DeduceInstanceTypes(selfParameter.type, patternInstance.type, deducedGenerics, nils);
                if (!deduceSucceded || deducedGenerics.Contains(null))
                {
                    return(false);
                }
            }

            for (int i = 0; i < givenParameterTypes.Length; i++)
            {
                var givenParameter     = givenParameterTypes[i];
                var candidateParameter = candidateParameterTypes[i].type;
                if (genericDeduceNeeded && (candidateParameter.is_generic_parameter || candidateParameter.is_generic_type_instance))
                {
                    candidateParameter = InstantiateParameter(candidateParameter, deducedGenerics);
                }

                if (givenParameter != null && !AreTheSameType(candidateParameter, givenParameter))
                {
                    return(false);
                }

                parameterTypes[i] = candidateParameter;
            }

            return(true);
        }
示例#5
0
        /// <summary>
        /// Автовыведение типов в yield'ax.
        /// </summary>
        private void ProcessAssigntToAutoType(addressed_expression to, ref expression_node from)
        {
            var sequence = to.type as compiled_generic_instance_type_node;

            // SSM 26.06.16 - правка в связи с автовыведением типов в yieldах
            if (to.type is auto_type)
            {
                try_convert_typed_expression_to_function_call(ref from);
                if (to is class_field_reference)
                {
                    var cfr = to as class_field_reference;
                    cfr.field.type = from.type;
                    cfr.type       = from.type; // Это неверно работает когда yieldится процедура #1439
                    // SSM 1.11.18 попытка правки возвращения процедуры в yield
                    //if (from.type.semantic_node_type == semantic_node_type.delegated_method)

                    cfr.field.inital_value = context.GetInitalValueForVariable(cfr.field, cfr.field.inital_value);
                }
                else if (to is local_block_variable_reference)
                {
                    var lvr = to as local_block_variable_reference;
                    lvr.var.type         = from.type;
                    lvr.type             = from.type;
                    lvr.var.inital_value = context.GetInitalValueForVariable(lvr.var, lvr.var.inital_value);
                }
                else
                {
                    AddError(to.location, "Не могу вывести тип при наличии yield: " + to.type.full_name);
                }
                //to.type = from.type; // и без всякого real_type!
            }
            else if (sequence?.instance_params[0] is ienumerable_auto_type)
            {
                type_node elem_type = null;
                try_convert_typed_expression_to_function_call(ref from);
                bool bb; // здесь bb не нужно. Оно нужно в foreach
                var  b = FindIEnumerableElementType(from.type, ref elem_type, out bb);
                if (!b)
                {
                    AddError(from.location, "CAN_NOT_EXECUTE_FOREACH_BY_EXPR_OF_TYPE_{0}", from.type.full_name);
                }

                var IEnumType = new template_type_reference(new named_type_reference("System.Collections.Generic.IEnumerable"),
                                                            new template_param_list(new semantic_type_node(elem_type)));
                if (to is class_field_reference)
                {
                    var cfr = to as class_field_reference;

                    cfr.field.type = convert_strong(IEnumType);
                    cfr.type       = cfr.field.type;
                }
                else if (to is local_block_variable_reference)
                {
                    var lvr = to as local_block_variable_reference;

                    lvr.var.type = convert_strong(IEnumType); // замена типа у описания переменной
                    lvr.type     = lvr.var.type;              // замена типа у переменной
                }
            }
        }
示例#6
0
        public expression_node visit(SyntaxTree.expression expr)
        {
            expr.visit(syntax_tree_visitor);

            /*addressed_expression ad = ret_semantic as addressed_expression;
             * if (ad != null && ad.is_addressed)
             * {
             *  if (convertion_data_and_alghoritms.check_for_constant(ad))
             *      ad.is_addressed = false;
             * }*/

            //Надеюсь, это сильно не скажется на производительности, хотя в другом случае этот же код просто будет разбросан по всем метдам syntax_tree_visitor-а.
            base_function_call bfc = ret_semantic as base_function_call;

            if (bfc != null)
            {
                if (bfc.simple_function_node.compile_time_executor != null)
                {
                    expression_node ex = bfc.simple_function_node.compile_time_executor(bfc.location, bfc.parameters.ToArray());
                    if (ex != null)
                    {
                        return(ex);
                    }
                }
            }

            return(ret_semantic as expression_node);
        }
示例#7
0
        /// <summary>
        /// Проверяет, подходит ли фаункция для вызова с указанными параметрами
        /// </summary>
        /// <param name="candidate"></param>
        /// <param name="givenParameterTypes">Типы параметров, указанные пользователем</param>
        /// <returns></returns>
        private bool IsSuitableFunction(
            function_node candidate,
            type_node[] givenParameterTypes,
            expression_node patternInstance,
            location deconstructionLocation,
            out type_node[] parameterTypes)
        {
            parameterTypes = new type_node[givenParameterTypes.Length];
            var selfParameter = candidate.is_extension_method ? candidate.parameters.First(IsSelfParameter) : null;

            Debug.Assert(!candidate.is_extension_method || selfParameter != null, "Couldn't find self parameter in extension method");
            var candidateParameterTypes =
                candidate.is_extension_method ?
                candidate.parameters.Where(x => !IsSelfParameter(x)).ToArray() :
                candidate.parameters.ToArray();

            if (candidateParameterTypes.Length != givenParameterTypes.Length)
            {
                return(false);
            }

            var genericDeduceNeeded = candidate.is_extension_method && candidate.is_generic_function;

            type_node[] deducedGenerics = new type_node[candidate.generic_parameters_count];
            if (genericDeduceNeeded)
            {
                // Выводим дженерики по self
                var nils           = new List <int>();
                var deduceSucceded = generic_convertions.DeduceInstanceTypes(selfParameter.type, patternInstance.type, deducedGenerics, nils);
                if (!deduceSucceded || deducedGenerics.Contains(null))
                {
                    // Проверка на то, что в Deconstruct все дженерики выводятся по self делается в другом месте
                    // TODO Patterns: сделать проверку из коммента выше
                    // TODO Patterns: запретить дженерик методы в классах. Можно использовать только дженерик-типы самого класса в качестве параметров
                    //AddError(deconstructionLocation, "COULDNT_DEDUCE_DECONSTRUCT_GENERIC_TYPE");
                    return(false);
                }
            }

            for (int i = 0; i < givenParameterTypes.Length; i++)
            {
                var givenParameter     = givenParameterTypes[i];
                var candidateParameter = candidateParameterTypes[i].type;
                if (genericDeduceNeeded && (candidateParameter.is_generic_parameter || candidateParameter.is_generic_type_instance))
                {
                    candidateParameter = InstantiateParameter(candidateParameter, deducedGenerics);
                }

                if (givenParameter != null && !AreTheSameType(candidateParameter, givenParameter))
                {
                    return(false);
                }

                parameterTypes[i] = candidateParameter;
            }

            return(true);
        }
 public static bool IsCapturedSelf(expression_node ex)
 {
     if (ex is class_field_reference)
     {
         class_field fld = (ex as class_field_reference).field;
         if (fld.name.Contains("<>local_variables_class"))
         {
             return(true);
         }
     }
     return(false);
 }
示例#9
0
 /// <summary>
 /// Выводит тип результата лямбды по первому присваиванию переменной Result.
 /// </summary>
 private void InferLambdaResultTypeFromAssignment(assign _assign, expression_node from, addressed_expression to)
 {
     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;
         }
     }
 }
示例#10
0
 private void CheckType(type_node type, expression_node initial_value, location loc)
 {
     /*if (type.IsPointer && type.element_type.is_value_type && type.element_type is common_type_node)
      * {
      *  AddHint("DO_NOT_USE_POINTERS_TO_RECORDS", loc);
      * }*/
     if (type.type_special_kind == SemanticTree.type_special_kind.short_string && !(current_type != null && current_type.is_value))
     {
         AddHint("DO_NOT_USE_SHORT_STRINGS", loc);
     }
     else if (type.type_special_kind == SemanticTree.type_special_kind.array_kind || type.type_special_kind == SemanticTree.type_special_kind.array_wrapper)
     {
         CheckType(type.element_type, initial_value, loc);
     }
 }
示例#11
0
        private void CheckAssign(expression_node p)
        {
            switch (p.semantic_node_type)
            {
            case semantic_node_type.local_variable_reference: IncreaseNumAssVar((local_variable_reference)p); break;

            case semantic_node_type.namespace_variable_reference: IncreaseNumAssVar((namespace_variable_reference)p); break;

            case semantic_node_type.class_field_reference: VisitExpression((p as class_field_reference).obj); IncreaseNumAssField((class_field_reference)p); break;

            case semantic_node_type.static_class_field_reference: IncreaseNumAssField((static_class_field_reference)p); break;

            case semantic_node_type.common_parameter_reference: IncreaseNumAssParam((common_parameter_reference)p); break;

            case semantic_node_type.deref_node: CheckAssign(((dereference_node)p).deref_expr); break;
            }
        }
示例#12
0
 private RetVal GetConstantValue(expression_node en)
 {
     if (en is bool_const_node)
     {
         if ((en as bool_const_node).constant_value)
         {
             return(RetVal.True);
         }
         else
         {
             return(RetVal.False);
         }
     }
     else
     {
         return(RetVal.Undef);
     }
 }
示例#13
0
        private bool Is1DArray(expression_node in_what)
        {
            var is1dimdynarr = false;
            var comptn       = in_what.type as compiled_type_node;

            if (comptn != null && comptn.type_special_kind == type_special_kind.array_kind && comptn.rank == 1)
            {
                is1dimdynarr = true;
            }
            if (!is1dimdynarr)
            {
                var comtn = in_what.type as common_type_node;
                if (comtn != null && comtn.internal_type_special_kind == type_special_kind.array_kind &&
                    comtn.rank == 1)
                {
                    is1dimdynarr = true;
                }
            }
            return(is1dimdynarr);
        }
示例#14
0
 /// <summary>
 /// Обрабатывает случай, когда левая часть присваивания short string.
 /// </summary>
 /// <returns>True - обработка прошла, иначе False.</returns>
 private bool ProcessAssignmentToShortStringIfPossible(assign _assign, addressed_expression to, expression_node from, location loc)
 {
     if (_assign.operator_type == Operators.Assignment)
     {
         if (to is simple_array_indexing &&
             (to as simple_array_indexing).simple_arr_expr.type.type_special_kind == 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(
                 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(true);
         }
         if (to.type.type_special_kind == 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(
                 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(true);
         }
     }
     return(false);
 }
示例#15
0
        private void VisitExpression(expression_node en)
        {
            if (en == null)
            {
                return;
            }
            //WriteDebugInfo(en.location);
            switch (en.semantic_node_type)
            {
            case semantic_node_type.exit_procedure:
                /*ничего писать не надо*/
                break;

            case semantic_node_type.typeof_operator:
                //VisitTypeOfOperator((typeof_operator)en);
                break;

            case semantic_node_type.statement_expression_node:
                VisitStatementsExpressionNode((statements_expression_node)en); break;

            case semantic_node_type.question_colon_expression:
                VisitQuestionColonExpression((question_colon_expression)en); break;

            case semantic_node_type.sizeof_operator:
                VisitSizeOfOperator((sizeof_operator)en); break;

            case semantic_node_type.is_node:
                VisitIsNode((is_node)en); break;

            case semantic_node_type.as_node:
                VisitAsNode((as_node)en); break;

            case semantic_node_type.compiled_static_method_call_node_as_constant:
                //VisitCompiledStaticMethodCallNodeAsConstant((compiled_static_method_call_as_constant)en);
                break;

            case semantic_node_type.array_initializer:
                VisitArrayInitializer((array_initializer)en);
                break;

            case semantic_node_type.record_initializer:
                VisitRecordInitializer((record_initializer)en);
                break;

            case semantic_node_type.array_const:
                //VisitArrayConst((array_const)en);
                break;

            case semantic_node_type.record_const:
                //VisitRecordConst((record_constant)en);
                break;

            case semantic_node_type.float_const_node:
                //VisitFloatConst((float_const_node)en);
                break;

            case semantic_node_type.byte_const_node:
                //VisitByteConstNode((byte_const_node)en);
                break;

            case semantic_node_type.int_const_node:
                //VisitIntConstNode((int_const_node)en);
                break;

            case semantic_node_type.sbyte_const_node:
                //VisitSByteConstNode((sbyte_const_node)en);
                break;

            case semantic_node_type.short_const_node:
                //VisitShortConstNode((short_const_node)en);
                break;

            case semantic_node_type.ushort_const_node:
                //VisitUShortConstNode((ushort_const_node)en);
                break;

            case semantic_node_type.uint_const_node:
                //VisitUIntConstNode((uint_const_node)en);
                break;

            case semantic_node_type.ulong_const_node:
                //VisitULongConstNode((ulong_const_node)en);
                break;

            case semantic_node_type.long_const_node:
                //VisitLongConstNode((long_const_node)en);
                break;

            case semantic_node_type.double_const_node:
                //VisitDoubleConstNode((double_const_node)en);
                break;

            case semantic_node_type.char_const_node:
                //VisitCharConstNode((char_const_node)en);
                break;

            case semantic_node_type.bool_const_node:
                //VisitBoolConstNode((bool_const_node)en);
                break;

            case semantic_node_type.string_const_node:
                //VisitStringConstNode((string_const_node)en);
                break;

            case semantic_node_type.local_variable_reference:
                VisitLocalVariableReference((local_variable_reference)en); break;

            case semantic_node_type.namespace_variable_reference:
                VisitNamespaceVariableReference((namespace_variable_reference)en); break;

            case semantic_node_type.basic_function_call:
                VisitBasicFunctionCall((basic_function_call)en); break;

            case semantic_node_type.common_parameter_reference:
                VisitCommonParameterReference((common_parameter_reference)en);
                break;

            case semantic_node_type.common_namespace_function_call:
                VisitCommonNamespaceFunctionCall((common_namespace_function_call)en); break;

            case semantic_node_type.basic_function_call_node_as_constant:
                VisitBasicFunctionCall((en as basic_function_call_as_constant).method_call); break;

            case semantic_node_type.common_namespace_function_call_node_as_constant:
                VisitCommonNamespaceFunctionCallAsConstant((common_namespace_function_call_as_constant)en); break;

            case semantic_node_type.common_in_function_function_call:
                VisitCommonInFuncFuncCall((common_in_function_function_call)en); break;

            case semantic_node_type.while_break_node:
                //VisitWhileBreakNode((while_break_node)en);
                is_break_stmt = true;
                break;

            case semantic_node_type.while_continue_node:
                //VisitWhileContinueNode((while_continue_node)en);
                is_break_stmt = true;
                break;

            case semantic_node_type.for_break_node:
                //VisitForBreakNode((for_break_node)en);
                is_break_stmt = true;
                break;

            case semantic_node_type.for_continue_node:
                //VisitForContinueNode((for_continue_node)en);
                is_break_stmt = true;
                break;

            case semantic_node_type.repeat_break_node:
                //VisitRepeatBreakNode((repeat_break_node)en);
                is_break_stmt = true;
                break;

            case semantic_node_type.repeat_continue_node:
                //VisitRepeatContinueNode((repeat_continue_node)en);
                is_break_stmt = true;
                break;

            case semantic_node_type.foreach_break_node:
                is_break_stmt = true;
                break;

            case semantic_node_type.foreach_continue_node:
                is_break_stmt = true;
                break;

            case semantic_node_type.common_static_method_call:
                VisitCommonStaticMethodCall((common_static_method_call)en); break;

            case semantic_node_type.compiled_static_method_call:
                VisitCompiledStaticMethodCall((compiled_static_method_call)en); break;

            case semantic_node_type.class_field_reference:
                VisitClassFieldReference((class_field_reference)en);
                break;

            case semantic_node_type.deref_node:
                VisitDerefNode((dereference_node)en); break;

            case semantic_node_type.common_method_call:
                VisitCommonMethodCall((common_method_call)en); break;

            case semantic_node_type.compiled_function_call:
                VisitCompiledFunctionCall((compiled_function_call)en); break;

            case semantic_node_type.get_addr_node:
                VisitGetAddrNode((get_addr_node)en); break;

            case semantic_node_type.common_constructor_call:
                VisitCommonConstructorCall((common_constructor_call)en); break;

            case semantic_node_type.compiled_constructor_call:
                VisitCompiledConstructorCall((compiled_constructor_call)en); break;

            case semantic_node_type.compiled_variable_reference:
                VisitCompiledVariableReference((compiled_variable_reference)en); break;

            case semantic_node_type.local_block_variable_reference:
                VisitLocalBlockVariableReference((local_block_variable_reference)en); break;

            case semantic_node_type.static_compiled_variable_reference:
                //VisitStaticCompiledVariableReference((static_compiled_variable_reference)en);
                break;

            case semantic_node_type.static_class_field_reference:
                VisitStaticClassFieldReference((static_class_field_reference)en);
                break;

            case semantic_node_type.non_static_property_reference:
                VisitNonStaticPropertyReference((non_static_property_reference)en); break;

            case semantic_node_type.simple_array_indexing:
                VisitSimpleArrayIndexing((simple_array_indexing)en); break;

            case semantic_node_type.this_node:
                //VisitThisNode((this_node)en);
                break;

            case semantic_node_type.null_const_node:
                //VisitNullConstNode((null_const_node)en);
                break;
                //default: ;//Console.WriteLine(en.semantic_node_type); throw new Exception("Unknown expression");
            }
        }
示例#16
0
        /// <summary>
        /// Обрабатывает случай, когда левая часть присваивания имеет тип event.
        /// </summary>
        /// <returns>True - обработка прошла, иначе False.</returns>
        private bool ProcessAssignmentToEventIfPossible(assign _assign, addressed_expression to, expression_node from,
                                                        location loc)
        {
            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;
                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 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 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(true);
            }
            return(false);
        }
示例#17
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);
        }
示例#18
0
        /// <summary>
        /// Автовыведение типов в yield'ax.
        /// </summary>
        private void ProcessAssigntToAutoType(addressed_expression to, ref expression_node from)
        {
            var sequence = to.type as compiled_generic_instance_type_node;

            // SSM 26.06.16 - правка в связи с автовыведением типов в yieldах
            if (to.type is auto_type)
            {
                try_convert_typed_expression_to_function_call(ref from);
                if (to is class_field_reference)
                {
                    var cfr = to as class_field_reference;

                    if (from is typed_expression) // SSM 22.12.18 syntax_tree_visitor.cs 16066 - взял оттуда
                    {
                        base_function_call bfc = ((from as typed_expression).type as delegated_methods).proper_methods[0];

                        /*if (bfc.function.is_generic_function && _var_def_statement.vars_type == null)
                         * {
                         *  AddError(inital_value.location, "CAN_NOT_DEDUCE_TYPE_{0}", null);
                         * }
                         * foreach (parameter p in bfc.simple_function_node.parameters)
                         * {
                         *  if (p.type.is_generic_parameter)
                         *      AddError(inital_value.location, "USE_ANONYMOUS_FUNCTION_TYPE_WITH_GENERICS");
                         * } */
                        common_type_node del =
                            convertion_data_and_alghoritms.type_constructor.create_delegate(context.get_delegate_type_name(), bfc.simple_function_node.return_value_type, bfc.simple_function_node.parameters, context.converted_namespace, null);
                        context.converted_namespace.types.AddElement(del); //- сомневаюсь - контекст уже поменялся!
                        //tn = del;
                        from      = convertion_data_and_alghoritms.explicit_convert_type(from, del);
                        from.type = del;
                    }

                    cfr.field.type = from.type;
                    cfr.type       = from.type; // Это неверно работает когда yieldится процедура #1439
                                                // SSM 1.11.18 попытка правки возвращения процедуры в yield
                                                //if (from.type.semantic_node_type == semantic_node_type.delegated_method)
                                                //cfr.type.semantic_node_type = semantic_node_type.delegated_method;


                    cfr.field.inital_value = context.GetInitalValueForVariable(cfr.field, cfr.field.inital_value);
                }
                else if (to is local_block_variable_reference)
                {
                    var lvr = to as local_block_variable_reference;
                    lvr.var.type         = from.type;
                    lvr.type             = from.type;
                    lvr.var.inital_value = context.GetInitalValueForVariable(lvr.var, lvr.var.inital_value);
                }
                else
                {
                    AddError(to.location, "Не могу вывести тип при наличии yield: " + to.type.full_name);
                }
                //to.type = from.type; // и без всякого real_type!
            }
            else if (sequence?.instance_params[0] is ienumerable_auto_type)
            {
                type_node elem_type = null;
                try_convert_typed_expression_to_function_call(ref from);
                bool bb; // здесь bb не нужно. Оно нужно в foreach
                var  b = FindIEnumerableElementType(from.type, ref elem_type, out bb);
                if (!b)
                {
                    AddError(from.location, "CAN_NOT_EXECUTE_FOREACH_BY_EXPR_OF_TYPE_{0}", from.type.full_name);
                }

                var IEnumType = new template_type_reference(new named_type_reference("System.Collections.Generic.IEnumerable"),
                                                            new template_param_list(new semantic_type_node(elem_type)));
                if (to is class_field_reference)
                {
                    var cfr = to as class_field_reference;

                    cfr.field.type = convert_strong(IEnumType);
                    cfr.type       = cfr.field.type;
                }
                else if (to is local_block_variable_reference)
                {
                    var lvr = to as local_block_variable_reference;

                    lvr.var.type = convert_strong(IEnumType); // замена типа у описания переменной
                    lvr.type     = lvr.var.type;              // замена типа у переменной
                }
            }
        }
示例#19
0
        /// <summary>
        /// Преобразует в семантическое представление поля to и from, проводя семантические проверки.
        /// </summary>
        private void AssignCheckAndConvert(assign _assign, out addressed_expression to, out expression_node from)
        {
            internal_is_assign = true;
            to = convert_address_strong(_assign.to);
            internal_is_assign = false;
            if (to == null)
            {
                AddError(get_location(_assign.to), "CAN_NOT_ASSIGN_TO_LEFT_PART");
            }

            //(ssyy) Вставляю проверки прямо сюда, т.к. запарился вылавливать другие случаи.
            bool flag;
            general_node_type node_type;

            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));
                }
            }

            // SSM исправление Саушкина 10.03.16
            var fromAsLambda = _assign.from as function_lambda_definition;

            if (fromAsLambda != null)
            {
                #region Вывод параметров лямбда-выражения

                LambdaHelper.InferTypesFromVarStmt(to.type, fromAsLambda, this); //lroman//

                #endregion

                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);
                ProcessAssigntToAutoType(to, ref from);
            }
            // end

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

            location loc = get_location(_assign);

            if (to is class_field_reference)
            {
                var classFieldRef = to as class_field_reference;
                if (classFieldRef.obj.type.type_special_kind == type_special_kind.record &&
                    classFieldRef.obj is base_function_call)
                {
                    //исключим ситуацию обращения к массиву
                    if (!(classFieldRef.obj is common_method_call &&
                          (classFieldRef.obj as common_method_call).obj.type.type_special_kind ==
                          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);
            }
            if (context.is_in_cycle() && !SemanticRules.AllowChangeLoopVariable)
            {
                var_definition_node toAsVariable = GetLocalVariableFromAdressExpressionIfPossible(to);
                if (toAsVariable != null && context.is_loop_variable(toAsVariable))
                {
                    AddError(to.location, "CANNOT_ASSIGN_TO_LOOP_VARIABLE");
                }
            }
            {
                var classFieldRef = (to as simple_array_indexing)?.simple_arr_expr as class_field_reference;
                if (classFieldRef?.obj is constant_node)
                {
                    AddError(loc, "LEFT_SIDE_CANNOT_BE_ASSIGNED_TO");
                }
            }
        }
示例#20
0
        /// <summary>
        /// Преобразует foreach в for, если коллекция это одномерный массив.
        /// </summary>
        /// <param name="_foreach_stmt"></param>
        /// <param name="in_what"></param>
        /// <returns>True - если преобразование удалось, иначе False</returns>
        private bool OptimizeForeachInCase1DArray(foreach_stmt _foreach_stmt, expression_node in_what)
        {
            var is1dimdynarr = false;
            var comptn       = in_what.type as compiled_type_node;

            if (comptn != null && comptn.type_special_kind == type_special_kind.array_kind && comptn.rank == 1)
            {
                is1dimdynarr = true;
            }
            if (!is1dimdynarr)
            {
                var comtn = in_what.type as common_type_node;
                if (comtn != null && comtn.internal_type_special_kind == type_special_kind.array_kind &&
                    comtn.rank == 1)
                {
                    is1dimdynarr = true;
                }
            }


            // SSM 23.08.16 Закомментировал оптимизацию. Не работает с лямбдами. Лямбды обходят старое дерево. А заменить foreach на for на этом этапе пока не получается - не развита инфраструктура

            if (is1dimdynarr) // Замена foreach на for для массива
            {
                // сгенерировать код для for и вызвать соответствующий visit
                var arrid = GenIdentName();
                //var vdarr = new var_statement(arrid, new semantic_addr_value(in_what)); // semantic_addr_value - перевод в синтаксис для мгновенного вычисления семантического выражения, которое уже вычислено в in_what
                var vdarr = new var_statement(arrid, _foreach_stmt.in_what);

                var i = GenIdentName();
                var x = _foreach_stmt.identifier;

                // Возможны 3 случая:
                // 1. _foreach_stmt.type_name = null - значит, переменная определена в другом месте
                // 2. _foreach_stmt.type_name = no_type_foreach - значит, это for var x in a
                // 3. _foreach_stmt.type_name = T - значит, это for var x: T in a

                statement vd;
                if (_foreach_stmt.type_name == null) // 1.
                {
                    vd = new assign(x, arrid.indexer(i));
                }
                else if (_foreach_stmt.type_name is no_type_foreach) // 2.
                {
                    vd = new var_statement(x, arrid.indexer(i));
                }
                else // 3.
                {
                    vd = new var_statement(x, _foreach_stmt.type_name, arrid.indexer(i));
                }

                // Превратить старое тело в statement_list и добавить к нему в начало x := a[i] или var x := a[i]
                var newbody = _foreach_stmt.stmt.ToStatementList();
                newbody.AddFirst(vd);

                var high = arrid.dot_node("Length").Minus(1);

                var fornode = new for_node(i, 0, high, newbody, for_cycle_type.to, null, null, true);

                var stl = new statement_list(vdarr, fornode);
                // Замена 1 оператора на 1 оператор. Всё хорошо даже если оператор помечен меткой
                ReplaceUsingParent(_foreach_stmt, stl);

                visit(stl);
                //visit(vdarr);
                //visit(fornode);

                return(true);
            }
            /// SSM 29.07.16
            return(false);
        }
示例#21
0
        private type_node[] InferAndCheckPatternVariableTypes(List <var_def_statement> variableDefinitions, expression_node patternInstance, desugared_deconstruction deconstruction)
        {
            var parameterTypes = variableDefinitions.Select(x => x.vars_type == null ? null : convert_strong(x.vars_type)).ToArray();
            List <function_node> candidates            = new List <function_node>();
            List <type_node[]>   deducedParametersList = new List <type_node[]>();
            var allDeconstructs = patternInstance.type.find_in_type(compiler_string_consts.deconstruct_method_name, context.CurrentScope);

            foreach (var canditateSymbol in allDeconstructs)
            {
                var deducedParameters = new type_node[parameterTypes.Length];
                var possibleCandidate = canditateSymbol.sym_info as function_node;
                if (!IsSuitableFunction(possibleCandidate, parameterTypes, patternInstance, get_location(deconstruction), out deducedParameters))
                {
                    continue;
                }

                deducedParametersList.Add(deducedParameters);
                candidates.Add(possibleCandidate);
            }

            if (candidates.Count == 0)
            {
                AddError(get_location(deconstruction), "NO_SUITABLE_DECONSTRUCT_FOUND");
                return(null);
            }
            else
            if (candidates.Count > 1)
            {
                RemoveDefaultDeconstruct(candidates);
                if (candidates.Count > 1 && !CheckIfParameterListElementsAreTheSame(deducedParametersList))
                {
                    AddError(get_location(deconstruction), "DECONSTRUCTOR_METHOD_AMBIGUITY");
                    return(null);
                }
            }

            // Единственный подхдящий кандидат найден, либо их несколько, с одинаковыми выходными параметрами
            var chosenFunction = candidates.First();

            if (chosenFunction.is_extension_method)
            {
                if (chosenFunction.is_generic_function)
                {
                    chosenFunction = generic_convertions.get_function_instance(chosenFunction, deducedParametersList.First().ToList());
                }

                return(chosenFunction.parameters.Where(x => !IsSelfParameter(x)).Select(x => x.type).ToArray());
            }
            else
            {
                return(chosenFunction.parameters.Select(x => x.type).ToArray());//deducedParametersList[0];
            }
        }
示例#22
0
        public override void visit(for_node _for_node)
        {
            #region MikhailoMMX, обработка omp parallel for
            bool isGenerateParallel   = false;
            bool isGenerateSequential = true;
            if (OpenMP.ForsFound)
            {
                OpenMP.LoopVariables.Push(_for_node.loop_variable.name.ToLower());
                //если в программе есть хоть одна директива parallel for - проверяем:
                if (DirectivesToNodesLinks.ContainsKey(_for_node) && OpenMP.IsParallelForDirective(DirectivesToNodesLinks[_for_node]))
                {
                    //перед этим узлом есть директива parallel for
                    if (CurrentParallelPosition == ParallelPosition.Outside)            //входим в самый внешний параллельный for
                    {
                        if (_for_node.create_loop_variable || (_for_node.type_name != null))
                        {
                            //сгенерировать сначала последовательную ветку, затем параллельную
                            //устанавливаем флаг и продолжаем конвертирование, считая, что конвертируем последовательную ветку
                            isGenerateParallel      = true;
                            CurrentParallelPosition = ParallelPosition.InsideSequential;
                            //в конце за счет флага вернем состояние обратно и сгенерируем и параллельную ветку тоже
                        }
                        else
                        {
                            WarningsList.Add(new OMP_BuildigError(new Exception("Переменная параллельного цикла должна быть определена в заголовке цикла"), new location(_for_node.source_context.begin_position.line_num, _for_node.source_context.begin_position.column_num, _for_node.source_context.end_position.line_num, _for_node.source_context.end_position.column_num, new document(_for_node.source_context.FileName))));
                        }
                    }
                    else //уже генерируем одну из веток
                         //если это параллельная ветка - последовательную генерировать не будем
                    if (CurrentParallelPosition == ParallelPosition.InsideParallel)
                    {
                        isGenerateParallel   = true;
                        isGenerateSequential = false;
                    }
                    //else
                    //а если последовательная - то флаг isGenerateParallel не установлен, сгенерируется только последовательная
                }
            }
            #endregion


            location            loopVariableLocation = get_location(_for_node.loop_variable);
            var_definition_node vdn = null;
            expression_node     left, right, res;
            expression_node     initialValue = convert_strong(_for_node.initial_value);
            expression_node     tmp          = initialValue;
            if (initialValue is typed_expression)
            {
                initialValue = convert_typed_expression_to_function_call(initialValue as typed_expression);
            }
            if (initialValue.type == null)
            {
                initialValue = tmp;
            }
            statements_list head_stmts = new statements_list(loopVariableLocation);
            convertion_data_and_alghoritms.statement_list_stack_push(head_stmts);

            var early_init_loop_variable = false; // SSM 25/05/16
            if (_for_node.type_name == null && !_for_node.create_loop_variable)
            {
                definition_node dn = context.check_name_node_type(_for_node.loop_variable.name, loopVariableLocation,
                                                                  general_node_type.variable_node);
                vdn = (var_definition_node)dn;
                if (context.is_loop_variable(vdn))
                {
                    AddError(get_location(_for_node.loop_variable), "CANNOT_ASSIGN_TO_LOOP_VARIABLE");
                }
                if (!check_name_in_current_scope(_for_node.loop_variable.name))
                {
                    AddError(new ForLoopControlMustBeSimpleLocalVariable(loopVariableLocation));
                }
            }
            else
            {
                //В разработке DS
                //throw new NotSupportedError(get_location(_for_node.type_name));
                type_node tn;
                if (_for_node.type_name != null)
                {
                    tn = convert_strong(_for_node.type_name);
                }
                else
                {
                    tn = initialValue.type;
                }
                //if (tn == SystemLibrary.SystemLibrary.void_type && _for_node.type_name != null)
                //	AddError(new VoidNotValid(get_location(_for_node.type_name)))
                if (_for_node.type_name != null)
                {
                    check_for_type_allowed(tn, get_location(_for_node.type_name));
                }
                vdn = context.add_var_definition(_for_node.loop_variable.name, get_location(_for_node.loop_variable), tn, initialValue /*, polymorphic_state.ps_common*/);
                vdn.polymorphic_state    = polymorphic_state.ps_common;
                early_init_loop_variable = true; // SSM 25/05/16
            }
            internal_interface ii = vdn.type.get_internal_interface(internal_interface_kind.ordinal_interface);
            if (ii == null)
            {
                AddError(new OrdinalTypeExpected(loopVariableLocation));
            }
            ordinal_type_interface oti = (ordinal_type_interface)ii;


            location            finishValueLocation = get_location(_for_node.finish_value);
            var_definition_node vdn_finish          = context.create_for_temp_variable(vdn.type, finishValueLocation);
            //Это должно стоять раньше!!
            left = create_variable_reference(vdn_finish, loopVariableLocation);
            expression_node finishValue = convert_strong(_for_node.finish_value);
            right = finishValue;
            if (right is typed_expression)
            {
                right = convert_typed_expression_to_function_call(right as typed_expression);
            }
            res = find_operator(compiler_string_consts.assign_name, left, right, finishValueLocation);
            head_stmts.statements.AddElement(res);

            if (!early_init_loop_variable) // SSM 25/05/16 - for var i := f1() to f2() do без этой правки дважды вызывал f1()
            {
                left  = create_variable_reference(vdn, loopVariableLocation);
                right = initialValue;
                res   = find_operator(compiler_string_consts.assign_name, left, right, loopVariableLocation);
                head_stmts.statements.AddElement(res);
            }


            location initialValueLocation = get_location(_for_node.initial_value);

            statement_node  sn_inc        = null;
            expression_node sn_while      = null;
            expression_node sn_init_while = null;
            left  = create_variable_reference(vdn, initialValueLocation);
            right = create_variable_reference(vdn, finishValueLocation);
            expression_node right_border = create_variable_reference(vdn_finish, finishValueLocation);
            switch (_for_node.cycle_type)
            {
            case for_cycle_type.to:
            {
                sn_inc =
                    convertion_data_and_alghoritms.create_simple_function_call(oti.inc_method, loopVariableLocation,
                                                                               left);
                sn_while = convertion_data_and_alghoritms.create_simple_function_call(oti.lower_method,
                                                                                      finishValueLocation, right, right_border);
                sn_init_while = convertion_data_and_alghoritms.create_simple_function_call(oti.lower_eq_method,
                                                                                           finishValueLocation, right, right_border);
                break;
            }

            case for_cycle_type.downto:
            {
                sn_inc =
                    convertion_data_and_alghoritms.create_simple_function_call(oti.dec_method, loopVariableLocation,
                                                                               left);
                sn_while = convertion_data_and_alghoritms.create_simple_function_call(oti.greater_method,
                                                                                      finishValueLocation, right, right_border);
                sn_init_while = convertion_data_and_alghoritms.create_simple_function_call(oti.greater_eq_method,
                                                                                           finishValueLocation, right, right_border);
                break;
            }
            }

            CheckToEmbeddedStatementCannotBeADeclaration(_for_node.statements);

            //DarkStar Modifed
            //исправил ошибку:  не работали break в циклах
            TreeRealization.for_node forNode = new TreeRealization.for_node(null, sn_while, sn_init_while, sn_inc, null, get_location(_for_node));
            if (vdn.type == SystemLibrary.SystemLibrary.bool_type)
            {
                forNode.bool_cycle = true;
            }
            context.cycle_stack.push(forNode);
            context.loop_var_stack.Push(vdn);
            statements_list slst = new statements_list(get_location(_for_node.statements));
            convertion_data_and_alghoritms.statement_list_stack_push(slst);

            context.enter_code_block_with_bind();
            forNode.body = convert_strong(_for_node.statements);
            context.leave_code_block();

            slst = convertion_data_and_alghoritms.statement_list_stack.pop();
            if (slst.statements.Count > 0 || slst.local_variables.Count > 0)
            {
                slst.statements.AddElement(forNode.body);
                forNode.body = slst;
            }

            context.cycle_stack.pop();
            context.loop_var_stack.Pop();
            head_stmts = convertion_data_and_alghoritms.statement_list_stack.pop();
            head_stmts.statements.AddElement(forNode);

            #region MikhailoMMX, обработка omp parallel for
            //флаг был установлен только если это самый внешний parallel for и нужно сгенерировать обе ветки
            //или если это вложенный parallel for, нужно сгенерировать обе ветки, но без проверки на OMP_Available
            //Последовательная ветка только что сгенерирована, теперь меняем состояние и генерируем параллельную
            if (isGenerateParallel)
            {
                CurrentParallelPosition = ParallelPosition.InsideParallel;
                statements_list stl = OpenMP.TryConvertFor(head_stmts, _for_node, forNode, vdn, initialValue, finishValue, this);
                CurrentParallelPosition = ParallelPosition.Outside;
                if (stl != null)
                {
                    var f = _for_node.DescendantNodes().OfType <function_lambda_definition>().FirstOrDefault();
                    if (f != null)
                    {
                        AddError(get_location(f), "OPENMP_CONTROLLED_CONSTRUCTIONS_CANNOT_CONTAIN_LAMBDAS");
                    }

                    OpenMP.LoopVariables.Pop();
                    return_value(stl);
                    return;
                }
            }
            if (OpenMP.ForsFound)
            {
                OpenMP.LoopVariables.Pop();
            }
            #endregion

            return_value(head_stmts);
        }