public void SaveXml(CompilationUnit cu) { try { this.cu = cu; is_assembly = cu.SyntaxTree is SyntaxTree.program_module || Compiler.is_dll(cu.SyntaxTree); XmlWriterSettings settings = new XmlWriterSettings(); settings.Encoding = Encoding.UTF8; settings.Indent = true; xtw = XmlTextWriter.Create(Path.ChangeExtension(cu.UnitName, ".xml"), settings); unit_name = Path.GetFileNameWithoutExtension(cu.UnitName); xtw.WriteStartDocument(); xtw.WriteStartElement("doc"); if (is_assembly) { xtw.WriteStartElement("assembly"); xtw.WriteStartElement("name"); xtw.WriteString(Path.GetFileNameWithoutExtension(cu.UnitName)); xtw.WriteEndElement(); xtw.WriteEndElement(); } else { xtw.WriteStartElement("unit"); xtw.WriteStartAttribute("name"); //xtw.WriteString((cu.SemanticTree as common_unit_node).unit_name); xtw.WriteString(Path.GetFileNameWithoutExtension(cu.UnitName)); xtw.WriteEndAttribute(); xtw.WriteString(cu.SemanticTree.documentation); xtw.WriteEndElement(); } SaveMembers(); xtw.WriteEndElement(); xtw.Flush(); } catch (Exception e) { } try { if (xtw != null) xtw.Close(); } catch { } }
public CompilationUnit ReadDLL(string FileName) { if (DLLCashe.ContainsKey(FileName)) return DLLCashe[FileName]; OnChangeCompilerState(this, CompilerState.ReadDLL, FileName); TreeRealization.using_namespace_list using_namespaces = new TreeRealization.using_namespace_list(); try { TreeRealization.dot_net_unit_node un = new TreeRealization.dot_net_unit_node(new NetHelper.NetScope(using_namespaces, /*System.Reflection.Assembly.LoadFrom(FileName)*/ PascalABCCompiler.NetHelper.NetHelper.LoadAssembly(FileName), SyntaxTreeToSemanticTreeConverter.SymbolTable)); CompilationUnit cu = new CompilationUnit(); cu.SemanticTree = un; //un.dotNetScope=new PascalABCCompiler.NetHelper.NetScope(using_namespaces, // System.Reflection.Assembly.LoadFrom(FileName),SyntaxTreeToSemanticTreeConverter.SymbolTable); DLLCashe[FileName] = cu; return cu; } catch (Exception e) { return null; } }
private TreeRealization.unit_node_list buildImplementationUsesList(CompilationUnit cu) { TreeRealization.unit_node_list unl = new PascalABCCompiler.TreeRealization.unit_node_list(); unl.AddRange(cu.ImplementationUsedUnits); foreach (TreeRealization.unit_node un in cu.InterfaceUsedUnits) { if (un is TreeRealization.dot_net_unit_node) unl.AddElement(un); } return unl; }
public void SavePCU(CompilationUnit Unit,string TagertFileName) { //#if DEBUG try { if (Unit.SyntaxTree != null && Unit.SyntaxTree is SyntaxTree.unit_module) { if (((SyntaxTree.unit_module)Unit.SyntaxTree).unit_name.HeaderKeyword == PascalABCCompiler.SyntaxTree.UnitHeaderKeyword.Library) return; foreach (SyntaxTree.compiler_directive cd in Unit.SyntaxTree.compiler_directives) if (cd.Name.text.ToLower() == TreeConverter.compiler_string_consts.compiler_savepcu) if (!Convert.ToBoolean(cd.Directive.text)) return; } } catch { } //#endif PCUWriter writer=null; try { #if DEBUG if (InternalDebug.PCUGenerate) #endif if (compilerOptions.SavePCU) if ((Unit.SemanticTree as TreeRealization.common_unit_node).namespaces.Count > 1 && Unit.SyntaxTree!=null && Unit.State == UnitState.Compiled) { writer = new PCUWriter(this, pr_ChangeState); if (FileInSearchDirectory(TagertFileName)) TagertFileName = Path.ChangeExtension(TagertFileName, CompilerOptions.CompiledUnitExtension); else { if(CompilerOptions.useOutputDirectory) TagertFileName = Path.Combine(CompilerOptions.OutputDirectory, Path.GetFileName(Path.ChangeExtension(TagertFileName, CompilerOptions.CompiledUnitExtension))); else TagertFileName = Path.Combine(Path.GetDirectoryName(Unit.SyntaxTree.file_name), Path.GetFileName(Path.ChangeExtension(TagertFileName, CompilerOptions.CompiledUnitExtension))); } bool dbginfo = true;/*CompilerOptions.Debug*/ #if DEBUG dbginfo = InternalDebug.IncludeDebugInfoInPCU; #endif writer.SaveSemanticTree(Unit, TagertFileName, dbginfo); } } catch (Exception err) { //ErrorsList.Add(new Errors.CompilerInternalError(string.Format("Compiler.Compile[{0}]", Path.GetFileName(this.CurrentCompilationUnit.SyntaxTree.file_name)), err)); OnChangeCompilerState(this, CompilerState.PCUWritingError, TagertFileName); #if DEBUG if (!InternalDebug.SkipPCUErrors) throw new Errors.CompilerInternalError(string.Format("Compiler.Compile[{0}]", Path.GetFileName(this.CurrentCompilationUnit.SyntaxTree.file_name)), err); writer.RemoveSelf(); #endif } }
public CompilationUnit CompileUnit(PascalABCCompiler.TreeRealization.unit_node_list Units, SyntaxTree.unit_or_namespace SyntaxUsesUnit) { string UnitName = GetUnitFileName(SyntaxUsesUnit); //if (UnitName == null) throw new UnitNotFound(SyntaxUsesUnit.name, CompilationUnit CurrentUnit = UnitTable[UnitName]; string name = Path.GetFileNameWithoutExtension(UnitName); if (Path.GetExtension(UnitName).ToLower() == CompilerOptions.CompiledUnitExtension) { string sfn = FindSourceFileName(Path.GetFileNameWithoutExtension(UnitName)); if (sfn != null && UnitTable[sfn] != null) CurrentUnit = UnitTable[sfn]; } if (CurrentUnit != null) if (CurrentUnit.State != UnitState.BeginCompilation || CurrentUnit.SemanticTree != null) //ИЗБАВИТЬСЯ ОТ ВТОРОГО УСЛОВИЯ { Units.AddElement(CurrentUnit.SemanticTree); Units.AddRange(GetReferences(CurrentUnit)); return CurrentUnit; } if (UnitName.ToLower().LastIndexOf(".dll") >= 0 || UnitName.ToLower().LastIndexOf(".exe") >= 0) if (File.Exists(UnitName)) { if (UnitTable.Count == 0) throw new ProgramModuleExpected(UnitName, null); if ((CurrentUnit = ReadDLL(UnitName)) != null) { Units.AddElement(CurrentUnit.SemanticTree); UnitTable[UnitName] = CurrentUnit; return CurrentUnit; } else //throw new DLLReadingError(UnitName); throw new AssemblyReadingError(CurrentCompilationUnit.SyntaxTree.file_name, UnitName, SyntaxUsesUnit.source_context); } if (Path.GetExtension(UnitName).ToLower() == CompilerOptions.CompiledUnitExtension) if (File.Exists(UnitName)) { if (UnitTable.Count == 0) throw new ProgramModuleExpected(UnitName, null); string SourceFileName = FindSourceFileName(Path.Combine(Path.GetDirectoryName(UnitName), Path.GetFileNameWithoutExtension(UnitName))); try { //TODO: подумать как это нормально сделать /*if (CompilerOptions.Debug) { PCUReader.PCUFileHeadState PCUFileHeadState = PCUReader.GetPCUFileHeadState(UnitName); if (PCUFileHeadState.IsPCUFile && PCUFileHeadState.SupportedVersion && !PCUFileHeadState.IncludetDebugInfo && SourceFileName != null) { //перекомпилируем файл для получения отладочной информации throw new Exception(""); } }*/ if ((CurrentUnit = ReadPCU(UnitName)) != null) { Units.AddElement(CurrentUnit.SemanticTree); Units.AddRange(GetReferences(CurrentUnit)); UnitTable[UnitName] = CurrentUnit; return CurrentUnit; } } catch (InvalidPCUFule) { //Перекомпилируем.... } catch (Error) { throw; } catch (Exception e) { OnChangeCompilerState(this, CompilerState.PCUReadingError, UnitName); #if DEBUG if (!InternalDebug.SkipPCUErrors) throw new Errors.CompilerInternalError("PCUReader", e); #endif } if (SourceFileName == null) throw new ReadPCUError(UnitName); else UnitName = SourceFileName; } string SourceText = null; Dictionary<SyntaxTree.syntax_tree_node, string> docs = null; if (CurrentUnit == null) { CurrentUnit = new CompilationUnit(); if (FirstCompilationUnit == null) FirstCompilationUnit = CurrentUnit; OnChangeCompilerState(this, CompilerState.BeginCompileFile, UnitName); SourceText = GetSourceFileText(UnitName); if (SourceText == null) if (CurrentUnit == FirstCompilationUnit) throw new SourceFileNotFound(UnitName); else throw new UnitNotFound(CurrentCompilationUnit.SyntaxTree.file_name, UnitName, SyntaxUsesUnit.source_context); CurrentUnit.SyntaxTree = InternalParseText(UnitName, SourceText, errorsList); if (errorsList.Count == 0) // SSM 2/05/16 - для преобразования синтаксических деревьев извне { CurrentUnit.SyntaxTree = syntaxTreeConvertersController.Convert(CurrentUnit.SyntaxTree) as SyntaxTree.compilation_unit; } if (errorsList.Count == 0 && need_gen_doc(CurrentUnit.SyntaxTree)) { if (SourceText != null) { docs = AddDocumentationToNodes(CurrentUnit.SyntaxTree, SourceText); if (docs != null) CurrentUnit.Documented = true; } } if (CurrentUnit.SyntaxTree is SyntaxTree.unit_module) compilerOptions.UseDllForSystemUnits = false; if (is_dll(CurrentUnit.SyntaxTree)) compilerOptions.OutputFileType = PascalABCCompiler.CompilerOptions.OutputType.ClassLibrary; CurrentUnit.CaseSensitive = ParsersController.LastParser.CaseSensitive; CurrentCompilationUnit = CurrentUnit; CurrentUnit.SyntaxUnitName = SyntaxUsesUnit; //BadNodesInSyntaxTree.Clear(); if (errorsList.Count > 0) { CurrentUnit.syntax_error = errorsList[0] as PascalABCCompiler.Errors.SyntaxError; foreach (Errors.Error er in errorsList) if (er is SyntaxError && (er as SyntaxError).bad_node != null) BadNodesInSyntaxTree[(er as SyntaxError).bad_node] = er; } //if (CurrentUnit.SyntaxTree == null) if (errorsList.Count > 0) { //if (errorsList.Count == 0) // throw new Errors.SyntaxError("Internal parser error: Parser not create syntax tree", UnitName,null,null); throw errorsList[0]; } UnitTable[UnitName] = CurrentUnit; if (UnitTable.Count > 1)//если это не главный модуль if (CurrentUnit.SyntaxTree is SyntaxTree.program_module) throw new UnitModuleExpected(UnitName, CurrentUnit.SyntaxTree.source_context.LeftSourceContext); else if (is_dll(CurrentUnit.SyntaxTree)) throw new UnitModuleExpectedLibraryFound(UnitName, CurrentUnit.SyntaxTree.source_context.LeftSourceContext); //здесь в начало uses добавляем стандартные модули #if DEBUG if (InternalDebug.AddStandartUnits) #endif AddStandartUnitsToUsesSection(CurrentUnit.SyntaxTree); } CurrentSyntaxUnit = SyntaxUsesUnit; CurrentCompilationUnit = CurrentUnit; CurrentUnit.PossibleNamespaces.Clear(); //TODO переделать, слишком сложно, некоторый код дублируется System.Collections.Generic.List<SyntaxTree.unit_or_namespace> SyntaxUsesList; SyntaxUsesList = GetSyntaxInterfaceUsesList(CurrentUnit.SyntaxTree); if (SyntaxUsesList != null) { for (int i = SyntaxUsesList.Count - 1 - CurrentUnit.InterfaceUsedUnits.Count; i >= 0; i--) { if (!IsPossibleNamespace(SyntaxUsesList[i], false)) { compilerOptions.UseDllForSystemUnits = false; break; } } } TreeRealization.unit_node_list References = GetReferences(CurrentUnit); if (SyntaxUsesList != null) { for (int i = SyntaxUsesList.Count - 1 - CurrentUnit.InterfaceUsedUnits.Count; i >= 0; i--) { if (IsPossibleNamespace(SyntaxUsesList[i], true)) { CurrentUnit.InterfaceUsedUnits.AddElement(new TreeRealization.namespace_unit_node(GetNamespace(SyntaxUsesList[i]))); CurrentUnit.PossibleNamespaces.Add(SyntaxUsesList[i]); } else { string CurrentSyntaxUnitName = GetUnitFileName(SyntaxUsesList[i]); CurrentUnit.CurrentUsesUnit = CurrentSyntaxUnitName; if (UnitTable[CurrentSyntaxUnitName] != null) if (UnitTable[CurrentSyntaxUnitName].State == UnitState.BeginCompilation) { string CurrentSyntaxUnitNameCurrentUsesUnit = UnitTable[CurrentSyntaxUnitName].CurrentUsesUnit; if (CurrentSyntaxUnitNameCurrentUsesUnit != null) { //если сначало взали pcu а потом решили его перекомпилировать, поэтому в таблице его нет if (UnitTable[CurrentSyntaxUnitNameCurrentUsesUnit] == null) UnitTable[CurrentSyntaxUnitName].CurrentUsesUnit = FindSourceFileName(Path.GetFileNameWithoutExtension(CurrentSyntaxUnitNameCurrentUsesUnit)); //далее финальная поверка на зацикливание if (UnitTable[CurrentSyntaxUnitName].CurrentUsesUnit != null && UnitTable[UnitTable[CurrentSyntaxUnitName].CurrentUsesUnit].State == UnitState.BeginCompilation) throw new CycleUnitReference(UnitName, SyntaxUsesList[i]); } } CompileUnit(CurrentUnit.InterfaceUsedUnits, SyntaxUsesList[i]); if (CurrentUnit.State == UnitState.Compiled) { Units.AddElement(CurrentUnit.SemanticTree); Units.AddRange(References); return CurrentUnit; } } } } CurrentCompilationUnit = CurrentUnit; CurrentUnit.InterfaceUsedUnits.AddRange(References); AddNamespaces(CurrentUnit.InterfaceUsingNamespaceList, CurrentUnit.PossibleNamespaces, true); AddNamespaces(CurrentUnit.InterfaceUsingNamespaceList, GetInterfaceSyntaxUsingList(CurrentUnit.SyntaxTree)); //Console.WriteLine("Compile Interface "+UnitName);//DEBUG #if DEBUG if (InternalDebug.SemanticAnalysis) #endif { OnChangeCompilerState(this, CompilerState.CompileInterface, UnitName); PascalABCCompiler.TreeConverter.SemanticRules.SymbolTableCaseSensitive = CurrentUnit.CaseSensitive; CurrentUnit.SemanticTree = SyntaxTreeToSemanticTreeConverter.CompileInterface( CurrentUnit.SyntaxTree, CurrentUnit.InterfaceUsedUnits, ErrorsList, Warnings, CurrentUnit.syntax_error, BadNodesInSyntaxTree, CurrentUnit.InterfaceUsingNamespaceList, docs, CompilerOptions.Debug, CompilerOptions.ForDebugging ); CheckErrors(); } TreeRealization.common_unit_node cun = CurrentUnit.SemanticTree as TreeRealization.common_unit_node; /*if (cun != null) { if (!UnitsSortedList.Contains(CurrentUnit))//vnimanie zdes inogda pri silnoj zavisimosti modulej moduli popadajut neskolko raz UnitsSortedList.Add(CurrentUnit); }*/ CurrentUnit.State = UnitState.InterfaceCompiled; if (Units != null) { Units.AddElement(CurrentUnit.SemanticTree); Units.AddRange(References); } SyntaxUsesList = GetSyntaxImplementationUsesList(CurrentUnit.SyntaxTree); CompilationUnit cu = null; bool interfcompile = true; CurrentUnit.ImplementationUsedUnits.clear(); CurrentUnit.PossibleNamespaces.Clear(); if (SyntaxUsesList != null) { for (int i = SyntaxUsesList.Count - 1; i >= 0; i--) if (!IsPossibleNamespace(SyntaxUsesList[i], true)) { cu = UnitTable[GetUnitFileName(SyntaxUsesList[i])]; if (cu != null && cu.State == UnitState.BeginCompilation) { UnitsToCompile.Add(cu); interfcompile = false; #if DEBUG // Console.WriteLine("[DEBUGINFO]Send compile to end " + Path.GetFileName(GetUnitFileName(SyntaxUsesList[i])));//DEBUG #endif } else CompileUnit(CurrentUnit.ImplementationUsedUnits, SyntaxUsesList[i]); } else { CurrentUnit.ImplementationUsedUnits.AddElement(new TreeRealization.namespace_unit_node(GetNamespace(SyntaxUsesList[i]))); CurrentUnit.PossibleNamespaces.Add(SyntaxUsesList[i]); } } CurrentCompilationUnit = CurrentUnit; AddNamespaces(CurrentUnit.ImplementationUsingNamespaceList, CurrentUnit.PossibleNamespaces, true); AddNamespaces(CurrentUnit.ImplementationUsingNamespaceList, GetImplementationSyntaxUsingList(CurrentUnit.SyntaxTree)); if (!interfcompile) { UnitsToCompile.Add(CurrentUnit); if (cun != null) { if (!UnitsSortedList.Contains(CurrentUnit))//vnimanie zdes inogda pri silnoj zavisimosti modulej moduli popadajut neskolko raz UnitsSortedList.Add(CurrentUnit); } //Console.WriteLine("Send compile to end "+UnitName);//DEBUG return CurrentUnit; } //Console.WriteLine("Compile Implementation "+UnitName);//DEBUG if (CurrentUnit.SyntaxTree is SyntaxTree.unit_module) { #if DEBUG if (InternalDebug.SemanticAnalysis) #endif { OnChangeCompilerState(this, CompilerState.CompileImplementation, UnitName); PascalABCCompiler.TreeConverter.SemanticRules.SymbolTableCaseSensitive = CurrentUnit.CaseSensitive; SyntaxTreeToSemanticTreeConverter.CompileImplementation( (PascalABCCompiler.TreeRealization.common_unit_node)CurrentUnit.SemanticTree, CurrentUnit.SyntaxTree, buildImplementationUsesList(CurrentUnit), ErrorsList, Warnings, CurrentUnit.syntax_error, BadNodesInSyntaxTree, CurrentUnit.InterfaceUsingNamespaceList, CurrentUnit.ImplementationUsingNamespaceList, docs, CompilerOptions.Debug, CompilerOptions.ForDebugging ); CheckErrors(); } } CurrentUnit.State = UnitState.Compiled; if (cun != null) { if (!UnitsSortedList.Contains(CurrentUnit))//vnimanie zdes inogda pri silnoj zavisimosti modulej moduli popadajut neskolko raz UnitsSortedList.Add(CurrentUnit); } OnChangeCompilerState(this, CompilerState.EndCompileFile, UnitName); //SavePCU(CurrentUnit, UnitName); CurrentUnit.UnitName = UnitName; return CurrentUnit; /*if(CurrentUnit.State!=UnitState.Compiled) { //Console.WriteLine("Compile Interface "+UnitName);//DEBUG CurrentUnit.SemanticTree=SyntaxTreeToSemanticTreeConverter.CompileInterface(CurrentUnit.SyntaxTree, CurrentUnit.InterfaceUsedUnits,CurrentUnit.syntax_error); CurrentUnit.State=UnitState.InterfaceCompiled; SyntaxUsesList=GetSemanticImplementationUsesList(CurrentUnit.SyntaxTree); if(SyntaxUsesList!=null) for(int i=SyntaxUsesList.Count-1;i>=0;i--) CompileUnit(CurrentUnit.ImplementationUsedUnits,SyntaxUsesList[i]); //Console.WriteLine("Compile Implementation "+UnitName);//DEBUG if (CurrentUnit.SyntaxTree is SyntaxTree.unit_module) { SyntaxTreeToSemanticTreeConverter.CompileImplementation(CurrentUnit.SemanticTree, CurrentUnit.SyntaxTree,CurrentUnit.ImplementationUsedUnits,CurrentUnit.syntax_error); } CurrentUnit.State=UnitState.Compiled; Units.Add(CurrentUnit.SemanticTree); SaveSemanticTreeToFile(CurrentUnit,UnitName); }*/ }
public TreeRealization.unit_node_list GetReferences(CompilationUnit Unit) { //TODO переделать, ConvertDirectives определена дважды и вызывается дважды! TreeRealization.unit_node_list res = new TreeRealization.unit_node_list(); List<TreeRealization.compiler_directive> directives; if (Unit.SemanticTree is TreeRealization.common_unit_node) directives = (Unit.SemanticTree as TreeRealization.common_unit_node).compiler_directives; else directives = ConvertDirectives(Unit.SyntaxTree); if (CompilerOptions.UseDllForSystemUnits) { directives.Add(new TreeRealization.compiler_directive("reference", "PABCRtl.dll", null)); directives.Add(new TreeRealization.compiler_directive("reference", "mscorlib.dll", null)); directives.Add(new TreeRealization.compiler_directive("reference", "System.dll", null)); directives.Add(new TreeRealization.compiler_directive("reference", "System.Core.dll", null)); directives.Add(new TreeRealization.compiler_directive("reference", "System.Numerics.dll", null)); directives.Add(new TreeRealization.compiler_directive("reference", "System.Windows.Forms.dll", null)); directives.Add(new TreeRealization.compiler_directive("reference", "System.Drawing.dll", null)); } foreach (TreeRealization.compiler_directive cd in directives) { if (cd.name.ToLower() == TreeConverter.compiler_string_consts.compiler_directive_reference) { if (string.IsNullOrEmpty(cd.directive)) throw new TreeConverter.SimpleSemanticError(cd.location, "EXPECTED_ASSEMBLY_NAME"); else CompileReference(res, cd); } } if (CompilerOptions.ProjectCompiled) { foreach (ReferenceInfo ri in project.references) { CompileReference(res,new TreeRealization.compiler_directive("reference",ri.full_assembly_name,null)); } } return res; }
public string Compile() { try { //var timer = System.Diagnostics.Stopwatch.StartNew(); ////// if (Path.GetExtension(CompilerOptions.SourceFileName) == ".vb") { return CompileVB(); } if (Path.GetExtension(CompilerOptions.SourceFileName) == ".cs") { return CompileCS(); } OnChangeCompilerState(this, CompilerState.CompilationStarting, CompilerOptions.SourceFileName); Reset(); //Console.WriteLine(timer.ElapsedMilliseconds / 1000.0); ////// if (CompilerOptions.ProjectCompiled) { PrepareCompileOptionsForProject(); } Environment.CurrentDirectory = CompilerOptions.SourceFileDirectory; // нужно для подключения *.inc и *.resources Units = new PascalABCCompiler.TreeRealization.unit_node_list(); CurrentSyntaxUnit = new SyntaxTree.uses_unit_in(new SyntaxTree.string_const(CompilerOptions.SourceFileName)); CompileUnit(Units, CurrentSyntaxUnit); //Console.WriteLine(timer.ElapsedMilliseconds / 1000.0); ////// foreach (CompilationUnit CurrentUnit in UnitsToCompile) if (CurrentUnit.State != UnitState.Compiled) { CurrentCompilationUnit = CurrentUnit; string UnitName = GetUnitFileName(CurrentUnit.SyntaxUnitName); //if(CurrentUnit.State!=UnitState.InterfaceCompiled) //DEBUG //Console.WriteLine("ERROR! interface not compiled "+GetUnitFileName(CurrentUnit.SyntaxUnitName));//DEBUG System.Collections.Generic.List<SyntaxTree.unit_or_namespace> SyntaxUsesList = GetSyntaxImplementationUsesList(CurrentUnit.SyntaxTree); CurrentUnit.PossibleNamespaces.Clear(); if (SyntaxUsesList != null) { for (int i = SyntaxUsesList.Count - 1; i >= 0; i--) if (!IsPossibleNamespace(SyntaxUsesList[i], false)) { compilerOptions.UseDllForSystemUnits = false; break; } for (int i = SyntaxUsesList.Count - 1; i >= 0; i--) if (!IsPossibleNamespace(SyntaxUsesList[i], true)) CompileUnit(CurrentUnit.ImplementationUsedUnits, SyntaxUsesList[i]); else { CurrentUnit.ImplementationUsedUnits.AddElement(new TreeRealization.namespace_unit_node(GetNamespace(SyntaxUsesList[i]))); CurrentUnit.PossibleNamespaces.Add(SyntaxUsesList[i]); } } //Console.WriteLine("Compile Implementation "+UnitName);//DEBUG //TODO: Избавиться от преобразования типа. AddNamespaces(CurrentUnit.ImplementationUsingNamespaceList, CurrentUnit.PossibleNamespaces, true); #if DEBUG if (InternalDebug.SemanticAnalysis) #endif { OnChangeCompilerState(this, CompilerState.CompileImplementation, UnitName); PascalABCCompiler.TreeConverter.SemanticRules.SymbolTableCaseSensitive = CurrentUnit.CaseSensitive; SyntaxTreeToSemanticTreeConverter.CompileImplementation( (PascalABCCompiler.TreeRealization.common_unit_node)CurrentUnit.SemanticTree, CurrentUnit.SyntaxTree, buildImplementationUsesList(CurrentUnit), ErrorsList,Warnings, CurrentUnit.syntax_error, BadNodesInSyntaxTree, CurrentUnit.InterfaceUsingNamespaceList, CurrentUnit.ImplementationUsingNamespaceList, null, CompilerOptions.Debug, CompilerOptions.ForDebugging ); CheckErrors(); } CurrentUnit.State = UnitState.Compiled; OnChangeCompilerState(this, CompilerState.EndCompileFile, UnitName); //SavePCU(CurrentUnit, UnitName); CurrentUnit.UnitName = UnitName; } ClosePCUReadersAndWriters(); if (CompilerOptions.SaveDocumentation) SaveDocumentations(); compilerDirectives = GetCompilerDirectives(UnitsSortedList); TreeRealization.compiler_directive compilerDirective; //TODO сделать это понормальному!!!!! if (compilerDirectives.ContainsKey(TreeConverter.compiler_string_consts.compiler_directive_apptype)) { string directive = compilerDirectives[TreeConverter.compiler_string_consts.compiler_directive_apptype][0].directive; if (string.Compare(directive,"console",true)==0) CompilerOptions.OutputFileType = CompilerOptions.OutputType.ConsoleApplicaton; else if (string.Compare(directive,"windows",true)==0) CompilerOptions.OutputFileType = CompilerOptions.OutputType.WindowsApplication; else if (string.Compare(directive,"dll",true)==0) CompilerOptions.OutputFileType = CompilerOptions.OutputType.ClassLibrary; else if (string.Compare(directive,"pcu",true)==0) CompilerOptions.OutputFileType = CompilerOptions.OutputType.PascalCompiledUnit; } moveSystemUnitToForwardUnitSortedList(); PascalABCCompiler.TreeRealization.common_unit_node system_unit = null; if (UnitsSortedList.Count>0) system_unit = UnitsSortedList[0].SemanticTree as PascalABCCompiler.TreeRealization.common_unit_node; if (system_unit != null) system_unit.IsConsoleApplicationVariable = CompilerOptions.OutputFileType == CompilerOptions.OutputType.ConsoleApplicaton; TreeRealization.program_node pn = null; NETGenerator.CompilerOptions cdo = new NETGenerator.CompilerOptions(); List<TreeRealization.compiler_directive> cds; if (compilerDirectives.TryGetValue(TreeConverter.compiler_string_consts.compiler_directive_platformtarget, out cds)) { string plt = cds[0].directive.ToLower(); if (plt.Equals("x86")) cdo.platformtarget = NETGenerator.CompilerOptions.PlatformTarget.x86; else if (plt.Equals("x64")) cdo.platformtarget = NETGenerator.CompilerOptions.PlatformTarget.x64; else if (plt.Equals("anycpu")) cdo.platformtarget = NETGenerator.CompilerOptions.PlatformTarget.AnyCPU; } if (this.compilerOptions.Only32Bit) cdo.platformtarget = NETGenerator.CompilerOptions.PlatformTarget.x86; if (compilerDirectives.TryGetValue(TreeConverter.compiler_string_consts.product_string, out cds)) { cdo.Product = cds[0].directive; } if (compilerDirectives.TryGetValue(TreeConverter.compiler_string_consts.version_string, out cds)) { cdo.ProductVersion = cds[0].directive; } if (compilerDirectives.TryGetValue(TreeConverter.compiler_string_consts.company_string, out cds)) { cdo.Company = cds[0].directive; } if (compilerDirectives.TryGetValue(TreeConverter.compiler_string_consts.trademark_string, out cds)) { cdo.TradeMark = cds[0].directive; } if (compilerDirectives.TryGetValue(TreeConverter.compiler_string_consts.copyright_string, out cds)) { cdo.Copyright = cds[0].directive; } if (compilerDirectives.TryGetValue(TreeConverter.compiler_string_consts.main_resource_string, out cds)) { cdo.MainResourceFileName = cds[0].directive; if (!File.Exists(cdo.MainResourceFileName)) { ErrorsList.Add(new ResourceFileNotFound(cds[0].directive, cds[0].location)); } } List<string> ResourceFiles = null; if (compilerDirectives.ContainsKey(TreeConverter.compiler_string_consts.compiler_directive_resource)) { ResourceFiles = new List<string>(); List<TreeRealization.compiler_directive> ResourceDirectives = compilerDirectives[TreeConverter.compiler_string_consts.compiler_directive_resource]; foreach (TreeRealization.compiler_directive cd in ResourceDirectives) if (!File.Exists(cd.directive)) { string fileName = Path.Combine(cd.location.doc.file_name, cd.directive); if (File.Exists(fileName)) ResourceFiles.Add(fileName); else ErrorsList.Add(new ResourceFileNotFound(cd.directive, cd.location)); } else ResourceFiles.Add(cd.directive); } string res_file = null; if (project != null) { if (!(project.major_version == 0 && project.minor_version == 0 && project.build_version == 0 && project.revision_version == 0)) cdo.ProductVersion = project.major_version + "." + project.minor_version + "." + project.build_version + "." + project.revision_version; if (!string.IsNullOrEmpty(project.product)) cdo.Product = project.product; if (!string.IsNullOrEmpty(project.company)) cdo.Company = project.company; if (!string.IsNullOrEmpty(project.trademark)) cdo.TradeMark = project.trademark; if (!string.IsNullOrEmpty(project.copyright)) cdo.Copyright = project.copyright; if (!string.IsNullOrEmpty(project.app_icon) && false) { //cdo.MainResourceFileName = project.app_icon; string rc_file = Path.GetFileNameWithoutExtension(project.app_icon) + ".rc"; StreamWriter sw = File.CreateText(rc_file); sw.WriteLine("1 ICON \"" + project.app_icon.Replace("\\", "\\\\") + "\""); if (cdo.NeedDefineVersionInfo) { cdo.NeedDefineVersionInfo = false; sw.WriteLine("1 VERSIONINFO"); string ver = project.major_version + "," + project.minor_version + "," + project.build_version + "," + project.revision_version; sw.WriteLine("FILEVERSION " + ver); /*sw.WriteLine("FILEFLAGSMASK VS_FFI_FILEFLAGSMASK"); sw.WriteLine("FILEFLAGS VER_DEBUG"); sw.WriteLine("FILEOS VOS__WINDOWS32"); if (project.project_type != ProjectType.Library) sw.WriteLine("FILETYPE VFT_APP"); else sw.WriteLine("FILETYPE VFT_DLL"); sw.WriteLine("FILESUBTYPE VFT2_UNKNOWN");*/ sw.WriteLine("BEGIN \r\n BLOCK \"StringFileInfo\"\r\n BEGIN \r\n BLOCK \"041904E3\"\r\nBEGIN"); sw.WriteLine("VALUE \"ProductName\"," + "\"" + cdo.Product + "\""); sw.WriteLine("VALUE \"FileVersion\"," + "\"" + ver + "\""); sw.WriteLine("VALUE \"ProductVersion\"," + "\"" + ver + "\""); sw.WriteLine("VALUE \"FileDescription\"," + "\"" + "" + "\""); sw.WriteLine("VALUE \"OriginalFileName\"," + "\"" + Path.GetFileName(CompilerOptions.OutputFileName) + "\""); sw.WriteLine("VALUE \"InternalName\"," + "\"" + Path.GetFileNameWithoutExtension(CompilerOptions.OutputFileName) + "\""); sw.WriteLine("VALUE \"CompanyName\"," + "\"" + cdo.Company + "\""); sw.WriteLine("VALUE \"LegalTrademarks1\"," + "\"" + cdo.TradeMark + "\""); sw.WriteLine("VALUE \"LegalCopyright\"," + "\"" + cdo.Copyright + "\""); sw.WriteLine("END"); sw.WriteLine("END"); sw.WriteLine("BLOCK \"VarFileInfo\"\r\nBEGIN"); sw.WriteLine("VALUE \"Translation\", 0x0419, 1251"); sw.WriteLine("END"); sw.WriteLine("END"); } sw.Close(); System.Diagnostics.Process prc = new System.Diagnostics.Process(); prc.StartInfo.FileName = Path.Combine(this.CompilerOptions.SystemDirectory, "rc.exe"); prc.StartInfo.Arguments = Path.Combine(Path.GetDirectoryName(project.app_icon), Path.GetFileNameWithoutExtension(project.app_icon) + ".rc"); prc.StartInfo.CreateNoWindow = true; prc.StartInfo.UseShellExecute = false; prc.StartInfo.RedirectStandardOutput = true; prc.StartInfo.RedirectStandardError = true; prc.Start(); prc.WaitForExit(); res_file = Path.Combine(Path.GetDirectoryName(project.app_icon), Path.GetFileNameWithoutExtension(project.app_icon) + ".res"); if (File.Exists(res_file)) { cdo.MainResourceFileName = res_file; } File.Delete(rc_file); } } if (ErrorsList.Count == 0 && compilerOptions.GenerateCode) { cdo.ForRunningWithEnvironment = CompilerOptions.RunWithEnvironment; switch (CompilerOptions.OutputFileType) { case CompilerOptions.OutputType.ClassLibrary: cdo.target = NETGenerator.TargetType.Dll; break; case CompilerOptions.OutputType.ConsoleApplicaton: cdo.target = NETGenerator.TargetType.Exe; break; case CompilerOptions.OutputType.WindowsApplication: cdo.target = NETGenerator.TargetType.WinExe; break; } if (project != null && project.ProjectType == ProjectType.WindowsApp) cdo.target = PascalABCCompiler.NETGenerator.TargetType.WinExe; switch (CompilerOptions.Debug) { case true: cdo.dbg_attrs = NETGenerator.DebugAttributes.Debug; break; case false: cdo.dbg_attrs = NETGenerator.DebugAttributes.Release; break; } if (CompilerOptions.ForDebugging) cdo.dbg_attrs = NETGenerator.DebugAttributes.ForDebbuging; //TODO: Разобратся c location для program_node и правильно передавать main_function. Добавить генератор main_function в SyntaxTreeToSemanticTreeConverter. pn = new PascalABCCompiler.TreeRealization.program_node(null, null); for (int i = 0; i < UnitsSortedList.Count; i++) pn.units.AddElement(UnitsSortedList[i].SemanticTree as TreeRealization.common_unit_node); //(ssyy) Добавил в условие c_module if (FirstCompilationUnit.SyntaxTree is SyntaxTree.program_module || FirstCompilationUnit.SyntaxTree is SyntaxTree.c_module) { if ((cdo.target == NETGenerator.TargetType.Exe) || (cdo.target == NETGenerator.TargetType.WinExe)) { if (UnitsSortedList.Count > 0) { pn.main_function = ((PascalABCCompiler.TreeRealization.common_unit_node)UnitsSortedList[UnitsSortedList.Count - 1].SemanticTree).main_function; /***************************Ivan added*******************************/ if (pn.main_function.function_code.location != null) { bool flag = false; PascalABCCompiler.TreeRealization.common_namespace_node main_ns = pn.main_function.namespace_node; for (int i = 0; i < main_ns.variables.Count; i++) { PascalABCCompiler.TreeRealization.namespace_variable nv = main_ns.variables[i]; if (nv.inital_value != null && nv.inital_value.location != null && !(nv.inital_value is PascalABCCompiler.TreeRealization.constant_node) && !(nv.inital_value is PascalABCCompiler.TreeRealization.record_initializer) && !(nv.inital_value is PascalABCCompiler.TreeRealization.array_initializer)) { varBeginOffset = main_ns.variables[i].inital_value.location.begin_line_num; flag = true; break; } } beginOffset = pn.main_function.function_code.location.begin_line_num; } /*******************************************************************/ Dictionary<string, object> config_dic = new Dictionary<string, object>(); if (CompilerOptions.Locale != null && PascalABCCompiler.StringResourcesLanguage.GetLCIDByTwoLetterISO(CompilerOptions.Locale) != null) { config_dic["locale"] = CompilerOptions.Locale; config_dic["full_locale"] = PascalABCCompiler.StringResourcesLanguage.GetLCIDByTwoLetterISO(CompilerOptions.Locale); } pn.create_main_function(StandarModules.ToArray(), config_dic); } } } else if (FirstCompilationUnit.SyntaxTree is SyntaxTree.unit_module && cdo.target == NETGenerator.TargetType.Dll) { pn.create_main_function_as_in_module(); } pn = semanticTreeConvertersController.Convert(pn) as TreeRealization.program_node; _semantic_tree = pn; if (FirstCompilationUnit.SyntaxTree is SyntaxTree.unit_module && CompilerOptions.OutputFileType != CompilerOptions.OutputType.ClassLibrary) { //если мы комилируем PCU CompilerOptions.OutputFileType = CompilerOptions.OutputType.PascalCompiledUnit; } else { if( CompilerOptions.OutputFileType!= CompilerOptions.OutputType.SemanticTree) #if DEBUG if (InternalDebug.CodeGeneration) #endif { try { File.Create(CompilerOptions.OutputFileName).Close(); //File.Delete(CompilerOptions.OutputFileName); string pdb_file_name=Path.ChangeExtension(CompilerOptions.OutputFileName, ".pdb"); if (File.Exists(pdb_file_name)) File.Delete(pdb_file_name); } catch (Exception) { throw new UnauthorizedAccessToFile(CompilerOptions.OutputFileName); } OnChangeCompilerState(this, CompilerState.CodeGeneration, CompilerOptions.OutputFileName); string[] ResourceFilesArray = null; if (ResourceFiles != null) ResourceFilesArray = ResourceFiles.ToArray(); cds = null; /*if (compilerDirectives.TryGetValue("platform", out cds) && cds[0].directive.ToLower() == "native") { //LLVMCodeGeneratorsController.Compile(pn, CompilerOptions.OutputFileName, CompilerOptions.SourceFileName, ResourceFilesArray); PABCToCppCodeGeneratorsController.Compile(pn, CompilerOptions.OutputFileName, CompilerOptions.SourceFileName, ResourceFilesArray); } else*/ CodeGeneratorsController.Compile(pn, CompilerOptions.OutputFileName, CompilerOptions.SourceFileName, cdo, CompilerOptions.StandartDirectories, ResourceFilesArray); if (res_file != null) File.Delete(res_file); } } } } catch (TreeConverter.ParserError err) { //конвертор уткнулся в ошибку. ничего не делаем } catch (Errors.CompilerInternalError err) { if (ErrorsList.Count == 0) ErrorsList.Add(err); else { #if DEBUG if (!InternalDebug.SkipInternalErrorsIfSyntaxTreeIsCorrupt) ErrorsList.Add(err); #endif } } catch (Errors.Error err) { if (ErrorsList.Count == 0) ErrorsList.Add(err); else if (err != ErrorsList[0]) { if (err is SemanticError) { int pos = ErrorsList.Count; SourceLocation loc = (err as SemanticError).SourceLocation, loctmp; if (loc != null) for (int i = 0; i < ErrorsList.Count; i++) if (ErrorsList[i] is LocatedError) if ((loctmp = (ErrorsList[i] as LocatedError).SourceLocation) != null) if (loctmp > loc) { pos = i; break; } ErrorsList.Insert(pos, err); } else ErrorsList.Add(err); } } catch (Exception err) { string fn = "Compiler"; if (CurrentCompilationUnit != null && this.CurrentCompilationUnit.SyntaxTree != null) fn = Path.GetFileName(this.CurrentCompilationUnit.SyntaxTree.file_name); Errors.CompilerInternalError comp_err = new Errors.CompilerInternalError(string.Format("Compiler.Compile[{0}]", fn), err); if (ErrorsList.Count == 0) ErrorsList.Add(comp_err); else { #if DEBUG if (!InternalDebug.SkipInternalErrorsIfSyntaxTreeIsCorrupt) ErrorsList.Add(comp_err); #endif } } //удаляем лишние ошибки /*foreach(Error er in errorsList) { }*/ //на случай если мы вывалились по исключению но у нас есть откомпилированные модули try { ClosePCUReadersAndWriters(); } catch (Exception e) { ErrorsList.Add(new Errors.CompilerInternalError("Compiler.ClosePCUReadersAndWriters", e)); } bool need_recompiled = false; if (ErrorsList.Count > 0) { if (compilerOptions.UseDllForSystemUnits && !has_only_syntax_errors(ErrorsList) && compilerOptions.IgnoreRtlErrors) { compilerOptions.UseDllForSystemUnits = false; ErrorsList.Clear(); need_recompiled = true; } } OnChangeCompilerState(this, CompilerState.CompilationFinished, CompilerOptions.SourceFileName); if (ClearAfterCompilation) ClearAll(); OnChangeCompilerState(this, CompilerState.Ready, null); if (ErrorsList.Count > 0) { return null; } else if (need_recompiled) { //Compiler c = new Compiler(sourceFilesProvider,OnChangeCompilerState); //return c.Compile(this.compilerOptions); return Compile(); } else return CompilerOptions.OutputFileName; }
internal void Reset() { Warnings.Clear(); errorsList.Clear(); //if (!File.Exists(CompilerOptions.SourceFileName)) throw new SourceFileNotFound(CompilerOptions.SourceFileName); CurrentCompilationUnit = null; FirstCompilationUnit = null; linesCompiled = 0; PCUReadersAndWritersClosed = false; ParsersController.Reset(); SyntaxTreeToSemanticTreeConverter.Reset(); CodeGeneratorsController.Reset(); //PABCToCppCodeGeneratorsController.Reset(); UnitsToCompile.Clear(); DLLCashe.Clear(); project = null; }
private Hashtable GetCompilerDirectives(CompilationUnit Unit) { Hashtable Directives = new Hashtable(StringComparer.CurrentCultureIgnoreCase); TreeRealization.common_unit_node cun = Unit.SemanticTree as TreeRealization.common_unit_node; if (cun != null) foreach (TreeRealization.compiler_directive cd in cun.compiler_directives) Directives[cd.name] = cd; return Directives; }