コード例 #1
0
ファイル: OpenMP.cs プロジェクト: lisiynos/pascalabcnet
        private static SyntaxTree.statement_list AssignArrs(SyntaxTree.array_type ArrFrom, SyntaxTree.addressed_value IdFrom, SyntaxTree.addressed_value IdTo)
        {
            SyntaxTree.statement_list OuterSTL = new PascalABCCompiler.SyntaxTree.statement_list();
            SyntaxTree.statement_list InnerSTL = OuterSTL;
            List<List<SyntaxTree.diapason>> DiapasonsList = get_list_of_diapasons(ArrFrom);
            List<List<SyntaxTree.ident>> IdentsList = new List<List<PascalABCCompiler.SyntaxTree.ident>>();
            int VarNum = 0;
            if (DiapasonsList == null)
                DiapasonsList = new List<List<PascalABCCompiler.SyntaxTree.diapason>>();
            foreach (List<SyntaxTree.diapason> Diapasons in DiapasonsList)
            {
                bool IsDynamicArray = false;
                List<SyntaxTree.method_call> Lens = new List<PascalABCCompiler.SyntaxTree.method_call>();
                if ((Diapasons.Count == 0) || (Diapasons[0] == null))
                {
                    //массив динамический, нужно делать setlength
                    IsDynamicArray = true;
                    SyntaxTree.procedure_call SetLenPC = new PascalABCCompiler.SyntaxTree.procedure_call();
                    SyntaxTree.method_call SetLenMC = new PascalABCCompiler.SyntaxTree.method_call();
                    SetLenMC.dereferencing_value = new SyntaxTree.ident("SetLength");
                    SetLenPC.func_name = SetLenMC;
                    SyntaxTree.expression_list SetLenParamsExl = new PascalABCCompiler.SyntaxTree.expression_list();
                    SetLenMC.parameters = SetLenParamsExl;

                    //индексное выражение для массива-приемника
                    SyntaxTree.addressed_value IndexerTo = IdTo;
                    foreach (List<SyntaxTree.ident> Idents in IdentsList)
                    {
                        SyntaxTree.indexer InnerInd = new PascalABCCompiler.SyntaxTree.indexer();
                        InnerInd.dereferencing_value = IndexerTo;
                        SyntaxTree.expression_list IndexersExl = new PascalABCCompiler.SyntaxTree.expression_list();
                        foreach (SyntaxTree.ident Ident in Idents)
                            IndexersExl.expressions.Add(new SyntaxTree.ident(Ident.name));
                        InnerInd.indexes = IndexersExl;
                        IndexerTo = InnerInd;
                    }

                    //индексное выражение для массива-источника
                    SyntaxTree.addressed_value IndexerFrom = IdFrom;
                    foreach (List<SyntaxTree.ident> Idents in IdentsList)
                    {
                        SyntaxTree.indexer InnerInd = new PascalABCCompiler.SyntaxTree.indexer();
                        InnerInd.dereferencing_value = IndexerFrom;
                        SyntaxTree.expression_list IndexersExl = new PascalABCCompiler.SyntaxTree.expression_list();
                        foreach (SyntaxTree.ident Ident in Idents)
                            IndexersExl.expressions.Add(new SyntaxTree.ident(Ident.name));
                        InnerInd.indexes = IndexersExl;
                        IndexerFrom = InnerInd;
                    }

                    SetLenParamsExl.expressions.Add(IndexerTo);

                    //List<SyntaxTree.method_call> Lengths = new List<PascalABCCompiler.SyntaxTree.method_call>();
                    if (Diapasons.Count == 0)
                    {
                        SyntaxTree.method_call LengthMC = new PascalABCCompiler.SyntaxTree.method_call();
                        LengthMC.dereferencing_value = new SyntaxTree.ident("Length");
                        SyntaxTree.expression_list LenMCExl = new PascalABCCompiler.SyntaxTree.expression_list();
                        LengthMC.parameters = LenMCExl;
                        LenMCExl.expressions.Add(IndexerFrom);
                        SetLenParamsExl.expressions.Add(LengthMC);
                        Lens.Add(LengthMC);
                    }
                    else
                    {
                        for (int i = 0; i < Diapasons.Count; ++i)
                        {
                            SyntaxTree.method_call LengthMC = new PascalABCCompiler.SyntaxTree.method_call();
                            LengthMC.dereferencing_value = new SyntaxTree.ident("Length");
                            SyntaxTree.expression_list LenMCExl = new PascalABCCompiler.SyntaxTree.expression_list();
                            LengthMC.parameters = LenMCExl;
                            LenMCExl.expressions.Add(IndexerFrom);
                            LenMCExl.expressions.Add(new SyntaxTree.int32_const(i));
                            SetLenParamsExl.expressions.Add(LengthMC);
                            Lens.Add(LengthMC);
                        }
                    }
                    InnerSTL.subnodes.Add(SetLenPC);
                }
                //к этому моменту вызов SetLength с параметрами сформирован
                //в Lens содержатся вызовы length по нужной размерности если массив динамический
                //теперь нужно создать циклы for и список переменных, по которым идут циклы
                List<SyntaxTree.ident> LoopIdents = new List<SyntaxTree.ident>();
                for (int i = 0; i < Math.Max(Diapasons.Count, 1); ++i)
                {
                    SyntaxTree.for_node ForNode = new PascalABCCompiler.SyntaxTree.for_node();
                    SyntaxTree.ident LoopVar = new PascalABCCompiler.SyntaxTree.ident("$i" + (VarNum++).ToString());
                    LoopIdents.Add(LoopVar);
                    ForNode.loop_variable = LoopVar;
                    ForNode.create_loop_variable = true;
                    if (IsDynamicArray)
                    {
                        ForNode.initial_value = new SyntaxTree.int32_const(0);
                        ForNode.finish_value = new PascalABCCompiler.SyntaxTree.bin_expr(Lens[i], new SyntaxTree.int32_const(1), PascalABCCompiler.SyntaxTree.Operators.Minus);
                    }
                    else
                    {
                        ForNode.initial_value = Diapasons[i].left;
                        ForNode.finish_value = Diapasons[i].right;
                    }
                    InnerSTL.subnodes.Add(ForNode);
                    ForNode.statements = new PascalABCCompiler.SyntaxTree.statement_list();
                    InnerSTL = ForNode.statements as SyntaxTree.statement_list;
                }
                IdentsList.Add(LoopIdents);
            }

            // к этому моменту создано гнездо циклов с установкой длины динамических массивов и перебором
            // вообще всех массивов. Осталось создать самое внутреннее присваивание
            SyntaxTree.addressed_value AssignIndexerFrom = IdFrom;
            SyntaxTree.addressed_value AssignIndexerTo = IdTo;
            foreach (List<SyntaxTree.ident> AssignIdents in IdentsList)
            {
                SyntaxTree.indexer FromIndexer = new PascalABCCompiler.SyntaxTree.indexer();
                SyntaxTree.indexer ToIndexer = new PascalABCCompiler.SyntaxTree.indexer();
                FromIndexer.dereferencing_value = AssignIndexerFrom;
                ToIndexer.dereferencing_value = AssignIndexerTo;

                SyntaxTree.expression_list Exl = new PascalABCCompiler.SyntaxTree.expression_list();
                foreach (SyntaxTree.ident id in AssignIdents)
                    Exl.expressions.Add(id);
                FromIndexer.indexes = Exl;
                ToIndexer.indexes = Exl;

                AssignIndexerFrom = FromIndexer;
                AssignIndexerTo = ToIndexer;
            }
            SyntaxTree.assign Assign = new PascalABCCompiler.SyntaxTree.assign();
            Assign.from = AssignIndexerFrom;
            Assign.to = AssignIndexerTo;
            Assign.operator_type = PascalABCCompiler.SyntaxTree.Operators.Assignment;
            InnerSTL.subnodes.Add(Assign);

            return OuterSTL;
        }
コード例 #2
0
ファイル: OpenMP.cs プロジェクト: lisiynos/pascalabcnet
        private static SyntaxTree.procedure_call CreateOMPParallelForCall(SyntaxTree.dot_node dn, SyntaxTree.expression FromInclusive, SyntaxTree.expression ToInclusive)
        {
            SyntaxTree.procedure_call pc = new PascalABCCompiler.SyntaxTree.procedure_call();
            SyntaxTree.method_call mc = new PascalABCCompiler.SyntaxTree.method_call();
            pc.func_name = mc;
            mc.dereferencing_value = CreateTPLFunctionReference("For");

            //Здесь прибавляем единицу ко второму параметру, так как в паскале верхняя граница включается, а в parallel.for - нет
            SyntaxTree.bin_expr ToExclusive = new SyntaxTree.bin_expr();
            ToExclusive.left = ToInclusive;
            ToExclusive.right = new SyntaxTree.int32_const(1);
            ToExclusive.operation_type = SyntaxTree.Operators.Plus;

            mc.parameters = new PascalABCCompiler.SyntaxTree.expression_list();
            mc.parameters.Add(FromInclusive);
            mc.parameters.Add(ToExclusive);
            mc.parameters.Add(dn);
            return pc;
        }
コード例 #3
0
ファイル: OpenMP.cs プロジェクト: lisiynos/pascalabcnet
        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;
        }