Beispiel #1
0
 private void SaveVariable(var_definition_node cfn)
 {
     if (!string.IsNullOrEmpty(cfn.documentation))
     {
         if (!cfn.documentation.Trim(' ', '\t').StartsWith("<summary>"))
         {
             xtw.WriteStartElement("member");
             xtw.WriteStartAttribute("name");
             if (!is_assembly)
             {
                 xtw.WriteString("V:" + cfn.name);
             }
             else
             {
                 xtw.WriteString("F:" + unit_name + "." + unit_name + "." + cfn.name);
             }
             xtw.WriteEndAttribute();
             xtw.WriteStartElement("summary");
             xtw.WriteString(cfn.documentation);
             xtw.WriteEndElement();
             xtw.WriteEndElement();
         }
         else
         {
             string       doc = string.Concat("<member name=\"" + (is_assembly?"F:" + unit_name + "." + unit_name + ".":"V:") + cfn.name + "\">", cfn.documentation, "</member>");
             StringReader sr  = new StringReader(doc);
             XmlReader    xr  = XmlTextReader.Create(sr);
             xr.Read();
             xtw.WriteNode(xr.ReadSubtree(), false);
             sr.Close();
             xr.Close();
         }
     }
 }
        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);
        }
Beispiel #3
0
        public void AddVariable(var_definition_node vdn)
        {
            VarInfo vi = new VarInfo();

            if (ht[vdn] == null)
            {
                ht[vdn] = vi;
            }
        }
Beispiel #4
0
        private void IncreaseNumUseVar(var_definition_node lvr)
        {
            VarInfo vi = helper.GetVariable(lvr);

            vi.num_use++;
            vi.act_num_use++;
            vi.cur_use++;
            //if (vi.cur_ass == 0 && !lvr.var.name.Contains("$")) helper.AddTempWarning(lvr.var,new UseWithoutAssign(lvr.var.name, lvr.location));
        }
Beispiel #5
0
        public void AddTempWarning(var_definition_node vdn, CompilerWarningWithLocation cw)
        {
            List <CompilerWarningWithLocation> lst = (List <CompilerWarningWithLocation>)warns[vdn];

            if (lst == null)
            {
                lst        = new List <CompilerWarningWithLocation>();
                warns[vdn] = lst;
            }
            lst.Add(cw);
        }
Beispiel #6
0
        private var_definition_node FindForeachVariable(foreach_stmt _foreach_stmt, type_node elem_type, bool sys_coll_ienum)
        {
            var_definition_node foreachVariable = null;

            if (_foreach_stmt.type_name == null) // значит, переменная определена в другом месте
            {
                location        loc1 = get_location(_foreach_stmt.identifier);
                definition_node dn   = context.check_name_node_type(_foreach_stmt.identifier.name, loc1,
                                                                    general_node_type.variable_node);
                foreachVariable = (var_definition_node)dn;
                if (!check_name_in_current_scope(_foreach_stmt.identifier.name))
                {
                    AddError(loc1, "FOREACH_LOOP_CONTROL_MUST_BE_SIMPLE_LOCAL_VARIABLE");
                }
            }
            else
            {
                foreachVariable = context.add_var_definition(_foreach_stmt.identifier.name,
                                                             get_location(_foreach_stmt.identifier));

                type_node tn;
                if (_foreach_stmt.type_name is no_type_foreach) // значит, это for var x in a
                {
                    tn = elem_type;
                }
                else // значит, это for var x: T in a
                {
                    tn = convert_strong(_foreach_stmt.type_name);
                    check_for_type_allowed(tn, get_location(_foreach_stmt.type_name));
                    check_using_static_class(tn, get_location(_foreach_stmt.type_name));
                }
                if (tn.is_value_type && !tn.is_standard_type)
                {
                    context.close_var_definition_list(tn, new default_operator_node(tn, foreachVariable.location));
                }
                else
                {
                    context.close_var_definition_list(tn, null);
                }
            }

            if (/*!(foreachVariable.type is compiled_generic_instance_type_node) &&*/ !sys_coll_ienum) // SSM 16.09.18 - закомментировал это ограничение для фиксации бага #1184
            {
                convertion_data_and_alghoritms.check_convert_type_with_inheritance(elem_type, foreachVariable.type,
                                                                                   get_location(_foreach_stmt.identifier));
            }
            return(foreachVariable);
        }
Beispiel #7
0
        private var_definition_node FindForeachVariable(foreach_stmt _foreach_stmt, type_node elem_type, bool sys_coll_ienum)
        {
            var_definition_node foreachVariable = null;

            if (_foreach_stmt.type_name == null) // значит, переменная определена в другом месте
            {
                location        loc1 = get_location(_foreach_stmt.identifier);
                definition_node dn   = context.check_name_node_type(_foreach_stmt.identifier.name, loc1,
                                                                    general_node_type.variable_node);
                foreachVariable = (var_definition_node)dn;
                if (!check_name_in_current_scope(_foreach_stmt.identifier.name))
                {
                    AddError(loc1, "FOREACH_LOOP_CONTROL_MUST_BE_SIMPLE_LOCAL_VARIABLE");
                }
            }
            else
            {
                foreachVariable = context.add_var_definition(_foreach_stmt.identifier.name,
                                                             get_location(_foreach_stmt.identifier));

                type_node tn;
                if (_foreach_stmt.type_name is no_type_foreach) // значит, это for var x in a
                {
                    tn = elem_type;
                }
                else // значит, это for var x: T in a
                {
                    tn = convert_strong(_foreach_stmt.type_name);
                    check_for_type_allowed(tn, get_location(_foreach_stmt.type_name));
                }

                context.close_var_definition_list(tn, null);
            }

            if (!(foreachVariable.type is compiled_generic_instance_type_node) && !sys_coll_ienum)
            {
                convertion_data_and_alghoritms.check_convert_type_with_inheritance(elem_type, foreachVariable.type,
                                                                                   get_location(_foreach_stmt.identifier));
            }
            return(foreachVariable);
        }
Beispiel #8
0
        public override void visit(foreach_stmt _foreach_stmt)
        {
            var loopIdentName = _foreach_stmt.identifier.name.ToLower();

            definition_node     dn  = null;
            var_definition_node vdn = null;

            var sl2 = new statements_list(_visitor.get_location(_foreach_stmt));

            _visitor.convertion_data_and_alghoritms.statement_list_stack_push(sl2);

            var newTreeNode = new CapturedVariablesTreeNodeForEachScope(_currentTreeNode, sl2.Scope.ScopeNum, _foreach_stmt);

            if (_currentTreeNode != null)
            {
                _currentTreeNode.ChildNodes.Add(newTreeNode);
            }
            _currentTreeNode = newTreeNode;

            _scopesCapturedVarsNodesDictionary.Add(sl2.Scope.ScopeNum, _currentTreeNode);

            var inWhat = _visitor.convert_strong(_foreach_stmt.in_what);
            var tmp    = inWhat;

            if (inWhat is typed_expression)
            {
                inWhat = _visitor.convert_typed_expression_to_function_call(inWhat as typed_expression);
            }

            type_node elemType = null;

            if (inWhat.type == null)
            {
                inWhat = tmp;
            }

            _visitor.FindIEnumerableElementType(/*_foreach_stmt, */ inWhat.type, ref elemType);

            if (_foreach_stmt.type_name == null)
            {
                var loc1 = _visitor.get_location(_foreach_stmt.identifier);
                dn  = _visitor.context.check_name_node_type(loopIdentName, loc1, general_node_type.variable_node);
                vdn = (var_definition_node)dn;
            }
            else
            {
                vdn = _visitor.context.add_var_definition(loopIdentName, _visitor.get_location(_foreach_stmt.identifier));

                type_node tn;
                if (_foreach_stmt.type_name is no_type_foreach)
                {
                    tn = elemType;
                }
                else
                {
                    tn = _visitor.convert_strong(_foreach_stmt.type_name);
                    _visitor.check_for_type_allowed(tn, _visitor.get_location(_foreach_stmt.type_name));
                }


                _visitor.context.close_var_definition_list(tn, null);

                _currentTreeNode.VariablesDefinedInScope.Add(new CapturedVariablesTreeNode.CapturedSymbolInfo(_foreach_stmt, _visitor.context.find(loopIdentName)));
            }

            newTreeNode.SymbolInfoLoopVar = _visitor.context.find(loopIdentName);

            if (!(vdn.type is compiled_generic_instance_type_node))
            {
                _visitor.convertion_data_and_alghoritms.check_convert_type_with_inheritance(vdn.type, elemType, _visitor.get_location(_foreach_stmt.identifier));
            }

            var fn = new foreach_node(vdn, inWhat, null, _visitor.get_location(_foreach_stmt));

            _visitor.context.cycle_stack.push(fn);
            _visitor.context.loop_var_stack.Push(vdn);

            ProcessNode(_foreach_stmt.in_what);

            if (!(_foreach_stmt.stmt is statement_list))
            {
                var stmtList = new statement_list(_foreach_stmt.stmt, _foreach_stmt.stmt.source_context);
                _foreach_stmt.stmt = stmtList;
            }

            ProcessNode(_foreach_stmt.stmt);

            _visitor.context.loop_var_stack.Pop();
            _visitor.convertion_data_and_alghoritms.statement_list_stack.pop();
            _visitor.context.cycle_stack.pop();

            _currentTreeNode = _currentTreeNode.ParentNode;
        }
Beispiel #9
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");
                }
            }
        }
Beispiel #10
0
        public void AddRealWarning(var_definition_node vdn, List <CompilerWarningWithLocation> cw)
        {
            List <CompilerWarningWithLocation> lst = (List <CompilerWarningWithLocation>)warns[vdn];

            cw.AddRange(lst);
        }
Beispiel #11
0
 public VarInfo GetVariable(var_definition_node vdn)
 {
     return((VarInfo)ht[vdn]);
 }
Beispiel #12
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);
        }