public string BuildCode(string existing_text, string generated_text, EventDescription event_description)
        {
            if (FirstCodeGeneration)
            {
                FirstCodeGeneration = false;
                string form_name = (Designer.Host.RootComponent as Control).Name;
                if (form_name == "Form1")
                {
                }
                string beg = string.Format(string_consts.begin_unit,
                                           Path.GetFileNameWithoutExtension(_file_name), (Designer.Host.RootComponent as Control).Name);
                existing_text   = beg + generated_text + string_consts.end_unit;
                TextEditor.Text = existing_text;
                if (event_description == null)
                {
                    return(existing_text); //beg + generated_text + SampleDesignerHost.string_consts.end_unit;
                }
            }
            //StringBuilder sb = new StringBuilder(existing_text); //TextEditor.Text);
            string[] sep = new string[1] {
                string_consts.nr
            };
            string[] lines = existing_text.Split(sep, StringSplitOptions.None);
            int      count = lines.Length;
            int      s_num = 0;
            string   trimed;

            //int end_region_num;
            while (s_num < count)
            {
                trimed = lines[s_num].TrimStart(' ', '\t');
                if (trimed.StartsWith(string_consts.begin_designer_region, StringComparison.InvariantCultureIgnoreCase))
                {
                    break;
                }
                s_num++;
            }
            if (s_num == count)
            {
                MessageDesignerCodeGenerationFailed();
                return(null);
            }
            int e_num = s_num + 1;

            while (e_num < count)
            {
                trimed = lines[e_num].TrimStart(' ', '\t');
                if (trimed.StartsWith(string_consts.end_designer_region, StringComparison.InvariantCultureIgnoreCase))
                {
                    break;
                }
                e_num++;
            }
            if (e_num == count)
            {
                MessageDesignerCodeGenerationFailed();
                return(null);
            }
            List <PascalABCCompiler.Errors.Error>           Errors   = new List <PascalABCCompiler.Errors.Error>();
            List <PascalABCCompiler.Errors.CompilerWarning> Warnings = new List <PascalABCCompiler.Errors.CompilerWarning>();

            //PascalABCCompiler.SyntaxTree.syntax_tree_node sn =
            //    MainForm.VisualEnvironmentCompiler.Compiler.ParsersController.Compile(
            //    FileName, TextEditor.Text, null, Errors, PascalABCCompiler.Parsers.ParseMode.Normal);
            PascalABCCompiler.SyntaxTree.compilation_unit sn =
                CodeCompletion.CodeCompletionController.ParsersController.GetCompilationUnit(
                    VisualPABCSingleton.MainForm._currentCodeFileDocument.FileName,
                    existing_text, //VisualPascalABC.Form1.Form1_object._currentCodeFileDocument.TextEditor.Text,
                    Errors,
                    Warnings);
            PascalABCCompiler.SyntaxTree.unit_module um = sn as PascalABCCompiler.SyntaxTree.unit_module;
            bool good_syntax = um != null;

            PascalABCCompiler.SyntaxTree.type_declaration form_decl = null;
            if (good_syntax)
            {
                good_syntax = um.implementation_part != null &&
                              um.interface_part != null &&
                              um.interface_part.interface_definitions != null &&
                              um.interface_part.interface_definitions.defs != null &&
                              um.interface_part.interface_definitions.defs.Count > 0;
            }
            if (good_syntax)
            {
                foreach (PascalABCCompiler.SyntaxTree.declaration decl in um.interface_part.interface_definitions.defs)
                {
                    PascalABCCompiler.SyntaxTree.type_declarations tdecls = decl as PascalABCCompiler.SyntaxTree.type_declarations;
                    if (tdecls != null)
                    {
                        foreach (PascalABCCompiler.SyntaxTree.type_declaration tdecl in tdecls.types_decl)
                        {
                            if (tdecl.source_context.begin_position.line_num - 1 < s_num &&
                                tdecl.source_context.end_position.line_num - 1 > e_num)
                            {
                                form_decl = tdecl;
                            }
                        }
                    }
                }
            }
            PascalABCCompiler.SyntaxTree.class_definition form_def = null;
            if (form_decl != null)
            {
                form_def = form_decl.type_def as PascalABCCompiler.SyntaxTree.class_definition;
            }
            if (form_decl == null || form_def == null || form_def.body == null)
            {
                MessageBox.Show(PascalABCCompiler.StringResources.Get("VP_MF_CODE_GENERATION_UNSUCCEFULL"),
                                PascalABCCompiler.StringResources.Get("VP_MF_FORM_DESIGNER"),
                                MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return(null);
            }
            else
            {
                string old_form_name           = form_decl.type_name.name;
                string new_form_name           = (Designer.Host.RootComponent as Control).Name;
                bool   implementation_not_null =
                    um.implementation_part.implementation_definitions != null &&
                    um.implementation_part.implementation_definitions.defs != null &&
                    um.implementation_part.implementation_definitions.defs.Count > 0;
                if (new_form_name != old_form_name)
                {
                    ReplaceName(form_decl.type_name, new_form_name, lines);
                    if (implementation_not_null)
                    {
                        foreach (PascalABCCompiler.SyntaxTree.declaration decl in
                                 um.implementation_part.implementation_definitions.defs)
                        {
                            PascalABCCompiler.SyntaxTree.procedure_definition pd = decl as PascalABCCompiler.SyntaxTree.procedure_definition;
                            if (pd != null)
                            {
                                if (pd.proc_header.name.class_name != null &&
                                    string.Compare(pd.proc_header.name.class_name.name, old_form_name, true) == 0)
                                {
                                    ReplaceName(pd.proc_header.name.class_name, new_form_name, lines);
                                }
                            }
                        }
                    }
                }
                if (event_description != null)
                {
                    MethodInfo mi = event_description.e.EventType.GetMethod(
                        PascalABCCompiler.TreeConverter.compiler_string_consts.invoke_method_name);
                    ParameterInfo[] pinfos        = mi.GetParameters();
                    bool            handler_found = false;

                    event_description.editor = TextEditor;
                    System.Text.RegularExpressions.MatchCollection matches =
                        System.Text.RegularExpressions.Regex.Matches(generated_text, string_consts.nr);
                    //строка, на которой последнее описание из секции реализаций
                    PascalABCCompiler.SyntaxTree.file_position last_defs_pos = null;
                    if (implementation_not_null)
                    {
                        last_defs_pos = um.implementation_part.implementation_definitions.defs[
                            um.implementation_part.implementation_definitions.defs.Count - 1
                                        ].source_context.end_position;

                        //Ищем описание обработчика
                        foreach (PascalABCCompiler.SyntaxTree.declaration decl in
                                 um.implementation_part.implementation_definitions.defs)
                        {
                            PascalABCCompiler.SyntaxTree.procedure_definition pd = decl as PascalABCCompiler.SyntaxTree.procedure_definition;
                            if (pd == null)
                            {
                                continue;
                            }
                            if (pd.proc_header.name == null || pd.proc_header.name.class_name == null ||              //roman//
                                String.Compare(pd.proc_header.name.class_name.name, new_form_name, true) != 0 ||
                                String.Compare(pd.proc_header.name.meth_name.name, event_description.EventName, true) != 0)
                            {
                                continue;
                            }
                            List <PascalABCCompiler.SyntaxTree.typed_parameters> syn_pars =
                                pd.proc_header.parameters.params_list;
                            bool should_continue = false;
                            int  par_count       = syn_pars.Count;
                            if (par_count != pinfos.Length)
                            {
                                continue;
                            }
                            for (int i = 0; i < par_count; ++i)
                            {
                                if (syn_pars[i].idents.idents.Count != 1)
                                {
                                    should_continue = true;
                                    break;
                                }
                                PascalABCCompiler.SyntaxTree.named_type_reference ntr =
                                    syn_pars[i].vars_type as PascalABCCompiler.SyntaxTree.named_type_reference;
                                if (ntr == null || syn_pars[i].param_kind != PascalABCCompiler.SyntaxTree.parametr_kind.none)
                                {
                                    should_continue = true;
                                    break;
                                }
                                string syn_name = BuildName(ntr.names);
                                if (String.Compare(syn_name, pinfos[i].ParameterType.Name) != 0 &&
                                    String.Compare(syn_name, pinfos[i].ParameterType.FullName) != 0)
                                {
                                    should_continue = true;
                                    break;
                                }
                            }
                            if (should_continue)
                            {
                                continue;
                            }
                            handler_found = true;
                            event_description.line_num = pd.proc_body.source_context.begin_position.line_num +
                                                         matches.Count + s_num - e_num + 2;
                            //last_defs_pos.line_num + s_num - e_num + matches.Count + 7;
                            event_description.column_num = pd.proc_body.source_context.begin_position.column_num;
                        }
                    }
                    else
                    {
                        last_defs_pos = um.implementation_part.source_context.end_position;
                    }
                    if (!handler_found)
                    {
                        string new_event = event_description.EventName;
                        if (pinfos.Length != 0)
                        {
                            new_event += "(";
                            new_event += pinfos[0].Name + ": " + pinfos[0].ParameterType.FullName.Replace("System.Windows.Forms.", "").Replace("System.", "");
                            for (int i = 1; i < pinfos.Length; ++i)
                            {
                                new_event += "; ";
                                new_event += pinfos[i].Name + ": " + pinfos[i].ParameterType.FullName.Replace("System.Windows.Forms.", "").Replace("System.", "");
                            }
                            new_event += ")";
                        }
                        new_event += ";";
                        string new_event_header = new_event;
                        new_event  = string_consts.nr + string_consts.nr + "procedure " + new_form_name + "." + new_event;
                        new_event += string_consts.nr + "begin" +
                                     string_consts.nr + "  " + string_consts.nr +
                                     "end;";
                        event_description.column_num      = 3;
                        event_description.line_num        = last_defs_pos.line_num + s_num - e_num + matches.Count + 7;
                        lines[last_defs_pos.line_num - 1] = lines[last_defs_pos.line_num - 1].Insert(last_defs_pos.column_num, new_event);
                        //Добавляем заголовок события
                        //int last_form_member_line = form_def.body.class_def_blocks[form_def.body.class_def_blocks.Count - 1].source_context.end_position.line_num - 1;
                        lines[s_num] = string_consts.event_handler_header_trim +
                                       "procedure " + new_event_header +
                                       string_consts.nr + lines[s_num];
                    }
                }
            }
            //generated_text = SampleDesignerHost.string_consts.tab + "private" +
            //    SampleDesignerHost.string_consts.nr + generated_text;
            string s1 = string.Join(string_consts.nr, lines, 0, s_num + 1);
            string s2 = string.Join(string_consts.nr, lines, e_num, lines.Length - e_num);

            return(s1 + string_consts.nr + string_consts.tab +
                   "internal" + string_consts.nr +
                   string_consts.tab2 + generated_text + s2);
        }
Example #2
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);
            }
        }
Example #3
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;
        }
Example #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;
        }
Example #5
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;
        }
Example #6
0
        /// <summary>
        /// Возвращает по семантическому типу соответсвующий ему синтаксический тип
        /// </summary>
        /// <param name="sem_type">семантический тип</param>
        /// <returns>Синтаксический тип</returns>
        public static SyntaxTree.type_definition ConvertToSyntaxType(type_node sem_type)
        {
            if (sem_type.IsPointer)// если указатель
            {
                SyntaxTree.ref_type rt = new PascalABCCompiler.SyntaxTree.ref_type();
                rt.pointed_to = ConvertToSyntaxType((sem_type as ref_type_node).pointed_type);
                return rt;

            }
            else
                if (sem_type.type_special_kind == SemanticTree.type_special_kind.none_kind
                    || sem_type.type_special_kind == SemanticTree.type_special_kind.record || sem_type.type_special_kind == SemanticTree.type_special_kind.text_file)
                {
                    if (sem_type.is_generic_type_instance)// это шаблонный тип
                    {
                        SyntaxTree.template_type_reference ttr = new PascalABCCompiler.SyntaxTree.template_type_reference();
                        SyntaxTree.named_type_reference ntr = new PascalABCCompiler.SyntaxTree.named_type_reference();
                        ttr.name = ntr;
                        ntr.names.AddRange(get_idents_from_generic_type(sem_type));
                        SyntaxTree.template_param_list tpl = new PascalABCCompiler.SyntaxTree.template_param_list();
                        ttr.params_list = tpl;
                        foreach (type_node tn in sem_type.instance_params)
                            tpl.params_list.Add(ConvertToSyntaxType(tn));

                        return ttr;
                    }
                    else if (sem_type.IsEnum)
                        return new PascalABCCompiler.SyntaxTree.named_type_reference(get_idents_from_dot_string(sem_type.name));
                    else
                        return new PascalABCCompiler.SyntaxTree.named_type_reference(get_idents_from_dot_string(sem_type.PrintableName));
                }
                else if (sem_type.type_special_kind == SemanticTree.type_special_kind.array_kind || sem_type.type_special_kind == SemanticTree.type_special_kind.array_wrapper)
                {
                    //значит тип-это массив
                    SyntaxTree.array_type arr_t = new PascalABCCompiler.SyntaxTree.array_type();
                    arr_t.source_context = new PascalABCCompiler.SyntaxTree.SourceContext(0xFFFFFF, 0, 0xFFFFFF, 0);
                    // Cоздаем индексер для массива
                    SyntaxTree.indexers_types indt = new PascalABCCompiler.SyntaxTree.indexers_types();
                    if (sem_type is common_type_node)
                    {
                        SyntaxTree.diapason diap = new PascalABCCompiler.SyntaxTree.diapason();
                        common_type_node ctn = sem_type as common_type_node;
                        if (ctn.constants.Length > 1)
                        {
                            diap.left = ConvertConstant(ctn.constants[0].constant_value);
                            diap.right = ConvertConstant(ctn.constants[1].constant_value);
                            indt.indexers.Add(diap);
                        }
                        else
                        {
                            for (int i = 0; i < ctn.rank; i++)
                                indt.indexers.Add(null);
                        }

                        arr_t.indexers = indt;
                    }
                    else if (sem_type is compiled_type_node)
                    {
                        compiled_type_node ctn = sem_type as compiled_type_node;
                        if (ctn.rank > 1)
                        {
                            for (int i = 0; i < ctn.rank; i++)
                                indt.indexers.Add(null);
                            arr_t.indexers = indt;
                        }
                        //Получаем индексеры из строки
                        //string ind_str = sem_type.PrintableName;
                        //ind_str = get_indexer_string(ind_str);

                        //if (ind_str.Length != 0)
                        //{
                        //    indt.indexers.AddRange(get_diapasons(ind_str).ToArray());
                        //    arr_t.indexers = indt;
                        //}
                    }
                    //проверяем тип элементов массива               
                    if (sem_type.element_type != null)
                    {
                        arr_t.elements_type = ConvertToSyntaxType(sem_type.element_type);
                    }
                    return arr_t;
                }
                else if (sem_type.type_special_kind == SemanticTree.type_special_kind.typed_file || sem_type.type_special_kind == SemanticTree.type_special_kind.binary_file)
                {
                    SyntaxTree.file_type ft = new PascalABCCompiler.SyntaxTree.file_type();
                    if (sem_type.element_type != null)
                        ft.file_of_type = ConvertToSyntaxType(sem_type.element_type);
                    //SyntaxTree.named_type_reference ntr = null;
                    //if (sem_type.element_type!= null)
                    //    ntr= new PascalABCCompiler.SyntaxTree.named_type_reference(get_idents_from_dot_string(sem_type.element_type.name));
                    //ft.file_of_type = ntr;
                    return ft;
                }
                else if (sem_type.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.short_string)
                {
                    SyntaxTree.string_num_definition snd = new PascalABCCompiler.SyntaxTree.string_num_definition();
                    snd.name = new SyntaxTree.ident(sem_type.name.Substring(0, sem_type.name.IndexOf('[')));
                    snd.num_of_symbols = new SyntaxTree.int32_const(Int32.Parse(get_indexer_string(sem_type.PrintableName)));
                    return snd;
                }
                else if (sem_type.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.set_type)
                {
                    SyntaxTree.set_type_definition std = new PascalABCCompiler.SyntaxTree.set_type_definition();
                    if (sem_type.element_type != null)
                        std.of_type = ConvertToSyntaxType(sem_type.element_type);
                    return std;
                }
                else if (sem_type.type_special_kind == SemanticTree.type_special_kind.diap_type)
                {
                    return get_diapason(sem_type);


                }

            return null;
        }