Ejemplo n.º 1
0
        private static SyntaxTree.if_node CreateNestedRegionBorder(bool ifEnter)
        {
            SyntaxTree.if_node result = new PascalABCCompiler.SyntaxTree.if_node();
            SyntaxTree.un_expr ue = new PascalABCCompiler.SyntaxTree.un_expr();
            ue.operation_type = PascalABCCompiler.SyntaxTree.Operators.LogicalNOT;
            ue.subnode = new SyntaxTree.ident(TreeConverter.compiler_string_consts.OMP_NESTED);
            result.condition = ue;

            SyntaxTree.assign AssignInParVar = new PascalABCCompiler.SyntaxTree.assign();
            AssignInParVar.operator_type = PascalABCCompiler.SyntaxTree.Operators.Assignment;
            AssignInParVar.from = new SyntaxTree.ident(ifEnter ? "true" : "false");
            AssignInParVar.to = new SyntaxTree.ident(InParallelSection);

            result.then_body = AssignInParVar;

            return result;
        }
Ejemplo n.º 2
0
        private static SyntaxTree.statement_list CreateFinalPart(string ObjName, VarInfoContainer Vars)
        {
            SyntaxTree.statement_list stl = new PascalABCCompiler.SyntaxTree.statement_list();

            //создаем присваивания разделяемым переменным
            for (int i = 0; i < Vars.SharedVariables.Count; ++i)
            {
                string VarName = Vars.SharedVariables[i].name;
                if (LoopVariables.Contains(VarName.ToLower()))
                    continue;

                SyntaxTree.dot_node DotNode = new PascalABCCompiler.SyntaxTree.dot_node();
                DotNode.left = new SyntaxTree.ident(ObjName);
                DotNode.right = new SyntaxTree.ident(VarName);

                SyntaxTree.array_type arrType = ConvertToSyntaxType(Vars.SharedVariables[i].type as type_node) as SyntaxTree.array_type;
                if (arrType != null && !is_dyn_arr(arrType))
                {
                    stl.subnodes.Add(AssignArrs(arrType, DotNode, new SyntaxTree.ident(VarName)));
                }
                else
                {
                    SyntaxTree.assign Assign = new PascalABCCompiler.SyntaxTree.assign();
                    Assign.operator_type = PascalABCCompiler.SyntaxTree.Operators.Assignment;
                    Assign.to = new SyntaxTree.ident(VarName);
                    Assign.from = DotNode;
                    stl.subnodes.Add(Assign);
                }

            }

            //создаем присваивания переменным редукции
            for (int i = 0; i < Vars.ReductionVariables.Count; ++i)
            {
                string VarName = Vars.ReductionVariables[i].name;

                SyntaxTree.dot_node DotNode = new PascalABCCompiler.SyntaxTree.dot_node();
                DotNode.left = new SyntaxTree.ident(ObjName);
                DotNode.right = new SyntaxTree.ident("$" + VarName);

                SyntaxTree.array_type arrType = ConvertToSyntaxType(Vars.ReductionVariables[i].type as type_node) as SyntaxTree.array_type;
                if (arrType != null && !is_dyn_arr(arrType))
                {
                    stl.subnodes.Add(AssignArrs(arrType, DotNode, new SyntaxTree.ident(VarName)));
                }
                else
                {
                    SyntaxTree.assign Assign = new PascalABCCompiler.SyntaxTree.assign();
                    Assign.operator_type = PascalABCCompiler.SyntaxTree.Operators.Assignment;
                    Assign.to = new SyntaxTree.ident(VarName);
                    Assign.from = DotNode;
                    stl.subnodes.Add(Assign);
                }
            }

            return stl;
        }
Ejemplo n.º 3
0
        private static SyntaxTree.procedure_definition CreateMethod(string MethodName, SyntaxTree.statement Body, string LoopVariableName, SyntaxTree.class_members ClassMember, VarInfoContainer Vars)
        {
            //  генерация метода
            SyntaxTree.procedure_definition ProcDef = new PascalABCCompiler.SyntaxTree.procedure_definition();
            //ClassMember.members.Add(ProcDef);
            SyntaxTree.procedure_header ProcHead = new PascalABCCompiler.SyntaxTree.procedure_header();
            ProcDef.proc_header = ProcHead;
            ProcHead.name = new PascalABCCompiler.SyntaxTree.method_name(null, null, new PascalABCCompiler.SyntaxTree.ident(MethodName), null);
            if (LoopVariableName != "")
            {
                //  параметр, счетчик цикла
                string ParamType = "integer";
                SyntaxTree.formal_parameters FormalParams = new PascalABCCompiler.SyntaxTree.formal_parameters();
                ProcHead.parameters = FormalParams;
                SyntaxTree.typed_parameters TypedParams = new PascalABCCompiler.SyntaxTree.typed_parameters();
                FormalParams.params_list.Add(TypedParams);
                SyntaxTree.ident_list idl = new PascalABCCompiler.SyntaxTree.ident_list();
                TypedParams.idents = idl;
                idl.Add(new SyntaxTree.ident(LoopVariableName));
                SyntaxTree.named_type_reference ntr = new PascalABCCompiler.SyntaxTree.named_type_reference();
                TypedParams.vars_type = ntr;
                ntr.Add(new SyntaxTree.ident(ParamType));
            }

            SyntaxTree.block ProcBlock = new PascalABCCompiler.SyntaxTree.block();
            ProcDef.proc_body = ProcBlock;
            ProcBlock.defs = new PascalABCCompiler.SyntaxTree.declarations();
            if (Vars.Constants.Count > 0)
            {
                SyntaxTree.consts_definitions_list cdl = new PascalABCCompiler.SyntaxTree.consts_definitions_list();
                ProcBlock.defs.defs.Add(cdl);
                //  константы - в методе
                for (int i = 0; i < Vars.Constants.Count; ++i)
                    cdl.Add(CreateClassMember(Vars.Constants[i], "") as SyntaxTree.typed_const_definition);
            }
            if ((Vars.ReductionVariables.Count > 0) || (Vars.PrivateVariables.Count > 0))
            {
                //  переменные редукции - в методе тоже, но без префикса
                SyntaxTree.variable_definitions vds = new PascalABCCompiler.SyntaxTree.variable_definitions();
                ProcBlock.defs.defs.Add(vds);
                for (int i = 0; i < Vars.ReductionVariables.Count; ++i)
                    vds.Add(CreateClassMember(Vars.ReductionVariables[i], "") as SyntaxTree.var_def_statement);
                //  и приватные переменные
                for (int i = 0; i < Vars.PrivateVariables.Count; ++i)
                    vds.Add(CreateClassMember(Vars.PrivateVariables[i], "") as SyntaxTree.var_def_statement);
            }

            if (Body is SyntaxTree.statement_list)
                ProcBlock.program_code = Body as SyntaxTree.statement_list;
            else
            {
                SyntaxTree.statement_list stl = new PascalABCCompiler.SyntaxTree.statement_list();
                stl.subnodes.Add(Body);
                ProcBlock.program_code = stl;
            }

            //присваивания для переменных редукции
            if (Vars.ReductionVariables.Count > 0)
            {
                SyntaxTree.statement_list LoopBodyInit = new PascalABCCompiler.SyntaxTree.statement_list();
                SyntaxTree.statement_list LoopBodyFinal = new PascalABCCompiler.SyntaxTree.statement_list();

                for (int i = 0; i < Vars.ReductionVariables.Count; ++i)
                {
                    //присваивание начального значения
                    SyntaxTree.assign Assign = new PascalABCCompiler.SyntaxTree.assign();
                    Assign.operator_type = PascalABCCompiler.SyntaxTree.Operators.Assignment;
                    Assign.to = new SyntaxTree.ident(Vars.ReductionVariables[i].name);
                    bool isBool = Vars.ReductionVariables[i].type.name.ToLower() == "boolean";
                    switch (Vars.ReductionActions[i])
                    {
                        case ReductionOperations.and:
                            {
                                if (isBool)
                                    Assign.from = new SyntaxTree.bool_const(true);
                                else
                                {
                                    //отрицание нуля
                                    Assign.from = new SyntaxTree.int32_const(0);
                                    LoopBodyInit.subnodes.Add(Assign);
                                    Assign = new PascalABCCompiler.SyntaxTree.assign();
                                    Assign.operator_type = PascalABCCompiler.SyntaxTree.Operators.Assignment;
                                    Assign.to = new SyntaxTree.ident(Vars.ReductionVariables[i].name);
                                    SyntaxTree.un_expr ue = new PascalABCCompiler.SyntaxTree.un_expr();
                                    ue.operation_type = PascalABCCompiler.SyntaxTree.Operators.LogicalNOT;
                                    ue.subnode = new SyntaxTree.ident(Vars.ReductionVariables[i].name);
                                    Assign.from = ue;
                                }
                                break;
                            }
                        case ReductionOperations.or:
                            if (isBool)
                                Assign.from = new SyntaxTree.bool_const(false);
                            else
                            {
                                Assign.from = new SyntaxTree.int32_const(0);
                            }
                            break;
                        case ReductionOperations.xor:  //
                        case ReductionOperations.plus: //см следующую ветку
                        case ReductionOperations.minus: Assign.from = new SyntaxTree.int32_const(0); break;
                        case ReductionOperations.mult: Assign.from = new SyntaxTree.int32_const(1); break;
                    }
                    LoopBodyInit.Add(Assign);

                    //присваивание после итерации
                    Assign = new PascalABCCompiler.SyntaxTree.assign();
                    Assign.operator_type = PascalABCCompiler.SyntaxTree.Operators.Assignment;
                    Assign.to = new SyntaxTree.ident("$" + Vars.ReductionVariables[i].name);
                    SyntaxTree.bin_expr From = new PascalABCCompiler.SyntaxTree.bin_expr();
                    From.left = new SyntaxTree.ident("$" + Vars.ReductionVariables[i].name);
                    From.right = new SyntaxTree.ident(Vars.ReductionVariables[i].name);
                    Assign.from = From;
                    switch (Vars.ReductionActions[i])
                    {
                        case ReductionOperations.and: From.operation_type = PascalABCCompiler.SyntaxTree.Operators.LogicalAND; break;
                        case ReductionOperations.or: From.operation_type = PascalABCCompiler.SyntaxTree.Operators.LogicalOR; break;
                        case ReductionOperations.xor: From.operation_type = PascalABCCompiler.SyntaxTree.Operators.BitwiseXOR; break;
                        case ReductionOperations.plus: From.operation_type = PascalABCCompiler.SyntaxTree.Operators.Plus; break;
                        case ReductionOperations.minus: From.operation_type = PascalABCCompiler.SyntaxTree.Operators.Minus; break;
                        case ReductionOperations.mult: From.operation_type = PascalABCCompiler.SyntaxTree.Operators.Multiplication; break;
                    }
                    LoopBodyFinal.Add(Assign);
                }

                //создаем обьект для блокировки в классе
                SyntaxTree.var_def_statement Lvds = new PascalABCCompiler.SyntaxTree.var_def_statement();
                SyntaxTree.ident_list Lidl = new PascalABCCompiler.SyntaxTree.ident_list();
                Lvds.vars = Lidl;
                Lidl.Add(new SyntaxTree.ident("$ReductionLock"));
                SyntaxTree.named_type_reference Lntr = new PascalABCCompiler.SyntaxTree.named_type_reference();
                Lvds.vars_type = Lntr;
                Lntr.Add(new SyntaxTree.ident("object"));
                SyntaxTree.new_expr Lne = new PascalABCCompiler.SyntaxTree.new_expr();
                Lvds.inital_value = Lne;
                Lne.type = Lntr;
                ClassMember.members.Add(Lvds);

                //создаем lock Statement на обьекте с присваиваниями в конце итерации
                SyntaxTree.lock_stmt reductionLock = new PascalABCCompiler.SyntaxTree.lock_stmt();
                reductionLock.lock_object = new SyntaxTree.ident("$ReductionLock");
                reductionLock.stmt = LoopBodyFinal;

                //собираем все вместе и присваиваем это телу процедуры
                LoopBodyInit.subnodes.AddRange(ProcBlock.program_code.subnodes);
                LoopBodyInit.subnodes.Add(reductionLock);
                ProcBlock.program_code = LoopBodyInit;
            }
            return ProcDef;
        }
Ejemplo n.º 4
0
        private static SyntaxTree.statement_list CreateInitPart(string ClassName, string ObjName, VarInfoContainer Vars)
        {
            SyntaxTree.statement_list stl = new PascalABCCompiler.SyntaxTree.statement_list();

            //Var Statement - объявление экземпляра обьекта-функции
            SyntaxTree.var_statement ClassVar = new PascalABCCompiler.SyntaxTree.var_statement();
            stl.subnodes.Add(ClassVar);
            SyntaxTree.var_def_statement ClassVarDef = new PascalABCCompiler.SyntaxTree.var_def_statement();
            ClassVar.var_def = ClassVarDef;
            SyntaxTree.ident_list ClassIdl = new PascalABCCompiler.SyntaxTree.ident_list();
            ClassVarDef.vars = ClassIdl;
            ClassIdl.idents.Add(new PascalABCCompiler.SyntaxTree.ident(ObjName));
            SyntaxTree.named_type_reference ClassTypeNTR = new PascalABCCompiler.SyntaxTree.named_type_reference();
            ClassVarDef.vars_type = ClassTypeNTR;
            ClassTypeNTR.names.Add(new PascalABCCompiler.SyntaxTree.ident(ClassName));
            SyntaxTree.new_expr ClassInitNE = new PascalABCCompiler.SyntaxTree.new_expr();
            ClassVarDef.inital_value = ClassInitNE;
            SyntaxTree.named_type_reference ClassInitNTR = new PascalABCCompiler.SyntaxTree.named_type_reference();
            ClassInitNE.type = ClassInitNTR;
            ClassInitNTR.names.Add(new PascalABCCompiler.SyntaxTree.ident(ClassName));

            //создаем присваивания разделяемым переменным
            for (int i = 0; i < Vars.SharedVariables.Count; ++i)
            {
                string VarName = Vars.SharedVariables[i].name;

                SyntaxTree.dot_node DotNode = new PascalABCCompiler.SyntaxTree.dot_node();
                DotNode.left = new SyntaxTree.ident(ObjName);
                DotNode.right = new SyntaxTree.ident(VarName);

                SyntaxTree.array_type arrType = ConvertToSyntaxType(Vars.SharedVariables[i].type as type_node) as SyntaxTree.array_type;
                if (arrType != null && !is_dyn_arr(arrType))
                {
                    stl.subnodes.Add(AssignArrs(arrType, new SyntaxTree.ident(VarName), DotNode));
                }
                else
                {
                    SyntaxTree.assign Assign = new PascalABCCompiler.SyntaxTree.assign();
                    Assign.operator_type = PascalABCCompiler.SyntaxTree.Operators.Assignment;
                    Assign.from = new SyntaxTree.ident(VarName);
                    Assign.to = DotNode;
                    stl.subnodes.Add(Assign);
                }
            }
            //создаем присваивания переменным редукции
            for (int i = 0; i < Vars.ReductionVariables.Count; ++i)
            {
                string VarName = Vars.ReductionVariables[i].name;

                SyntaxTree.dot_node DotNode = new PascalABCCompiler.SyntaxTree.dot_node();
                DotNode.left = new SyntaxTree.ident(ObjName);
                DotNode.right = new SyntaxTree.ident("$" + VarName);

                SyntaxTree.array_type arrType = ConvertToSyntaxType(Vars.ReductionVariables[i].type as type_node) as SyntaxTree.array_type;
                if (arrType != null && !is_dyn_arr(arrType))
                {
                    stl.subnodes.Add(AssignArrs(arrType, new SyntaxTree.ident(VarName), DotNode));
                }
                else
                {
                    SyntaxTree.assign Assign = new PascalABCCompiler.SyntaxTree.assign();
                    Assign.operator_type = PascalABCCompiler.SyntaxTree.Operators.Assignment;
                    Assign.from = new SyntaxTree.ident(VarName);
                    Assign.to = DotNode;
                    stl.subnodes.Add(Assign);
                }
            }
            return stl;
        }
Ejemplo n.º 5
0
        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;
        }