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); }
//инициализация критических секций с созданием класса 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); } }
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; }
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; }
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; }
/// <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; }