public LambdaResultTypeInferrer(function_header lambdaHeader, proc_block lambdaBody, syntax_tree_visitor syntaxTreeVisitor)
 {
     this.lambdaBody = lambdaBody;
     this.lambdaHeader = lambdaHeader;
     this.syntaxTreeVisitor = syntaxTreeVisitor;
     resultExpressionsTypes = new List<Tuple<type_node, expression, expression_node>>();
 }
        //private special_operation_kind _current_operation_kind= special_operation_kind.none;

		public convertion_data_and_alghoritms(syntax_tree_visitor stv)
		{
            type_table.type_table_function_call_maker = create_simple_function_call;
			_stv=stv;
            _type_constructor = new type_constructor(this);
            SystemLibrary.SystemLibrary.type_constructor = _type_constructor;
		}
 public CapturedVariablesSubstitutor(Dictionary<SubstitutionKey, List<ident>> identsReferences,
                                     Dictionary<int, CapturedVariablesSubstitutionClassGenerator.ScopeClassDefinition> generatedScopeClassesInfo,
                                     List<CapturedVariablesTreeNodeLambdaScope> lambdasToBeAddedAsMethods,
                                     Dictionary<SubstitutionKey, dot_node> substitutionsInfo,
                                     Dictionary<int, CapturedVariablesTreeNode> capturedVarsTreeNodesDictionary,
                                     Dictionary<string, Tuple<string, class_field, semantic_node>> mappingForNonPublicFieldsOfClass,
                                     syntax_tree_visitor visitor)
 {
     _identsReferences = identsReferences;
     _generatedScopeClassesInfo = generatedScopeClassesInfo;
     _substitutionsInfo = substitutionsInfo;
     _capturedVarsTreeNodesDictionary = capturedVarsTreeNodesDictionary;
     _lambdasToBeAddedAsMethods = lambdasToBeAddedAsMethods;
     _mappingForNonPublicFieldsOfClass = mappingForNonPublicFieldsOfClass;
     _visitor = visitor;
 }
Beispiel #4
0
		public returner(syntax_tree_visitor stv)
		{
            syntax_tree_visitor = stv;
		}
        /// <summary>
        /// Вывод типа параметров лямбд и типа возвращаемого значения при присваивании лямбды переменной
        /// </summary>
        public static void InferTypesFromVarStmt(type_node leftType, function_lambda_definition lambdaDef, syntax_tree_visitor visitor, Operators op = Operators.Undefined)
        {
            if (lambdaDef == null)
            {
                return;
            }
            if (leftType != null)
            {
                delegate_internal_interface dii_left =
                    (delegate_internal_interface)leftType.get_internal_interface(internal_interface_kind.delegate_interface);
                if (dii_left == null)
                {
                    if (leftType != SystemLibrary.SystemLibrary.system_delegate_type)
                    {
                        if (op != Operators.Undefined)
                        {
                            var sil = leftType.find_in_type(name_reflector.get_name(op));
                            if (sil != null && sil.Count > 0)
                            {
                                foreach (SymbolInfo si in sil)
                                {
                                    if (si.sym_info is function_node)
                                    {
                                        function_node fn = si.sym_info as function_node;
                                        if (fn.parameters.Count == 2)
                                        {
                                            dii_left = (delegate_internal_interface)fn.parameters[1].type.get_internal_interface(internal_interface_kind.delegate_interface);
                                            if (dii_left != null)
                                            {
                                                break;
                                            }
                                            if (fn.parameters[1].type.is_generic_parameter)
                                            {
                                                compiled_type_node ctn  = leftType as compiled_type_node;
                                                common_type_node   ctn2 = leftType as common_type_node;
                                                if (ctn != null && ctn.is_generic_type_instance && fn.parameters[0].type.is_generic_type_instance && ctn.original_generic == fn.parameters[0].type.original_generic)
                                                {
                                                    dii_left = (delegate_internal_interface)ctn.generic_params[0].get_internal_interface(internal_interface_kind.delegate_interface);
                                                    if (dii_left != null)
                                                    {
                                                        break;
                                                    }
                                                }
                                                if (ctn2 != null && ctn2.is_generic_type_instance && ctn2.instance_params.Count > 0 && fn.parameters[0].type.is_generic_type_instance && ctn2.original_generic == fn.parameters[0].type.original_generic)
                                                {
                                                    dii_left = (delegate_internal_interface)ctn2.instance_params[0].get_internal_interface(internal_interface_kind.delegate_interface);
                                                    if (dii_left != null)
                                                    {
                                                        break;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        if (dii_left == null)
                        {
                            visitor.AddError(visitor.get_location(lambdaDef), "ILLEGAL_LAMBDA_VARIABLE_TYPE");
                        }
                    }
                    else
                    {
                        return;
                    }
                }

                int leftTypeParamsNumber = dii_left.parameters.Count;
                int lambdaDefParamsCount = 0;
                if (lambdaDef.formal_parameters != null && lambdaDef.formal_parameters.params_list.Count != 0)
                {
                    for (int i = 0; i < lambdaDef.formal_parameters.params_list.Count; i++)
                    {
                        lambdaDefParamsCount += lambdaDef.formal_parameters.params_list[i].idents.idents.Count;
                    }
                    if (lambdaDefParamsCount != leftTypeParamsNumber)
                    {
                        visitor.AddError(visitor.get_location(lambdaDef), "ILLEGAL_LAMBDA_PARAMETERS_NUMBER");
                    }
                    bool flag = true;
                    SyntaxTree.formal_parameters lambdaDefParamsTypes = new formal_parameters();
                    for (int i = 0; i < lambdaDef.formal_parameters.params_list.Count; i++)
                    {
                        for (int j = 0; j < lambdaDef.formal_parameters.params_list[i].idents.idents.Count; j++)
                        {
                            var param = new SyntaxTree.typed_parameters();
                            param.idents = new ident_list();
                            param.idents.Add(lambdaDef.formal_parameters.params_list[i].idents.idents[j]);
                            param.vars_type      = lambdaDef.formal_parameters.params_list[i].vars_type;
                            param.source_context = lambdaDef.formal_parameters.source_context;
                            lambdaDefParamsTypes.Add(param);
                        }
                    }
                    for (int i = 0; i < leftTypeParamsNumber && flag; i++)
                    {
                        if (lambdaDefParamsTypes.params_list[i].vars_type is SyntaxTree.lambda_inferred_type)
                        {
                            if ((lambdaDefParamsTypes.params_list[i].vars_type as SyntaxTree.lambda_inferred_type).real_type is lambda_any_type_node)
                            {
                                var curLeftParType = dii_left.parameters[i].type;
                                lambdaDefParamsTypes.params_list[i].vars_type = new SyntaxTree.lambda_inferred_type();
                                (lambdaDefParamsTypes.params_list[i].vars_type as SyntaxTree.lambda_inferred_type).real_type = curLeftParType;
                                continue;
                            }
                        }
                        var lambdaPar = visitor.convert_strong(lambdaDefParamsTypes.params_list[i].vars_type);
                        if (!convertion_data_and_alghoritms.eq_type_nodes(dii_left.parameters[i].type, lambdaPar))
                        {
                            visitor.AddError(visitor.get_location(lambdaDef), "ILLEGAL_LAMBDA_VARIABLE_TYPE");
                        }
                    }
                    lambdaDef.formal_parameters = lambdaDefParamsTypes;
                }
                if (lambdaDef.return_type != null && lambdaDef.return_type is lambda_inferred_type)
                {
                    if (dii_left.return_value_type != null)
                    {
                        (lambdaDef.return_type as lambda_inferred_type).real_type = dii_left.return_value_type;
                    }
                    else // SSM 23/07/16 - попытка бороться с var p: Shape->() := a->a.Print()
                    {
                        // lambdaDef.usedkeyword == 1 // function
                        var b = lambdaDef.usedkeyword == 0 && TryConvertFuncLambdaBodyWithMethodCallToProcLambdaBody(lambdaDef); // пытаться конвертировать только если мы явно не указали, что это функция
                        if (!b)
                        {
                            visitor.AddError(visitor.get_location(lambdaDef), "UNABLE_TO_CONVERT_FUNCTIONAL_TYPE_TO_PROCEDURAL_TYPE");
                        }
                    }
                }
            }
            else
            {
                if (lambdaDef.formal_parameters != null)
                {
                    for (int i = 0; i < lambdaDef.formal_parameters.params_list.Count; i++)
                    {
                        if (lambdaDef.formal_parameters.params_list[i].vars_type is lambda_inferred_type)
                        {
                            visitor.AddError(visitor.get_location(lambdaDef), "IMPOSSIBLE_TO_INFER_TYPES_IN_LAMBDA");
                        }
                    }
                }
            }
        }
Beispiel #6
0
        /// <summary>
        /// Вывод типа параметров лямбд и типа возвращаемого значения при присваивании лямбды переменной
        /// </summary>
        public static void InferTypesFromVarStmt(type_node leftType, function_lambda_definition lambdaDef, syntax_tree_visitor visitor)
        {
            if (lambdaDef == null)
            {
                return;
            }
            if (leftType != null)
            {
                delegate_internal_interface dii_left =
                    (delegate_internal_interface)leftType.get_internal_interface(internal_interface_kind.delegate_interface);
                if (dii_left == null)
                {
                    if (leftType != SystemLibrary.SystemLibrary.system_delegate_type)
                    {
                        visitor.AddError(visitor.get_location(lambdaDef), "ILLEGAL_LAMBDA_VARIABLE_TYPE");
                    }
                    else
                    {
                        return;
                    }
                }

                int leftTypeParamsNumber = dii_left.parameters.Count;
                int lambdaDefParamsCount = 0;
                if (lambdaDef.formal_parameters != null && lambdaDef.formal_parameters.params_list.Count != 0)
                {
                    for (int i = 0; i < lambdaDef.formal_parameters.params_list.Count; i++)
                    {
                        lambdaDefParamsCount += lambdaDef.formal_parameters.params_list[i].idents.idents.Count;
                    }
                    if (lambdaDefParamsCount != leftTypeParamsNumber)
                    {
                        visitor.AddError(visitor.get_location(lambdaDef), "ILLEGAL_LAMBDA_PARAMETERS_NUMBER");
                    }
                    bool flag = true;
                    SyntaxTree.formal_parameters lambdaDefParamsTypes = new formal_parameters();
                    for (int i = 0; i < lambdaDef.formal_parameters.params_list.Count; i++)
                    {
                        for (int j = 0; j < lambdaDef.formal_parameters.params_list[i].idents.idents.Count; j++)
                        {
                            var param = new SyntaxTree.typed_parameters();
                            param.idents = new ident_list();
                            param.idents.Add(lambdaDef.formal_parameters.params_list[i].idents.idents[j]);
                            param.vars_type      = lambdaDef.formal_parameters.params_list[i].vars_type;
                            param.source_context = lambdaDef.formal_parameters.source_context;
                            lambdaDefParamsTypes.Add(param);
                        }
                    }
                    for (int i = 0; i < leftTypeParamsNumber && flag; i++)
                    {
                        if (lambdaDefParamsTypes.params_list[i].vars_type is SyntaxTree.lambda_inferred_type)
                        {
                            if ((lambdaDefParamsTypes.params_list[i].vars_type as SyntaxTree.lambda_inferred_type).real_type is lambda_any_type_node)
                            {
                                var curLeftParType = dii_left.parameters[i].type;
                                lambdaDefParamsTypes.params_list[i].vars_type = new SyntaxTree.lambda_inferred_type();
                                (lambdaDefParamsTypes.params_list[i].vars_type as SyntaxTree.lambda_inferred_type).real_type = curLeftParType;
                                continue;
                            }
                        }
                        var lambdaPar = visitor.convert_strong(lambdaDefParamsTypes.params_list[i].vars_type);
                        if (!convertion_data_and_alghoritms.eq_type_nodes(dii_left.parameters[i].type, lambdaPar))
                        {
                            visitor.AddError(visitor.get_location(lambdaDef), "ILLEGAL_LAMBDA_VARIABLE_TYPE");
                        }
                    }
                    lambdaDef.formal_parameters = lambdaDefParamsTypes;
                }
                if (lambdaDef.return_type != null && lambdaDef.return_type is lambda_inferred_type)
                {
                    if (dii_left.return_value_type != null)
                    {
                        (lambdaDef.return_type as lambda_inferred_type).real_type = dii_left.return_value_type;
                    }
                    else // SSM 23/07/16 - попытка бороться с var p: Shape->() := a->a.Print()
                    {
                        var b = TryConvertFuncLambdaBodyWithMethodCallToProcLambdaBody(lambdaDef);
                        if (!b)
                        {
                            throw new SimpleSemanticError(visitor.get_location(lambdaDef), "UNABLE_TO_CONVERT_FUNCTIONAL_TYPE_TO_PROCEDURAL_TYPE");
                        }
                    }
                }
            }
            else
            {
                if (lambdaDef.formal_parameters != null)
                {
                    for (int i = 0; i < lambdaDef.formal_parameters.params_list.Count; i++)
                    {
                        if (lambdaDef.formal_parameters.params_list[i].vars_type is lambda_inferred_type)
                        {
                            visitor.AddError(visitor.get_location(lambdaDef), "IMPOSSIBLE_TO_INFER_TYPES_IN_LAMBDA");
                        }
                    }
                }
            }
        }
Beispiel #7
0
 /// <summary>
 /// Вывод типа параметров лямбд и типа возвращаемого значения при присваивании лямбды переменной 
 /// </summary>
 public static void InferTypesFromVarStmt(type_node leftType, function_lambda_definition lambdaDef, syntax_tree_visitor visitor)
 {
     if (lambdaDef == null)
         return;
     if (leftType != null)
     {
         delegate_internal_interface dii_left =
             (delegate_internal_interface)leftType.get_internal_interface(internal_interface_kind.delegate_interface);
         if (dii_left == null)
             visitor.AddError(visitor.get_location(lambdaDef), "ILLEGAL_LAMBDA_VARIABLE_TYPE");
         int leftTypeParamsNumber = dii_left.parameters.Count;
         int lambdaDefParamsCount = 0;
         if (lambdaDef.formal_parameters != null && lambdaDef.formal_parameters.params_list.Count != 0)
         {
             for (int i = 0; i < lambdaDef.formal_parameters.params_list.Count; i++)
                 lambdaDefParamsCount += lambdaDef.formal_parameters.params_list[i].idents.idents.Count;
             if (lambdaDefParamsCount != leftTypeParamsNumber)
                 visitor.AddError(visitor.get_location(lambdaDef), "ILLEGAL_LAMBDA_PARAMETERS_NUMBER");
             bool flag = true;
             SyntaxTree.formal_parameters lambdaDefParamsTypes = new formal_parameters();
             for (int i = 0; i < lambdaDef.formal_parameters.params_list.Count; i++)
                 for (int j = 0; j < lambdaDef.formal_parameters.params_list[i].idents.idents.Count; j++)
                 {
                     var param = new SyntaxTree.typed_parameters();
                     param.idents = new ident_list();
                     param.idents.Add(lambdaDef.formal_parameters.params_list[i].idents.idents[j]);
                     param.vars_type = lambdaDef.formal_parameters.params_list[i].vars_type;
                     lambdaDefParamsTypes.Add(param);
                 }
             for (int i = 0; i < leftTypeParamsNumber && flag; i++)
             {
                 if (lambdaDefParamsTypes.params_list[i].vars_type is SyntaxTree.lambda_inferred_type)
                 {
                     if ((lambdaDefParamsTypes.params_list[i].vars_type as SyntaxTree.lambda_inferred_type).real_type is lambda_any_type_node)
                     {
                         var curLeftParType = dii_left.parameters[i].type;
                         lambdaDefParamsTypes.params_list[i].vars_type = new SyntaxTree.lambda_inferred_type();
                         (lambdaDefParamsTypes.params_list[i].vars_type as SyntaxTree.lambda_inferred_type).real_type = curLeftParType;
                         continue;
                     }
                 }
                 var lambdaPar = visitor.convert_strong(lambdaDefParamsTypes.params_list[i].vars_type);
                 if (!convertion_data_and_alghoritms.eq_type_nodes(dii_left.parameters[i].type, lambdaPar))
                 {
                     visitor.AddError(visitor.get_location(lambdaDef), "ILLEGAL_LAMBDA_VARIABLE_TYPE");
                 }
             }
             lambdaDef.formal_parameters = lambdaDefParamsTypes;
         }
         if (lambdaDef.return_type != null && lambdaDef.return_type is lambda_inferred_type)
         {
             if (dii_left.return_value_type != null)
                 (lambdaDef.return_type as lambda_inferred_type).real_type = dii_left.return_value_type;
             else // SSM 23/07/16 - попытка бороться с var p: Shape->() := a->a.Print()
             {
                 var b = TryConvertFuncLambdaBodyWithMethodCallToProcLambdaBody(lambdaDef);
                 if (!b)
                     throw new SimpleSemanticError(visitor.get_location(lambdaDef), "UNABLE_TO_CONVERT_FUNCTIONAL_TYPE_TO_PROCEDURAL_TYPE");
             }
         }
     }
     else
     {
         if (lambdaDef.formal_parameters != null)
             for (int i = 0; i < lambdaDef.formal_parameters.params_list.Count; i++)
                 if (lambdaDef.formal_parameters.params_list[i].vars_type is lambda_inferred_type)
                     visitor.AddError(visitor.get_location(lambdaDef), "IMPOSSIBLE_TO_INFER_TYPES_IN_LAMBDA");
     }
 }
 public CapturedVariablesTreeBuilder(syntax_tree_visitor visitor)
 {
     _visitor = visitor;
     _scopesCapturedVarsNodesDictionary = new Dictionary<int, CapturedVariablesTreeNode>();
     _identsReferences = new Dictionary<SubstitutionKey, List<ident>>();
 }
Beispiel #9
0
        private static void CreateInParallelVariable(syntax_tree_visitor syntax_tree_visitor, out string VarName)
        {
            //сохраняем контекст
            ContextInfo contextInfo = new ContextInfo(syntax_tree_visitor);

            VarName = "$InParallelSection";

            try
            {
                //создание и конвертирование переменной                
                SyntaxTree.var_def_statement vds = new PascalABCCompiler.SyntaxTree.var_def_statement();
                SyntaxTree.variable_definitions var_def = new PascalABCCompiler.SyntaxTree.variable_definitions(vds, null);
                SyntaxTree.ident_list idl = new PascalABCCompiler.SyntaxTree.ident_list();
                vds.vars = idl;
                idl.Add(new SyntaxTree.ident(VarName));
                SyntaxTree.named_type_reference ntr = new PascalABCCompiler.SyntaxTree.named_type_reference();
                vds.vars_type = ntr;
                ntr.names.Add(new PascalABCCompiler.SyntaxTree.ident("boolean"));
                vds.inital_value = new PascalABCCompiler.SyntaxTree.ident("false");
                syntax_tree_visitor.visit(var_def);
            }
            finally
            {
                //восстанавливаем контекст
                contextInfo.RestoreContext(syntax_tree_visitor);
            }
            InParallelSectionCreated = true;
        }
Beispiel #10
0
 private static if_node CreateIfCondition(syntax_tree_visitor syntax_tree_visitor, statements_list ifthen, statements_list ifelse, location loc)
 {
     //сохраняем контекст
     ContextInfo contextInfo = new ContextInfo(syntax_tree_visitor);
     
     if_node res = null;
     try
     {
         SyntaxTree.if_node if_node = new PascalABCCompiler.SyntaxTree.if_node();
         SyntaxTree.un_expr une = new PascalABCCompiler.SyntaxTree.un_expr();
         une.operation_type = SyntaxTree.Operators.LogicalNOT;
         une.subnode = new SyntaxTree.ident(InParallelSection);
         if_node.condition = une;
         if_node.then_body = new SyntaxTree.empty_statement();
         if_node.then_body = new SyntaxTree.empty_statement();
         res = syntax_tree_visitor.convert_strong(if_node) as if_node;
         res.then_body = ifthen;
         res.else_body = ifelse;
         res.location = loc;
     }
     finally
     {
         //восстанавливаем контекст
         contextInfo.RestoreContext(syntax_tree_visitor);
     }
     return res;
 }
Beispiel #11
0
 public void RestoreContext(syntax_tree_visitor syntax_tree_visitor)
 {
     SemanticRules.ThrowErrorWithoutSave = SemanticRulesThrowErrorWithoutSave;
     syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack = statement_list_stack;
     syntax_tree_visitor.context.converted_type = converted_type;
     syntax_tree_visitor.context.var_defs = current_var_defs;
     syntax_tree_visitor.context.set_field_access_level(curr_fal);
     syntax_tree_visitor.context.block_stack = block_stack;
     syntax_tree_visitor.context.CyclesStack = cycle_stack;
     syntax_tree_visitor.context.member_decls = current_member_decls;
     syntax_tree_visitor.context.func_stack = function_node_stack;
     syntax_tree_visitor.context.last_created_function = current_last_created_function;
 }
Beispiel #12
0
 public void SaveContext(syntax_tree_visitor syntax_tree_visitor)
 {
     converted_type = syntax_tree_visitor.context.converted_type;
     syntax_tree_visitor.context.converted_type = null;
     statement_list_stack = syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack;
     syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack = new statement_list_stack();
     curr_fal = syntax_tree_visitor.context.get_field_access_level();
     current_var_defs = syntax_tree_visitor.context.var_defs;
     syntax_tree_visitor.context.var_defs = new List<var_definition_node>();
     block_stack = syntax_tree_visitor.context.block_stack;
     syntax_tree_visitor.context.block_stack = new Stack<code_block>();
     cycle_stack = syntax_tree_visitor.context.CyclesStack;
     syntax_tree_visitor.context.CyclesStack = new statement_node_stack();
     current_member_decls = syntax_tree_visitor.context.member_decls;
     syntax_tree_visitor.context.member_decls = new Hashtable();
     function_node_stack = syntax_tree_visitor.context.func_stack;
     syntax_tree_visitor.context.func_stack = new common_function_node_stack();
     current_last_created_function = syntax_tree_visitor.context.last_created_function;
     SemanticRulesThrowErrorWithoutSave = SemanticRules.ThrowErrorWithoutSave;
     SemanticRules.ThrowErrorWithoutSave = true;
 }
Beispiel #13
0
        private static bool GenerateOMPParallelSectionsCall(statements_list stmts, SyntaxTree.statement_list syntax_stmts, statements_list omp_stmts, syntax_tree_visitor syntax_tree_visitor)
        {

            SyntaxTree.expression_list delegates = new PascalABCCompiler.SyntaxTree.expression_list();
            SyntaxTree.statement_list stlInit = new PascalABCCompiler.SyntaxTree.statement_list();
            SyntaxTree.statement_list stlFinal = new PascalABCCompiler.SyntaxTree.statement_list();
            VarInfoContainer Vars = new VarInfoContainer();
            string ClassName = syntax_tree_visitor.context.get_free_name("$section_class{0}");
            List<SyntaxTree.statement> Sections = new List<PascalABCCompiler.SyntaxTree.statement>();
            foreach (SyntaxTree.statement syntax_statement in syntax_stmts.subnodes)
            {
                if (syntax_statement is SyntaxTree.empty_statement)
                    continue;       //А зачем? ;-)
                if (syntax_statement is SyntaxTree.var_statement)
                {
                    //выдать предупреждение. Это не нормально для параллельных секций
                    syntax_tree_visitor.visit(syntax_statement as SyntaxTree.var_statement);
                }
                else
                {
                    //ищем используемые переменные
                    VarFinderSyntaxVisitor VFvis = new VarFinderSyntaxVisitor(syntax_statement, syntax_tree_visitor.context, false);
                    SyntaxTree.compiler_directive dir = syntax_tree_visitor.DirectivesToNodesLinks[syntax_stmts];
                    
                    //if (DirInfosTable[dir].ErrorName == "WARNING_IN_CLAUSE_PARAMETERS_REPEATED_VARS")
                    //    syntax_tree_visitor.AddWarning(new Errors.CommonWarning(StringResources.Get(DirInfosTable[dir].ErrorName), syntax_stmts.source_context.FileName, DirInfosTable[dir].SC.begin_position.line_num, DirInfosTable[dir].SC.begin_position.column_num));
                    //else if (DirInfosTable[dir].ErrorName == "ERROR_IN_CLAUSE_PARAMETERS")
                    //{
                    //    syntax_tree_visitor.AddWarning(new Errors.CommonWarning(StringResources.Get(DirInfosTable[dir].ErrorName), syntax_stmts.source_context.FileName, DirInfosTable[dir].SC.begin_position.line_num, DirInfosTable[dir].SC.begin_position.column_num));
                    //}
                    //else
                    if (DirInfosTable[dir].ErrorName != null)
                    {
                        syntax_tree_visitor.AddWarning(new Errors.CommonWarning(PascalABCCompiler.StringResources.Get(DirInfosTable[dir].ErrorName), syntax_stmts.source_context.FileName, DirInfosTable[dir].SC.begin_position.line_num, DirInfosTable[dir].SC.begin_position.column_num));
                    }
                    Vars.UnionWith(GetVarInfoContainer(VFvis, null, DirInfosTable[dir].Privates, syntax_tree_visitor, dir));
                    Sections.Add(syntax_statement);
                }
            }
            //сохраняем контекст
            ContextInfo contextInfo = new ContextInfo(syntax_tree_visitor);

            try
            {
                //создание и конвертирование класса
                SyntaxTree.class_members member;
                SyntaxTree.type_declarations Decls = CreateClass(ClassName, out member, Vars);
                for (int i = 0; i < Sections.Count; ++i)
                    member.members.Add(CreateMethod("method" + i.ToString(), Sections[i], "", member, Vars));
                syntax_tree_visitor.visit(Decls);
            }
            finally
            {
                //восстанавливаем контекст
                contextInfo.RestoreContext(syntax_tree_visitor);
            }
            //создаем инициализацию и финализацию
            int NameNum = 0;
            string ObjName = GetFreeName("$section_obj", ref NameNum, syntax_tree_visitor.context);

            stlInit.subnodes.AddRange(CreateInitPart(ClassName, ObjName, Vars).subnodes);
            stlFinal.subnodes.AddRange(CreateFinalPart(ObjName, Vars).subnodes);

            SyntaxTree.procedure_call pc = new PascalABCCompiler.SyntaxTree.procedure_call();
            SyntaxTree.method_call mc = new PascalABCCompiler.SyntaxTree.method_call();
            mc.dereferencing_value = CreateTPLFunctionReference("Invoke");
            pc.func_name = mc;
            SyntaxTree.expression_list exl = new PascalABCCompiler.SyntaxTree.expression_list();
            //foreach (string str in ObjNames)
            for (int i=0; i<Sections.Count; ++i)
                exl.Add(new SyntaxTree.dot_node(new SyntaxTree.ident(ObjName), new SyntaxTree.ident("Method"+i.ToString())));
            mc.parameters = exl;

            stlInit.subnodes.Add(CreateNestedRegionBorder(true));
            stlInit.subnodes.Add(pc);
            stlInit.subnodes.AddRange(stlFinal.subnodes);
            stlInit.subnodes.Add(CreateNestedRegionBorder(false));

            statement_node st = syntax_tree_visitor.ret.visit(stlInit);
            omp_stmts.statements.AddElement(st);
            return true;
        }
 public compilation_context(convertion_data_and_alghoritms convertion_data_and_alghoritms, syntax_tree_visitor syntax_tree_visitor)
 {
     this.convertion_data_and_alghoritms = convertion_data_and_alghoritms;
     this.syntax_tree_visitor = syntax_tree_visitor;
     _instance = this;
 }
Beispiel #15
0
        internal static statements_list TryConvertSections(statements_list semantic_stmts, SyntaxTree.statement_list syntax_stmts, syntax_tree_visitor syntax_tree_visitor)
        {
            try
            {
                location loc = semantic_stmts.location;
                statements_list omp_stmts = new statements_list(loc);
                statements_list head_stmts = new statements_list(loc);
                syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_push(head_stmts);

                if (!InParallelSectionCreated)
                    CreateInParallelVariable(syntax_tree_visitor, out InParallelSection);
                //если omp доступен то (выполнять паралельно) иначе (выполнять последовательно операторы)
                if_node ifnode = CreateIfCondition(syntax_tree_visitor, omp_stmts, semantic_stmts, loc);
                head_stmts.statements.AddElement(ifnode);
                
                //генерим ветку в случае когда доступен omp
                if (!GenerateOMPParallelSectionsCall(semantic_stmts, syntax_stmts, omp_stmts, syntax_tree_visitor))
                {
                    syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_pop();
                    return null;
                }

                syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_pop();

                return head_stmts;
            }
            catch (OpenMPException e)
            {
                Exception ex = new Exception(e.ToString());
                syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_pop();
                syntax_tree_visitor.WarningsList.Add(new OMP_BuildigError(ex, syntax_tree_visitor.get_location(new SyntaxTree.syntax_tree_node(e.SC))));
            }
            catch (Exception e)
            {
                syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_pop();
                syntax_tree_visitor.WarningsList.Add(new OMP_BuildigError(e, semantic_stmts.location));
            }
            return null;
        }
Beispiel #16
0
 public SubtreeCreator(syntax_tree_visitor visitor)
 {
     _syntaxTreeVisitor = visitor;
 }
Beispiel #17
0
        private static VarInfoContainer GetVarInfoContainer(VarFinderSyntaxVisitor VFVis, List<ReductionDirective> Reductions, List<string> PrivateVars, syntax_tree_visitor visitor, SyntaxTree.compiler_directive dir)
        {
            if (Reductions == null)
                Reductions = new List<ReductionDirective>();
            if (PrivateVars == null)
                PrivateVars = new List<string>();
            VarInfoContainer Result = new VarInfoContainer();

            //константы копируются сразу
            Result.Constants = VFVis.Constants;

            //список переменных для редукции
            //ищем переменные с такими именами, проверяем их наличие, тип и если все хорошо - добавляем в список
            foreach (ReductionDirective rd in Reductions)
                foreach (string rdVarName in rd.variables)
                {
                    if (LoopVariables.Contains(rdVarName))
                    {
                        visitor.AddWarning(new PascalABCCompiler.Errors.CommonWarning(String.Format(PascalABCCompiler.StringResources.Get("OMPERROR_REDUCTION_WITH_LOOPVAR_{0}"), rdVarName), visitor.CurrentDocument.file_name, dir.source_context.begin_position.line_num, dir.source_context.begin_position.column_num));
                        continue;
                    }
                    SymbolInfo si = visitor.context.find(rdVarName);
                    if (si == null)
                    {
                        visitor.AddWarning(new PascalABCCompiler.Errors.CommonWarning(String.Format(PascalABCCompiler.StringResources.Get("OMPERROR_UNKNOWN_VARNAME_{0}"), rdVarName), visitor.CurrentDocument.file_name, dir.source_context.begin_position.line_num, dir.source_context.begin_position.column_num));
                        continue;
                    }
                    if (!(si.sym_info is SemanticTree.IVAriableDefinitionNode))
                    {
                        visitor.AddWarning(new PascalABCCompiler.Errors.CommonWarning(String.Format(PascalABCCompiler.StringResources.Get("OMPERROR_NAME_IS_NOT_VAR_{0}"), rdVarName), visitor.CurrentDocument.file_name, dir.source_context.begin_position.line_num, dir.source_context.begin_position.column_num));
                        continue;
                    }
                    if (!IsValidVarForReduction(si.sym_info as SemanticTree.IVAriableDefinitionNode))
                    {
                        visitor.AddWarning(new PascalABCCompiler.Errors.CommonWarning(String.Format(PascalABCCompiler.StringResources.Get("OMPERROR_IS_NOT_POSSIBLE_REDUCTION_WITH_THIS_VAR_{0}"), rdVarName), visitor.CurrentDocument.file_name, dir.source_context.begin_position.line_num, dir.source_context.begin_position.column_num));
                        continue;
                    }
                    Result.ReductionVariables.Add(si.sym_info as SemanticTree.IVAriableDefinitionNode);
                    Result.ReductionActions.Add(rd.Oper);
                    //for (int i = 0; i < VFVis.Variables.Count; ++i)
                    //    if (VFVis.Variables[i].name.ToLower() == rdVarName.ToLower())
                    //    {
                    //        Result.ReductionVariables.Add(VFVis.Variables[i]);
                    //        Result.ReductionActions.Add(rd.Oper);
                    //        break;
                    //    }
                }

            //приватные переменные - аналогично, но без проверки на тип
            foreach (string privateVar in PrivateVars)
            {
                SymbolInfo si = visitor.context.find(privateVar);
                if (si == null)
                {
                    visitor.AddWarning(new PascalABCCompiler.Errors.CommonWarning(String.Format(PascalABCCompiler.StringResources.Get("OMPERROR_UNKNOWN_VARNAME_{0}"), privateVar), visitor.CurrentDocument.file_name, dir.source_context.begin_position.line_num, dir.source_context.begin_position.column_num));
                    continue;
                }
                if (!(si.sym_info is SemanticTree.IVAriableDefinitionNode))
                {
                    visitor.AddWarning(new PascalABCCompiler.Errors.CommonWarning(String.Format(PascalABCCompiler.StringResources.Get("OMPERROR_NAME_IS_NOT_VAR_{0}"), privateVar), visitor.CurrentDocument.file_name, dir.source_context.begin_position.line_num, dir.source_context.begin_position.column_num));
                    continue;
                }
                Result.PrivateVariables.Add(si.sym_info as SemanticTree.IVAriableDefinitionNode);
            }

            //по всем переменным:
            //если она не приватная и по ней нет редукции - переписываем ее в список разделяемых
            foreach (SemanticTree.IVAriableDefinitionNode var in VFVis.Variables)
            {
                bool NotShared = false;
                foreach (SemanticTree.IVAriableDefinitionNode rdn in Result.ReductionVariables)
                    if (rdn.name.ToLower() == var.name.ToLower())
                    {
                        NotShared = true;
                        break;
                    }
                if (!NotShared)
                    foreach (SemanticTree.IVAriableDefinitionNode prVar in Result.PrivateVariables)
                        if (prVar.name.ToLower() == var.name.ToLower())
                        {
                            NotShared = true;
                            break;
                        }
                if (!NotShared)
                    Result.SharedVariables.Add(var);
            }

            return Result;
        }
Beispiel #18
0
 public returner(syntax_tree_visitor stv)
 {
     syntax_tree_visitor = stv;
 }
Beispiel #19
0
        //инициализация OpenMP
        public static void InitOpenMP(List<SyntaxTree.compiler_directive> directives, syntax_tree_visitor visitor, SyntaxTree.compilation_unit cu)
        {
            //Из-за переноса этой проверки в секцию инициализации - оно не всегда успевает инициализироваться до выполнения этого кода.
            //Будем надеяться, что условие никогда не выполнится. Без постороннего вмешательства (замена файлов старыми версиями) - не должно.
            //if (SystemLibrary.SystemLibInitializer.OMP_Available == null || SystemLibrary.SystemLibInitializer.OMP_Available.NotFound)
            //{
            //    visitor.AddWarning(new Errors.CommonWarning(PascalABCCompiler.StringResources.Get("OMPERROR_OMP_NOT_AVAILABLE"), cu.file_name, cu.source_context.begin_position.line_num, cu.source_context.begin_position.column_num));
            //    return;
            //}
            foreach (SyntaxTree.compiler_directive dir in directives)
            {
                if (dir.Name.text.ToLower() == "omp")
                {
                    string DirText = dir.Directive.text.ToLower();
                    DirectiveInfo dirInf = new DirectiveInfo(dir);
                    
                    DirInfosTable.Add(dir, dirInf);
                    if (dirInf.Kind == DirectiveKind.ParallelFor)
                        ForsFound = true;
                    else if (dirInf.Kind == DirectiveKind.ParallelSections)
                        SectionsFound = true;
                    else if (dirInf.Kind == DirectiveKind.Critical)
                        LocksFound = true;
                    else 
                    {
                        visitor.AddWarning(new Errors.CommonWarning(PascalABCCompiler.StringResources.Get(dirInf.ErrorName), dir.Directive.source_context.FileName, dirInf.SC.begin_position.line_num, dirInf.SC.begin_position.column_num));
                    }
                }
            }
            //уже не нужно
            //if (ForsFound && SystemLibrary.SystemLibInitializer.OMP_ParallelFor.NotFound)
            //{
            //    visitor.AddWarning(new Errors.CommonWarning(PascalABCCompiler.StringResources.Get("OMPERROR_PARALLELIZATION_FOR_NOT_AVAILABLE"), cu.file_name, cu.source_context.begin_position.line_num, cu.source_context.begin_position.column_num));
            //    ForsFound = false;
            //}
            //if (SectionsFound && SystemLibrary.SystemLibInitializer.OMP_ParallelSections.NotFound)
            //{
            //    visitor.AddWarning(new Errors.CommonWarning(PascalABCCompiler.StringResources.Get("OMPERROR_PARALLELIZATION_SECTIONS_NOT_AVAILABLE"), cu.file_name, cu.source_context.begin_position.line_num, cu.source_context.begin_position.column_num));
            //    SectionsFound = false;
            //}

            //"оторванные" директивы:
            //можно использовать директивы синхронизации и вне параллельных областей.
            //if (!SectionsFound && !ForsFound && LocksFound)
            //{
            //    visitor.AddWarning(new Errors.CommonWarning(PascalABCCompiler.StringResources.Get("OMPERROR_USING_CRITICAL_SECTIONS_OUTSIDE_PARALLEL_STRUCTURES"), cu.file_name, cu.source_context.begin_position.line_num, cu.source_context.begin_position.column_num));
            //    LocksFound = false;
            //}

        }
Beispiel #20
0
 /// <summary>
 /// Вывод типа возвращаемого значения лямбды
 /// </summary>
 public static void InferResultType(function_header funcHeader, proc_block procBody, syntax_tree_visitor visitor)
 {
     var retType = funcHeader.return_type as lambda_inferred_type;
     if (retType != null && retType.real_type is lambda_any_type_node)
         retType.real_type = new LambdaResultTypeInferrer(funcHeader, procBody, visitor).InferResultType();
 }
Beispiel #21
0
        //инициализация критических секций с созданием класса
        private static void InitCriticals(syntax_tree_visitor visitor)
        {
            //генерируем класс
            SyntaxTree.type_declarations TypeDecls = new PascalABCCompiler.SyntaxTree.type_declarations();
            SyntaxTree.type_declaration TypeDecl = new PascalABCCompiler.SyntaxTree.type_declaration();
            TypeDecls.types_decl.Add(TypeDecl);
            LocksName = visitor.context.get_free_name("$locks_container{0}");
            TypeDecl.type_name = new PascalABCCompiler.SyntaxTree.ident(LocksName);
            SyntaxTree.class_definition ClassDef = new PascalABCCompiler.SyntaxTree.class_definition();
            TypeDecl.type_def = ClassDef;
            SyntaxTree.class_body ClassBody = new PascalABCCompiler.SyntaxTree.class_body();
            ClassDef.body = ClassBody;
            SyntaxTree.class_members ClassMember = new PascalABCCompiler.SyntaxTree.class_members();
            ClassBody.class_def_blocks.Add(ClassMember);
            ClassMember.access_mod = new PascalABCCompiler.SyntaxTree.access_modifer_node(PascalABCCompiler.SyntaxTree.access_modifer.public_modifer);

            List<string> ProcessedNames = new List<string>();

            foreach (KeyValuePair<SyntaxTree.compiler_directive, DirectiveInfo> pair in DirInfosTable)
            {

                if (pair.Value.Kind == DirectiveKind.Critical)
                {
                    string LockName = "$default";
                    if (pair.Value.Name.Length != 0)
                        LockName = pair.Value.Name;

                    if (ProcessedNames.Contains(LockName))
                        continue;
                    ProcessedNames.Add(LockName);

                    SyntaxTree.var_def_statement vds = new PascalABCCompiler.SyntaxTree.var_def_statement();
                    SyntaxTree.ident_list idl = new PascalABCCompiler.SyntaxTree.ident_list();
                    vds.vars = idl;
                    idl.Add(new SyntaxTree.ident(LockName));
                    SyntaxTree.named_type_reference ntr = new PascalABCCompiler.SyntaxTree.named_type_reference();
                    vds.vars_type = ntr;
                    ntr.Add(new SyntaxTree.ident("object"));
                    SyntaxTree.new_expr ne = new PascalABCCompiler.SyntaxTree.new_expr();
                    vds.inital_value = ne;
                    ne.type = ntr;
                    vds.var_attr = PascalABCCompiler.SyntaxTree.definition_attribute.Static;
                    ClassMember.members.Add(vds);
                }

            }
            //сохраняем контекст
            ContextInfo contextInfo = new ContextInfo(visitor);

            try
            {
                visitor.visit(TypeDecls);
                LocksInitialized = true;
            }
            finally
            {
                //восстанавливаем контекст
                contextInfo.RestoreContext(visitor);
            }
        }
Beispiel #22
0
 /// <summary>
 /// Временный узел, который используется при выведении типов параметров
 /// </summary>
 /// <param name="def"></param>
 /// <param name="visitor"></param>
 /// <returns></returns>
 public static typed_expression GetTempFunctionNodeForTypeInference(SyntaxTree.function_lambda_definition def, syntax_tree_visitor visitor)
 {
     var res = new common_namespace_function_node(def.lambda_name, null, null, null);
     if (def.return_type != null)
         res.return_value_type = visitor.convert_strong(def.return_type);
     else
         res.return_value_type = null;
     res.parameters.clear();
     if (def.formal_parameters != null && def.formal_parameters.params_list.Count != 0)
     {
         for (int i = 0; i < def.formal_parameters.params_list.Count; i++)
             for (int j = 0; j < def.formal_parameters.params_list[i].idents.idents.Count; j++)
             {
                 var new_param = new common_parameter(null, SemanticTree.parameter_type.value, res, concrete_parameter_type.cpt_none, null);
                 new_param.type = visitor.convert_strong(def.formal_parameters.params_list[i].vars_type);
                 res.parameters.AddElement(new_param);
             }
     }
     var hhh = new delegated_methods();
     hhh.proper_methods.AddElement(new common_namespace_function_call(res, null));
     return new typed_expression(hhh, null);
 }
Beispiel #23
0
        public static void TryConvertCritical(ref SyntaxTree.statement st, syntax_tree_visitor visitor, SyntaxTree.compiler_directive directive)
        {
            if (!LocksInitialized)
                InitCriticals(visitor);

            string LockName = "$default";
            if (DirInfosTable[directive].Name.Length != 0)
                LockName = DirInfosTable[directive].Name;
            SyntaxTree.lock_stmt LockStmt = new PascalABCCompiler.SyntaxTree.lock_stmt();
            LockStmt.lock_object = new SyntaxTree.dot_node(new SyntaxTree.ident(LocksName), new SyntaxTree.ident(LockName));
            LockStmt.stmt = st;
            st = LockStmt;
        }
Beispiel #24
0
        //Проверки на доступность OMP и директиву проводятся перед вызовом.
        internal static statements_list TryConvertFor(statements_list for_head_stmts, SyntaxTree.for_node for_node, for_node fn, var_definition_node loop_variable, expression_node fromInclusive, expression_node toInclusive, syntax_tree_visitor syntax_tree_visitor)
        {
            try
            {
                location loc = fn.location;
                statements_list omp_stmts = new statements_list(loc);
                statements_list head_stmts = new statements_list(loc);

                syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_push(head_stmts);

                if (!InParallelSectionCreated)
                    CreateInParallelVariable(syntax_tree_visitor, out InParallelSection);
                //если omp доступен то (выполнять паралельно) иначе (выполнять for)
                if_node ifnode = CreateIfCondition(syntax_tree_visitor, omp_stmts, for_head_stmts, loc);
                head_stmts.statements.AddElement(ifnode);

                //генерим ветку в случае когда доступен omp
                if (!GenerateOMPParallelForCall(fn.body, for_node, loop_variable, omp_stmts, syntax_tree_visitor, fromInclusive, toInclusive))
                {
                    syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_pop();
                    return null;
                }

                syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_pop();

                return head_stmts;
            }
            catch (OpenMPException e)
            {
                Exception ex = new Exception(e.ToString());
                syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_pop();
                syntax_tree_visitor.WarningsList.Add(new OMP_BuildigError(ex, syntax_tree_visitor.get_location(new SyntaxTree.syntax_tree_node(e.SC))));
            }
            catch (Exception e)
            {
                syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_pop();
                syntax_tree_visitor.WarningsList.Add(new OMP_BuildigError(e, fn.location));
            }
            return null;
        }
Beispiel #25
0
        private static bool GenerateOMPParallelForCall(statement_node body, SyntaxTree.for_node for_node, var_definition_node loop_variable, statements_list omp_stmts, syntax_tree_visitor syntax_tree_visitor, expression_node fromInclusive, expression_node toInclusive)
        {
            SyntaxTree.statement syntax_body = for_node.statements;

            expression_node omp_call = null;
            base_function_call bfc = body as base_function_call;
            if (bfc != null && bfc.parameters.Count == 1 && bfc.parameters[0] is variable_reference &&
                ((variable_reference)bfc.parameters[0]).VariableDefinition == loop_variable && ((bfc.function.parameters[0].type as type_node).PrintableName.ToLower() == "integer"))
            {
                //если тело цикла - вызов функции с одни параметром - переменной цикла,
                //если при этом у вызываемой функции тип параметра - integer, а не какой-нибудь object, как это бывает с write и вообще может быть с перегрузкой
                //то генерировать класс не надо.
                //генерируем вызов и все
                omp_call = syntax_tree_visitor.CreateDelegateCall(bfc);
                if (omp_call == null)
                {
                    syntax_tree_visitor.AddWarning(new OMP_ConstructionNotSupportedNow(body.location));
                    syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_pop();
                    return false;
                }
                base_function_call omp_parallel_for_call = null;
                if (SystemLibrary.SystemLibInitializer.OMP_ParallelFor.sym_info is common_namespace_function_node)
                    omp_parallel_for_call = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.OMP_ParallelFor.sym_info as common_namespace_function_node, body.location);
                else
                    omp_parallel_for_call = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.OMP_ParallelFor.sym_info as compiled_function_node, body.location);
                omp_parallel_for_call.parameters.AddElement(fromInclusive);
                omp_parallel_for_call.parameters.AddElement(toInclusive);
                omp_parallel_for_call.parameters.AddElement(omp_call);
                omp_stmts.statements.AddElement(omp_parallel_for_call);
            }
            else
            {
                //ищем используемые переменные, получаем редукцию из директивы и составляем список переменных по типам
                VarFinderSyntaxVisitor VFvis = new VarFinderSyntaxVisitor(syntax_body, syntax_tree_visitor.context, true);
                SyntaxTree.compiler_directive dir = syntax_tree_visitor.DirectivesToNodesLinks[for_node];
                //if (DirInfosTable[dir].ErrorName == "WARNING_IN_CLAUSE_PARAMETERS_REPEATED_VARS")
                //    syntax_tree_visitor.AddWarning(new Errors.CommonWarning(StringResources.Get(DirInfosTable[dir].ErrorName), for_node.source_context.FileName, DirInfosTable[dir].SC.begin_position.line_num, DirInfosTable[dir].SC.begin_position.column_num));
                //else if (DirInfosTable[dir].ErrorName == "ERROR_IN_CLAUSE_PARAMETERS")
                //{
                //    syntax_tree_visitor.AddWarning(new Errors.CommonWarning(StringResources.Get(DirInfosTable[dir].ErrorName), for_node.source_context.FileName, DirInfosTable[dir].SC.begin_position.line_num, DirInfosTable[dir].SC.begin_position.column_num));
                //}
                //else
               
                if (DirInfosTable[dir].ErrorName !=null)//== "ERROR_IN_CLAUSE")
                {
                    syntax_tree_visitor.AddWarning(new Errors.CommonWarning(PascalABCCompiler.StringResources.Get(DirInfosTable[dir].ErrorName), for_node.source_context.FileName, DirInfosTable[dir].SC.begin_position.line_num, DirInfosTable[dir].SC.begin_position.column_num));
                }

                VarInfoContainer Vars = GetVarInfoContainer(VFvis, DirInfosTable[dir].Reductions, DirInfosTable[dir].Privates, syntax_tree_visitor, dir);

                //сохраняем контекст
                ContextInfo contextInfo = new ContextInfo(syntax_tree_visitor);

                string ClassName = syntax_tree_visitor.context.get_free_name("$for_class{0}");

                try
                {
                    //создаем и конвертируем класс
                    SyntaxTree.class_members member;
                    SyntaxTree.type_declarations Decls = CreateClass(ClassName, out member, Vars);
                    member.members.Add(CreateMethod("Method", syntax_body, for_node.loop_variable.name, member, Vars));
                    syntax_tree_visitor.visit(Decls);
                }
                finally
                {
                    //восстанавливаем контекст
                    contextInfo.RestoreContext(syntax_tree_visitor);
                }

                //создаем инициализацию, вызов и финализацию
                string ObjName = syntax_tree_visitor.context.get_free_name("$for_obj{0}");

                SyntaxTree.dot_node dn = new SyntaxTree.dot_node(new SyntaxTree.ident(ObjName), new SyntaxTree.ident("Method"));

                SyntaxTree.statement_list stl = CreateInitPart(ClassName, ObjName, Vars);
                stl.subnodes.Add(CreateNestedRegionBorder(true));
                stl.subnodes.Add(CreateOMPParallelForCall(dn, for_node.initial_value, for_node.finish_value));
                stl.subnodes.Add(CreateNestedRegionBorder(false));
                stl.subnodes.AddRange(CreateFinalPart(ObjName, Vars).subnodes);
                omp_stmts.statements.AddElement(syntax_tree_visitor.ret.visit(stl));
            }
            return true;
        }
        /// <summary>
        /// Вывод типа возвращаемого значения лямбды
        /// </summary>
        public static void InferResultType(function_header funcHeader, proc_block procBody, syntax_tree_visitor visitor)
        {
            var retType = funcHeader.return_type as lambda_inferred_type;

            if (retType != null && retType.real_type is lambda_any_type_node)
            {
                retType.real_type = new LambdaResultTypeInferrer(funcHeader, procBody, visitor).InferResultType();
            }
        }
Beispiel #27
0
 public ContextInfo(syntax_tree_visitor syntax_tree_visitor)
 {
     SaveContext(syntax_tree_visitor);
 }
        /// <summary>
        /// Временный узел, который используется при выведении типов параметров
        /// </summary>
        /// <param name="def"></param>
        /// <param name="visitor"></param>
        /// <returns></returns>
        public static typed_expression GetTempFunctionNodeForTypeInference(SyntaxTree.function_lambda_definition def, syntax_tree_visitor visitor)
        {
            var res = new common_namespace_function_node(def.lambda_name, visitor.get_location(def), null, null);

            if (def.return_type != null)
            {
                res.return_value_type = visitor.convert_strong(def.return_type);
            }
            else
            {
                res.return_value_type = null;
            }
            res.parameters.clear();
            if (def.formal_parameters != null && def.formal_parameters.params_list.Count != 0)
            {
                for (int i = 0; i < def.formal_parameters.params_list.Count; i++)
                {
                    var tt = visitor.convert_strong(def.formal_parameters.params_list[i].vars_type); // SSM 29/12/18
                    for (int j = 0; j < def.formal_parameters.params_list[i].idents.idents.Count; j++)
                    {
                        var new_param = new common_parameter(null, SemanticTree.parameter_type.value, res, concrete_parameter_type.cpt_none, visitor.get_location(def.formal_parameters.params_list[i].idents.idents[0]));
                        new_param.type = tt;
                        res.parameters.AddElement(new_param);
                    }
                }
            }
            var hhh = new delegated_methods();

            hhh.proper_methods.AddElement(new common_namespace_function_call(res, visitor.get_location(def)));
            return(new typed_expression(hhh, visitor.get_location(def)));
        }
        public static void Substitute(syntax_tree_visitor _visitor, declarations decls, statement_list _statementList)
        {
            var tree = new CapturedVariablesTreeBuilder(_visitor).BuildTree(_statementList);
            var substs = new CapturedVariablesSubstitutionClassGenerator(tree.RootNode).GenerateSubstitutions();
            new CapturedVariablesSubstitutor(tree.IdentsReferences, substs.GeneratedScopeClassesInfo, substs.LambdasToBeAddedAsMethods, substs.SubstitutionsInfo, tree.CapturedVarsNodesDictionary, substs.ConvertingClassNonPublicMembersMapping, _visitor)
                .Substitute(_statementList);

            if (_visitor.context.converting_block() == block_type.function_block && tree.ProcedureScope != null)
            {
                if (decls != null && decls.defs != null)
                {
                    foreach (var def in decls.defs.Where(d => d is const_definition ||
                                                              d is consts_definitions_list ||
                                                              d is variable_definitions))
                    {
                        var constDef = def as const_definition;
                        if (constDef != null)
                        {
                            var finder = new FindMainIdentsVisitor();
                            finder.ProcessNode(constDef.const_value);

                            foreach (var v in finder.vars)
                            {
                                var si = _visitor.context.find(v.name);
                                if (si == null)
                                {
                                    continue;
                                }

                                if(tree.ProcedureScope.VariablesDefinedInScope.Any(var => var.SymbolInfo == si))
                                {
                                    _visitor.AddError(new UsingCapturedParameterIsNotAllowedInInitializers(_visitor.get_location(v)));
                                }
                            }
                            continue;
                        }

                        var constDefList = def as consts_definitions_list;
                        if (constDefList != null)
                        {
                            foreach (var cd in constDefList.const_defs)
                            {
                                var finder = new FindMainIdentsVisitor();
                                finder.ProcessNode(cd.const_value);

                                foreach (var v in finder.vars)
                                {
                                    var si = _visitor.context.find(v.name);
                                    if (si == null)
                                    {
                                        continue;
                                    }

                                    if (tree.ProcedureScope.VariablesDefinedInScope.Any(var => var.SymbolInfo == si))
                                    {
                                        _visitor.AddError(new UsingCapturedParameterIsNotAllowedInInitializers(_visitor.get_location(v)));
                                    }
                                }
                            }
                            continue;
                        }

                        var varDefList = def as variable_definitions;
                        if (varDefList != null)
                        {
                            foreach (var d in varDefList.var_definitions)
                            {
                                var finder = new FindMainIdentsVisitor();
                                finder.ProcessNode(d.inital_value);

                                foreach (var v in finder.vars)
                                {
                                    var si = _visitor.context.find(v.name);
                                    if (si == null)
                                    {
                                        continue;
                                    }

                                    if (tree.ProcedureScope.VariablesDefinedInScope.Any(var => var.SymbolInfo == si))
                                    {
                                        _visitor.AddError(new UsingCapturedParameterIsNotAllowedInInitializers(_visitor.get_location(v)));
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }