Перемещение модулей SPython в Lib\SPython (#3371)

* Replace languageCaseSensitive by languageName data in PCU and caseSensitive parameters in Compiler functions

* Implement SearchDirectories filling in Compiler and move SPython standard modules to their new directory

* Implement search using current language extension first in Compiler

* Delete LibForVB folder and update TestRunner to support different Lib dirs

* Update installer scripts to create separate Lib folder for SPython

* Take into account Lib dirs not found

* Delete supportedSourceFiles variable in Compiler

* Delete unused functions from LanguageIntegrator
This commit is contained in:
Александр Земляк 2026-01-13 08:20:13 +03:00 committed by GitHub
parent d7a81d312c
commit 51e4ae050a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
33 changed files with 224 additions and 9949 deletions

View file

@ -9,6 +9,7 @@ using PascalABCCompiler.Parsers;
using PascalABCCompiler.Errors;
using System.IO;
using Languages.Facade;
using System.Linq;
namespace CodeCompletion
{
@ -280,17 +281,28 @@ namespace CodeCompletion
}
const string LibSourceDirectoryIdent = "%LIBSOURCEDIRECTORY%";
public static string FindSourceFileName(string unit_name, out int found_dir_ind, bool caseSensitiveSearch, params string[] ddirs)
public static string FindSourceFileName(string unit_name, out int found_dir_ind, ILanguage currentUnitLanguage, params string[] ddirs)
{
// TODO: check error in older version
List<string> Dirs = new List<string>();
Dirs.AddRange(ddirs);
if (CodeCompletionController.comp != null)
Dirs.AddRange(CodeCompletionController.comp.CompilerOptions.SearchDirectories);
Dirs.AddRange(CodeCompletionController.comp.GetCurrentSearchDirectories(currentUnitLanguage));
// Надо как-то проверять, что мы не в инсталированной версии EVA
if (CodeCompletionController.StandartDirectories.ContainsKey(LibSourceDirectoryIdent) && Directory.Exists(CodeCompletionController.StandartDirectories[LibSourceDirectoryIdent]))
Dirs.Add(CodeCompletionController.StandartDirectories[LibSourceDirectoryIdent]);
return CodeCompletionController.comp.FindSourceFileNameInDirs(unit_name, out found_dir_ind, caseSensitiveSearch, Dirs.ToArray());
Dirs.AddRange(GetLibSourceDirectories(currentUnitLanguage));
return CodeCompletionController.comp.FindSourceFileNameInDirs(unit_name, out found_dir_ind, currentUnitLanguage, Dirs.ToArray());
}
private static string[] GetLibSourceDirectories(ILanguage currentUnitLanguage)
{
return LanguageProvider.Instance.Languages
.Where(lang => lang == currentUnitLanguage)
.Concat(LanguageProvider.Instance.Languages.Where(lang => lang != currentUnitLanguage))
.Select(lang => Path.Combine(CodeCompletionController.StandartDirectories[LibSourceDirectoryIdent],
lang.Name.Replace(PascalABCCompiler.StringConstants.pascalLanguageName, ""))) // для PascalABC.NET прямо в LibSource, остальные во внутренних папках
.Where(dir => Directory.Exists(dir))
.ToArray();
}
public static CodeCompletionNameHelper Helper

View file

@ -79,6 +79,7 @@ namespace CodeCompletion
pcu_file.Version = br.ReadInt16();
pcu_file.Revision = br.ReadInt32();
pcu_file.CRC = br.ReadInt64();
pcu_file.UseRtlDll = br.ReadBoolean();
pcu_file.IncludeDebugInfo = br.ReadBoolean();
return true;
}
@ -108,7 +109,10 @@ namespace CodeCompletion
pcu_file.SourceFileName = br.ReadString();
else
pcu_file.SourceFileName = Path.GetFileNameWithoutExtension(FileName);
int num_names = br.ReadInt32();
pcu_file.languageName = br.ReadString();
int num_names = br.ReadInt32();
pcu_file.names = new NameRef[num_names];
for (int i=0; i<num_names; i++)
{
@ -116,6 +120,7 @@ namespace CodeCompletion
pcu_file.names[i].offset = br.ReadInt32();
pcu_file.names[i].symbol_kind = (symbol_kind)br.ReadByte();
pcu_file.names[i].special_scope = br.ReadByte();
pcu_file.names[i].always_restore = br.ReadBoolean();
}
//ssyy
num_names = br.ReadInt32();
@ -126,6 +131,7 @@ namespace CodeCompletion
pcu_file.implementation_names[i].offset = br.ReadInt32();
pcu_file.implementation_names[i].symbol_kind = (symbol_kind)br.ReadByte();
pcu_file.implementation_names[i].special_scope = br.ReadByte();
pcu_file.implementation_names[i].always_restore = br.ReadBoolean();
}
//\ssyy
int num_incl = br.ReadInt32();

View file

@ -1,5 +1,6 @@
// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using Languages.Facade;
using PascalABCCompiler;
using PascalABCCompiler.Parsers;
using PascalABCCompiler.SyntaxTree;
@ -2698,14 +2699,14 @@ namespace CodeCompletion
{
unit_or_namespace s = _interface_node.uses_modules.units[j];
CompileUsedUnitOrNamespace(s, Path.GetDirectoryName(_unit_module.file_name),
cur_scope, ns_cache, unl, currentUnitLanguage.CaseSensitive);
cur_scope, ns_cache, unl, currentUnitLanguage);
}
}
// компиляция зависимостей из конструкций import и from import
if (cur_scope != null && _unit_module.initialization_part != null)
{
CompileImportedDependencies(_unit_module.initialization_part, _unit_module.file_name, ns_cache, usedUnitsNames, currentUnitLanguage.CaseSensitive);
CompileImportedDependencies(_unit_module.initialization_part, _unit_module.file_name, ns_cache, usedUnitsNames, currentUnitLanguage);
}
StringComparer comparer = currentUnitLanguage.CaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase;
@ -2716,7 +2717,7 @@ namespace CodeCompletion
// Добавление всех стандартных модулей EVA
foreach (var standardUnitName in currentUnitLanguage.SystemUnitNames.Except(usedUnitsNames, comparer))
{
AddStandardUnit(standardUnitName, currentUnitLanguage.CaseSensitive, currentUnitLanguage.LanguageInformation.AddStandardUnitNamesToUserScope);
AddStandardUnit(standardUnitName, currentUnitLanguage);
}
}
@ -2853,14 +2854,14 @@ namespace CodeCompletion
PascalABCCompiler.TreeRealization.using_namespace_list unl = new PascalABCCompiler.TreeRealization.using_namespace_list();
public SymScope cur_scope;
public static string FindPCUFileName(string UnitName, string curr_path, bool caseSensitiveSearch)
public static string FindPCUFileName(string UnitName, string curr_path, Languages.Facade.ILanguage currentUnitLanguage)
{
return CodeCompletionController.comp.FindPCUFileName(UnitName, curr_path, out _, caseSensitiveSearch);
return CodeCompletionController.comp.FindPCUFileName(UnitName, curr_path, out _, currentUnitLanguage);
}
private void AddStandardUnit(string unitName, bool caseSensitiveSearch, bool addStandardUnitNameToCurrentScope)
private void AddStandardUnit(string unitName, Languages.Facade.ILanguage currentUnitLanguage)
{
string unitPath = CodeCompletionNameHelper.FindSourceFileName(unitName, out _, caseSensitiveSearch);
string unitPath = CodeCompletionNameHelper.FindSourceFileName(unitName, out _, currentUnitLanguage);
if (unitPath != null)
{
DomConverter dc = CodeCompletionController.comp_modules[unitPath] as DomConverter;
@ -2880,7 +2881,7 @@ namespace CodeCompletion
//get_standart_types(dc.stv);
// для SPython, например, не нужно подсказывать стандартные модули в программе, это условие для этого EVA
if (addStandardUnitNameToCurrentScope)
if (currentUnitLanguage.LanguageInformation.AddStandardUnitNamesToUserScope)
{
entry_scope.AddName(unitName, dc.visitor.entry_scope);
}
@ -2898,7 +2899,7 @@ namespace CodeCompletion
dc.visitor.entry_scope.InitAssemblies();
entry_scope.AddUsedUnit(dc.visitor.entry_scope);
//get_standart_types(dc.stv);
if (addStandardUnitNameToCurrentScope)
if (currentUnitLanguage.LanguageInformation.AddStandardUnitNamesToUserScope)
{
entry_scope.AddName(unitName, dc.visitor.entry_scope);
}
@ -2907,14 +2908,14 @@ namespace CodeCompletion
}
private void CompileUsedUnitOrNamespace(unit_or_namespace s, string curr_path,
SymScope cur_scope, Hashtable ns_cache, using_namespace_list unl, bool caseSensitiveSearch)
SymScope cur_scope, Hashtable ns_cache, using_namespace_list unl, Languages.Facade.ILanguage currentUnitLanguage)
{
try
{
if (s is uses_unit_in uui)
{
string unit_name = CodeCompletionNameHelper.FindSourceFileName(uui.in_file.Value, out _, caseSensitiveSearch, curr_path);
string unit_name = CodeCompletionNameHelper.FindSourceFileName(uui.in_file.Value, out _, currentUnitLanguage, curr_path);
if (unit_name == null) throw new InvalidOperationException($"uses '{uui.in_file.Value}';");
CompileUnit(unit_name, cur_scope);
@ -2930,8 +2931,8 @@ namespace CodeCompletion
// на случай имен модулей, отличающихся от имен файла EVA
string realName = GetRealNameForModule(usedName);
string pcu_unit_name = FindPCUFileName(realName, curr_path, caseSensitiveSearch);
string unit_name = CodeCompletionNameHelper.FindSourceFileName(realName, out _, caseSensitiveSearch, curr_path);
string pcu_unit_name = FindPCUFileName(realName, curr_path, currentUnitLanguage);
string unit_name = CodeCompletionNameHelper.FindSourceFileName(realName, out _, currentUnitLanguage, curr_path);
/*if (pcu_unit_name != null && unit_name != null && string.Compare(System.IO.Path.GetDirectoryName(_program_module.file_name), System.IO.Path.GetDirectoryName(pcu_unit_name), true) == 0
&& string.Compare(System.IO.Path.GetDirectoryName(_program_module.file_name), System.IO.Path.GetDirectoryName(unit_name), true) != 0)
@ -3032,15 +3033,15 @@ namespace CodeCompletion
}
private void CompileImportedUnit(string importedName, statement importStatement, as_statement_list asStatementsList, string curr_path,
SymScope cur_scope, using_namespace_list unl, bool caseSensitiveSearch)
SymScope cur_scope, using_namespace_list unl, ILanguage currentUnitLanguage)
{
try
{
// на случай имен модулей, отличающихся от имен файла EVA
string realName = GetRealNameForModule(importedName);
string pcu_unit_name = FindPCUFileName(realName, curr_path, caseSensitiveSearch);
string unit_name = CodeCompletionNameHelper.FindSourceFileName(realName, out _, caseSensitiveSearch, curr_path);
string pcu_unit_name = FindPCUFileName(realName, curr_path, currentUnitLanguage);
string unit_name = CodeCompletionNameHelper.FindSourceFileName(realName, out _, currentUnitLanguage, curr_path);
if (unit_name != null)
{
@ -3273,14 +3274,14 @@ namespace CodeCompletion
{
unit_or_namespace s = _program_module.used_units.units[j];
CompileUsedUnitOrNamespace(s, Path.GetDirectoryName(_program_module.file_name),
cur_scope, ns_cache, unl, currentUnitLanguage.CaseSensitive);
cur_scope, ns_cache, unl, currentUnitLanguage);
}
}
// компиляция зависимостей из конструкций import и from import
if (cur_scope != null && _program_module.program_block.program_code != null)
{
CompileImportedDependencies(_program_module.program_block.program_code, _program_module.file_name, ns_cache, usedUnitsNames, currentUnitLanguage.CaseSensitive);
CompileImportedDependencies(_program_module.program_block.program_code, _program_module.file_name, ns_cache, usedUnitsNames, currentUnitLanguage);
}
StringComparer comparer = currentUnitLanguage.CaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase;
@ -3288,7 +3289,7 @@ namespace CodeCompletion
// Добавление всех стандартных модулей EVA
foreach (var unitName in currentUnitLanguage.SystemUnitNames.Except(usedUnitsNames, comparer))
{
AddStandardUnit(unitName, currentUnitLanguage.CaseSensitive, currentUnitLanguage.LanguageInformation.AddStandardUnitNamesToUserScope);
AddStandardUnit(unitName, currentUnitLanguage);
}
foreach (string s in namespaces)
@ -3350,7 +3351,7 @@ namespace CodeCompletion
}
}
private void CompileImportedDependencies(statement_list statementList, string fileName, Hashtable ns_cache, List<string> usedUnitNames, bool caseSensitiveSearch)
private void CompileImportedDependencies(statement_list statementList, string fileName, Hashtable ns_cache, List<string> usedUnitNames, Languages.Facade.ILanguage currentUnitLanguage)
{
var importStatements = statementList.list.Where(st => st is import_statement || st is from_import_statement);
@ -3362,7 +3363,7 @@ namespace CodeCompletion
{
CompileImportedUnit(unitNode.name, import, import.modules_names,
Path.GetDirectoryName(fileName),
cur_scope, unl, caseSensitiveSearch);
cur_scope, unl, currentUnitLanguage);
usedUnitNames.Add(unitNode.name);
}
@ -3371,7 +3372,7 @@ namespace CodeCompletion
{
CompileImportedUnit(fromImport.module_name.name, fromImport, fromImport.imported_names,
Path.GetDirectoryName(fileName),
cur_scope, unl, caseSensitiveSearch);
cur_scope, unl, currentUnitLanguage);
usedUnitNames.Add(fromImport.module_name.name);
}
@ -5063,7 +5064,7 @@ namespace CodeCompletion
{
unit_or_namespace s = _implementation_node.uses_modules.units[j];
CompileUsedUnitOrNamespace(s, Path.GetDirectoryName(this.cur_unit_file_name),
cur_scope, ns_cache, unl, currentLanguage.CaseSensitive);
cur_scope, ns_cache, unl, currentLanguage);
}
}
impl_scope = cur_scope;

View file

@ -363,8 +363,6 @@ namespace PascalABCCompiler
}
}
public string[] ParserSearchPaths;
// LeftToAll - слева во все модули, RightToMain - справа, только в основную программу
public enum StandardModuleAddMethod { LeftToAll, RightToMain };
@ -458,8 +456,7 @@ namespace PascalABCCompiler
{ "%PABCSYSTEM%", SystemDirectory }
};
ParserSearchPaths = new string[] { Path.Combine(SystemDirectory, "Lib") };
SearchDirectories = ParserSearchPaths.ToList();
SearchDirectories = new List<string>();
}
@ -634,10 +631,6 @@ namespace PascalABCCompiler
get { return state; }
}
private void SetSupportedSourceFiles()
{
supportedSourceFiles = LanguageProvider.Languages.Select(language => SupportedSourceFile.Make(language)).ToArray();
}
private void SetSupportedProjectFiles()
{
@ -645,13 +638,6 @@ namespace PascalABCCompiler
supportedProjectFiles = new SupportedSourceFile[] { new SupportedSourceFile(new string[1] { ".pabcproj" }, "PascalABC.NET") };
}
private SupportedSourceFile[] supportedSourceFiles = null;
public SupportedSourceFile[] SupportedSourceFiles
{
get { return supportedSourceFiles; }
set { supportedSourceFiles = value; }
}
private SupportedSourceFile[] supportedProjectFiles = null;
public SupportedSourceFile[] SupportedProjectFiles
{
@ -805,7 +791,6 @@ namespace PascalABCCompiler
if (ChangeCompilerState != null)
OnChangeCompilerState += ChangeCompilerState;
supportedSourceFiles = comp.SupportedSourceFiles;
supportedProjectFiles = comp.SupportedProjectFiles;
// 29.07.2024 EVA
@ -842,7 +827,6 @@ namespace PascalABCCompiler
SyntaxTreeToSemanticTreeConverter = new TreeConverter.SyntaxTreeToSemanticTreeConverter();
CodeGeneratorsController = new CodeGenerators.Controller();
SetSupportedSourceFiles();
SetSupportedProjectFiles();
semanticTreeConvertersController = new SemanticTreeConvertersController(this);
@ -1133,14 +1117,14 @@ namespace PascalABCCompiler
if (implementationUsesList != null)
{
SetUseDLLForSystemUnits(Path.GetDirectoryName(unitFileName), implementationUsesList, implementationUsesList.Count - 1, CurrentUnit.Language.CaseSensitive);
SetUseDLLForSystemUnits(Path.GetDirectoryName(unitFileName), implementationUsesList, implementationUsesList.Count - 1, CurrentUnit.Language);
for (int i = implementationUsesList.Count - 1; i >= 0; i--)
{
if (!IsPossibleNetNamespaceOrStandardPasFile(implementationUsesList[i], true, Path.GetDirectoryName(unitFileName), CurrentUnit.Language.CaseSensitive))
if (!IsPossibleNetNamespaceOrStandardPasFile(implementationUsesList[i], true, Path.GetDirectoryName(unitFileName), CurrentUnit.Language))
{
// докомпилируем юнит, если он не является пространством имен или стандартным pas файлом из Lib
CompileUnit(CurrentUnit.ImplementationUsedUnits, CurrentUnit.ImplementationUsedDirectUnits, implementationUsesList[i], Path.GetDirectoryName(unitFileName), CurrentUnit.Language.CaseSensitive);
CompileUnit(CurrentUnit.ImplementationUsedUnits, CurrentUnit.ImplementationUsedDirectUnits, implementationUsesList[i], Path.GetDirectoryName(unitFileName), CurrentUnit.Language);
}
else
{
@ -1946,7 +1930,7 @@ namespace PascalABCCompiler
return usesSection;
}
public string FindPCUFileName(string fileName, string currentPath, out int folderPriority, bool caseSensitiveSearch)
public string FindPCUFileName(string fileName, string currentPath, out int folderPriority, ILanguage currentUnitLanguage)
{
if (string.IsNullOrEmpty(Path.GetExtension(fileName)))
fileName += CompilerOptions.CompiledUnitExtension;
@ -1958,11 +1942,12 @@ namespace PascalABCCompiler
if (Path.GetExtension(fileName) != CompilerOptions.CompiledUnitExtension)
fileNameWithPriority = null;
else if (FindFileWithExtensionInDirs(fileName, out _, caseSensitiveSearch, currentPath) is string resultFileName1)
else if (FindFileWithExtensionInDirs(fileName, out _, currentUnitLanguage, currentPath) is string resultFileName1)
fileNameWithPriority = Tuple.Create(resultFileName1, 1);
else if (CompilerOptions.OutputDirectory != CompilerOptions.SourceFileDirectory && FindFileWithExtensionInDirs(Path.GetFileName(fileName), out _, caseSensitiveSearch, CompilerOptions.OutputDirectory) is string resultFileName2)
else if (CompilerOptions.OutputDirectory != CompilerOptions.SourceFileDirectory && FindFileWithExtensionInDirs(Path.GetFileName(fileName), out _, currentUnitLanguage, CompilerOptions.OutputDirectory) is string resultFileName2)
fileNameWithPriority = Tuple.Create(resultFileName2, 2);
else if (FindFileWithExtensionInDirs(fileName, out var dirIndex, caseSensitiveSearch, CompilerOptions.SearchDirectories.ToArray()) is string resultFileName3)
else if (FindFileWithExtensionInDirs(
fileName, out var dirIndex, currentUnitLanguage, GetCurrentSearchDirectories(currentUnitLanguage)) is string resultFileName3)
fileNameWithPriority = Tuple.Create(resultFileName3, 3 + dirIndex);
else
fileNameWithPriority = null;
@ -1974,16 +1959,28 @@ namespace PascalABCCompiler
return fileNameWithPriority?.Item1;
}
public string FindSourceFileName(string fileName, string currentPath, out int folderPriority, bool caseSensitiveSearch)
public string[] GetCurrentSearchDirectories(ILanguage currentUnitLanguage)
{
var libDirs = LanguageProvider.Languages
.Where(lang => lang == currentUnitLanguage)
.Concat(LanguageProvider.Languages.Where(lang => lang != currentUnitLanguage))
.Select(lang => Path.Combine(CompilerOptions.SystemDirectory, "Lib",
lang.Name.Replace(StringConstants.pascalLanguageName, ""))) // для PascalABC.NET прямо в Lib, остальные во внутренних папках
.Where(dir => Directory.Exists(dir));
return CompilerOptions.SearchDirectories.Concat(libDirs).ToArray();
}
public string FindSourceFileName(string fileName, string currentPath, out int folderPriority, ILanguage currentUnitLanguage)
{
var cacheKey = Tuple.Create(fileName.ToLower(), currentPath?.ToLower());
if (!SourceFileNamesDictionary.TryGetValue(cacheKey, out var fileNameWithPriority))
{
if (FindSourceFileNameInDirs(fileName, out _, caseSensitiveSearch, currentPath) is string resultFileName1)
if (FindSourceFileNameInDirs(fileName, out _, currentUnitLanguage, currentPath) is string resultFileName1)
fileNameWithPriority = Tuple.Create(resultFileName1, 1);
else if (FindSourceFileNameInDirs(fileName, out var dirIndex, caseSensitiveSearch, CompilerOptions.SearchDirectories.ToArray()) is string resultFileName2)
else if (FindSourceFileNameInDirs(fileName, out var dirIndex, currentUnitLanguage, GetCurrentSearchDirectories(currentUnitLanguage)) is string resultFileName2)
fileNameWithPriority = Tuple.Create(resultFileName2, 3 + dirIndex);
else
fileNameWithPriority = null;
@ -1995,26 +1992,24 @@ namespace PascalABCCompiler
return fileNameWithPriority?.Item1;
}
public string FindSourceFileNameInDirs(string fileName, out int foundDirIndex, bool caseSensitiveSearch, params string[] Dirs)
public string FindSourceFileNameInDirs(string fileName, out int foundDirIndex, ILanguage currentUnitLanguage, params string[] Dirs)
{
var fileNameExtension = Path.GetExtension(fileName);
var isExtensionEmpty = string.IsNullOrEmpty(fileNameExtension);
// TODO: ищем сперва для расширения текущего языка EVA
foreach (SupportedSourceFile sf in SupportedSourceFiles)
// Ищем сначала по расширениям текущего языка, потом по всем остальным
foreach (ILanguage lang in new ILanguage[] { currentUnitLanguage }.Concat(LanguageProvider.Languages.Where(l => l != currentUnitLanguage)))
{
foreach (string extension in sf.Extensions)
foreach (string extension in lang.FilesExtensions)
{
if (isExtensionEmpty || fileNameExtension == extension)
{
var resultFileName = FindFileWithExtensionInDirs(isExtensionEmpty ? fileName + extension : fileName, out foundDirIndex, caseSensitiveSearch, Dirs);
var resultFileName = FindFileWithExtensionInDirs(isExtensionEmpty ? fileName + extension : fileName, out foundDirIndex, currentUnitLanguage, Dirs);
if (resultFileName != null)
return resultFileName;
}
}
}
}
foundDirIndex = 0;
return null;
@ -2082,13 +2077,13 @@ namespace PascalABCCompiler
throw new InvalidOperationException($"Could not find path to \"{u2.UnitFileName}\" relative to \"{u1.UnitFileName}\"");
}
private string FindFileWithExtensionInDirs(string fileName, out int foundDirIndex, bool caseSensitiveSearch, params string[] dirs)
private string FindFileWithExtensionInDirs(string fileName, out int foundDirIndex, ILanguage currentUnitLanguage, params string[] dirs)
{
if (Path.IsPathRooted(fileName))
{
foundDirIndex = 0;
if (caseSensitiveSearch)
if (currentUnitLanguage.CaseSensitive)
{
var foundFileName = Directory.GetFiles(Path.GetDirectoryName(fileName), Path.GetFileName(fileName), SearchOption.TopDirectoryOnly)
.FirstOrDefault(f => f == fileName);
@ -2106,7 +2101,7 @@ namespace PascalABCCompiler
var dir = dirs[dirIndex];
var fullFileName = Path.Combine(dir, fileName);
if (caseSensitiveSearch)
if (currentUnitLanguage.CaseSensitive)
{
var foundFileName = Directory.GetFiles(dir, fileName, SearchOption.TopDirectoryOnly)
.FirstOrDefault(f => f == fullFileName);
@ -2202,7 +2197,7 @@ namespace PascalABCCompiler
}
public string GetUnitFileName(SyntaxTree.unit_or_namespace unitNode, string currentPath, bool caseSensitiveSearch)
public string GetUnitFileName(SyntaxTree.unit_or_namespace unitNode, string currentPath, ILanguage currentUnitLanguage)
{
if (unitNode is SyntaxTree.uses_unit_in unitNodeCasted && unitNodeCasted.name == null)
return unitNodeCasted.in_file.Value;
@ -2221,10 +2216,10 @@ namespace PascalABCCompiler
}
return GetUnitFileName(unitName, unitNode.UsesPath(), currentPath, unitNode.source_context, caseSensitiveSearch);
return GetUnitFileName(unitName, unitNode.UsesPath(), currentPath, unitNode.source_context, currentUnitLanguage);
}
public string GetUnitFileName(string unitName, string usesPath, string currentPath, SyntaxTree.SourceContext sourceContext, bool caseSensitiveSearch)
public string GetUnitFileName(string unitName, string usesPath, string currentPath, SyntaxTree.SourceContext sourceContext, ILanguage currentUnitLanguage)
{
var cacheKey = Tuple.Create(usesPath.ToLower(), currentPath?.ToLower());
@ -2232,7 +2227,7 @@ namespace PascalABCCompiler
if (GetUnitFileNameCache.TryGetValue(cacheKey, out var unitPaths))
{
if (caseSensitiveSearch)
if (currentUnitLanguage.CaseSensitive)
{
foreach (var unitPath in unitPaths)
{
@ -2249,8 +2244,8 @@ namespace PascalABCCompiler
}
// число приоритета меньше означает, что папка более важная
var sourceFileName = FindSourceFileName(usesPath, currentPath, out var sourceFilePriority, caseSensitiveSearch);
var pcuFileName = FindPCUFileName(usesPath, currentPath, out var pcuFilePriority, caseSensitiveSearch);
var sourceFileName = FindSourceFileName(usesPath, currentPath, out var sourceFilePriority, currentUnitLanguage);
var pcuFileName = FindPCUFileName(usesPath, currentPath, out var pcuFilePriority, currentUnitLanguage);
bool sourceFileExists = sourceFileName != null;
bool pcuFileExists = pcuFileName != null;
@ -2455,7 +2450,7 @@ namespace PascalABCCompiler
namespaces[unitModule.unit_name.idunit_name.name] = namespaceNode;
}
AddDeclarationsAndReferencedUnitsToNamespaces(namespaceModules, file, unitModule, namespaceNode, compilationUnit.Language.CaseSensitive);
AddDeclarationsAndReferencedUnitsToNamespaces(namespaceModules, file, unitModule, namespaceNode, compilationUnit.Language);
}
// корневой модуль является чем-то одним из этого
@ -2511,7 +2506,7 @@ namespace PascalABCCompiler
}
private void AddDeclarationsAndReferencedUnitsToNamespaces(List<SyntaxTree.unit_or_namespace> namespace_modules, string file,
SyntaxTree.unit_module unitModule, SyntaxTree.syntax_namespace_node namespaceNode, bool caseSensitive)
SyntaxTree.unit_module unitModule, SyntaxTree.syntax_namespace_node namespaceNode, ILanguage currentUnitLanguage)
{
if (unitModule.interface_part.interface_definitions != null)
{
@ -2524,7 +2519,7 @@ namespace PascalABCCompiler
CheckForDuplicatesInUsesSection(unitModule.interface_part.uses_modules.units);
foreach (SyntaxTree.unit_or_namespace name_space in unitModule.interface_part.uses_modules.units)
{
if (IsPossibleNetNamespaceOrStandardPasFile(name_space, false, Path.GetDirectoryName(file), caseSensitive))
if (IsPossibleNetNamespaceOrStandardPasFile(name_space, false, Path.GetDirectoryName(file), currentUnitLanguage))
{
namespaceNode.referenced_units.AddElement(new namespace_unit_node(GetNamespace(name_space), GetLocationFromTreenode(name_space, unitModule.file_name)), null);
}
@ -2752,7 +2747,7 @@ namespace PascalABCCompiler
NetHelper.AssemblyResolveScope assemblyResolveScope;
private bool IsPossibleNetNamespaceOrStandardPasFile(SyntaxTree.unit_or_namespace name_space, bool addToStandardModules, string currentPath, bool caseSensitiveSearch)
private bool IsPossibleNetNamespaceOrStandardPasFile(SyntaxTree.unit_or_namespace name_space, bool addToStandardModules, string currentPath, ILanguage currentUnitLanguage)
{
if (name_space is SyntaxTree.uses_unit_in)
return false;
@ -2761,8 +2756,8 @@ namespace PascalABCCompiler
if (name_space.name.idents.Count > 1)
return true;
string sourceFileName = FindSourceFileName(name_space.name.idents[0].name, currentPath, out _, caseSensitiveSearch);
string pcuFileName = FindPCUFileName(name_space.name.idents[0].name, currentPath, out _, caseSensitiveSearch);
string sourceFileName = FindSourceFileName(name_space.name.idents[0].name, currentPath, out _, currentUnitLanguage);
string pcuFileName = FindPCUFileName(name_space.name.idents[0].name, currentPath, out _, currentUnitLanguage);
// если нет исходников и pcu
if (sourceFileName == null && pcuFileName == null)
@ -2951,9 +2946,9 @@ namespace PascalABCCompiler
/// <param name="currentUnitNode">Синтаксический узел текущего модуля (или пространства имен)</param>
/// <param name="previousPath">Директория родительского модуля</param>
/// <returns>Скомпилированный юнит</returns>
public CompilationUnit CompileUnit(unit_node_list unitsFromUsesSection, Dictionary<unit_node, CompilationUnit> directUnitsFromUsesSection, SyntaxTree.unit_or_namespace currentUnitNode, string previousPath, bool caseSensitiveSearch = false)
public CompilationUnit CompileUnit(unit_node_list unitsFromUsesSection, Dictionary<unit_node, CompilationUnit> directUnitsFromUsesSection, SyntaxTree.unit_or_namespace currentUnitNode, string previousPath, ILanguage previousUnitLanguage = null)
{
string unitFileName = GetUnitFileName(currentUnitNode, previousPath, caseSensitiveSearch);
string unitFileName = GetUnitFileName(currentUnitNode, previousPath, previousUnitLanguage);
string unitId = Path.ChangeExtension(unitFileName, null);
// Имя папки, в которой лежит текущий модуль
// Используется для подключения модулей, $include и т.п. из модуля, подключённого с uses-in
@ -2983,7 +2978,7 @@ namespace PascalABCCompiler
else
{
// если есть pcu - возврат EVA
if (UnitHasPCU(unitsFromUsesSection, directUnitsFromUsesSection, currentUnitNode, ref unitFileName, ref currentUnit, caseSensitiveSearch))
if (UnitHasPCU(unitsFromUsesSection, directUnitsFromUsesSection, currentUnitNode, ref unitFileName, ref currentUnit, previousUnitLanguage))
return currentUnit;
// нет pcu и модуль не откомпилирован => новый модуль EVA
@ -3156,7 +3151,7 @@ namespace PascalABCCompiler
{
interfaceUsesList = GetInterfaceUsesSection(currentUnit.SyntaxTree);
SetUseDLLForSystemUnits(currentDirectory, interfaceUsesList, interfaceUsesList.Count - 1 - currentUnit.InterfaceUsedUnits.Count, currentUnit.Language.CaseSensitive);
SetUseDLLForSystemUnits(currentDirectory, interfaceUsesList, interfaceUsesList.Count - 1 - currentUnit.InterfaceUsedUnits.Count, currentUnit.Language);
references = GetReferences(currentUnit);
@ -3230,9 +3225,9 @@ namespace PascalABCCompiler
{
for (int i = implementationUsesList.Count - 1; i >= 0; i--)
{
if (!IsPossibleNetNamespaceOrStandardPasFile(implementationUsesList[i], true, currentPath, currentUnit.Language.CaseSensitive))
if (!IsPossibleNetNamespaceOrStandardPasFile(implementationUsesList[i], true, currentPath, currentUnit.Language))
{
CompilationUnit unitFromUsesSection = UnitTable[Path.ChangeExtension(GetUnitFileName(implementationUsesList[i], currentPath, currentUnit.Language.CaseSensitive), null)];
CompilationUnit unitFromUsesSection = UnitTable[Path.ChangeExtension(GetUnitFileName(implementationUsesList[i], currentPath, currentUnit.Language), null)];
// защита от попадания в бесконечный цикл (когда мы вернемся в тот юнит, в котором уже были (еще не скомпилированный), а затем спустимся по дереву зависимостей сюда же и т.д.)
// первая часть условия - если мы встречаем юнит не первый раз, вторая часть - если интерфейс еще не скомпилирован
@ -3246,7 +3241,7 @@ namespace PascalABCCompiler
}
else
{
CompileUnit(currentUnit.ImplementationUsedUnits, currentUnit.ImplementationUsedDirectUnits, implementationUsesList[i], currentPath, currentUnit.Language.CaseSensitive);
CompileUnit(currentUnit.ImplementationUsedUnits, currentUnit.ImplementationUsedDirectUnits, implementationUsesList[i], currentPath, currentUnit.Language);
}
}
else
@ -3322,7 +3317,7 @@ namespace PascalABCCompiler
shouldReturnCurrentUnit = false;
for (int i = interfaceUsesList.Count - 1 - currentUnit.InterfaceUsedUnits.Count; i >= 0; i--) // здесь откидываются модули с уже откомпилированными интерфейсами из секции uses (см. комментарий, обозначенный #1710)
{
if (IsPossibleNetNamespaceOrStandardPasFile(interfaceUsesList[i], true, currentPath, currentUnit.Language.CaseSensitive) || namespaces.ContainsKey(interfaceUsesList[i].name.idents[0].name))
if (IsPossibleNetNamespaceOrStandardPasFile(interfaceUsesList[i], true, currentPath, currentUnit.Language) || namespaces.ContainsKey(interfaceUsesList[i].name.idents[0].name))
{
currentUnit.InterfaceUsedUnits.AddElement(new namespace_unit_node(GetNamespace(interfaceUsesList[i])), null);
currentUnit.possibleNamespaces.Add(interfaceUsesList[i]);
@ -3336,7 +3331,7 @@ namespace PascalABCCompiler
#endregion
// компиляция модулей из интерфейса текущего модуля
CompileUnit(currentUnit.InterfaceUsedUnits, currentUnit.InterfaceUsedDirectUnits, interfaceUsesList[i], currentPath, currentUnit.Language.CaseSensitive);
CompileUnit(currentUnit.InterfaceUsedUnits, currentUnit.InterfaceUsedDirectUnits, interfaceUsesList[i], currentPath, currentUnit.Language);
// если текущий модуль был откомпилирован в другом рекурсивном вызове
if (currentUnit.State == UnitState.Compiled)
@ -3351,7 +3346,7 @@ namespace PascalABCCompiler
private void SemanticCheckNoLoopDependenciesOfInterfaces(CompilationUnit currentUnit, string unitFileName, SyntaxTree.unit_or_namespace usedUnitNode, string currentPath)
{
var usedUnitFileName = GetUnitFileName(usedUnitNode, currentPath, currentUnit.Language.CaseSensitive);
var usedUnitFileName = GetUnitFileName(usedUnitNode, currentPath, currentUnit.Language);
var usedUnitId = Path.ChangeExtension(usedUnitFileName, null);
// когда образуется цикл здесь сохранится смежная вершина графа (используемый юнит), которая тоже принадлежит циклу
@ -3378,13 +3373,13 @@ namespace PascalABCCompiler
/// <summary>
/// Если в программе в секции uses есть не про-во имен и не стандартный модуль, то использование PABCRtl.dll отменяется
/// </summary>
private void SetUseDLLForSystemUnits(string currentDirectory, List<SyntaxTree.unit_or_namespace> usesList, int lastUnitIndex, bool caseSensitive)
private void SetUseDLLForSystemUnits(string currentDirectory, List<SyntaxTree.unit_or_namespace> usesList, int lastUnitIndex, ILanguage currentUnitLanguage)
{
if (usesList != null && CompilerOptions.UseDllForSystemUnits)
{
for (int i = lastUnitIndex; i >= 0; i--)
{
if (!IsPossibleNetNamespaceOrStandardPasFile(usesList[i], false, currentDirectory, caseSensitive))
if (!IsPossibleNetNamespaceOrStandardPasFile(usesList[i], false, currentDirectory, currentUnitLanguage))
{
CompilerOptions.UseDllForSystemUnits = false;
break;
@ -3648,7 +3643,7 @@ namespace PascalABCCompiler
return docs;
}
private bool UnitHasPCU(unit_node_list unitsFromUsesSection, Dictionary<unit_node, CompilationUnit> directUnitsFromUsesSection, SyntaxTree.unit_or_namespace currentUnitNode, ref string UnitFileName, ref CompilationUnit currentUnit, bool caseSensitiveSearch)
private bool UnitHasPCU(unit_node_list unitsFromUsesSection, Dictionary<unit_node, CompilationUnit> directUnitsFromUsesSection, SyntaxTree.unit_or_namespace currentUnitNode, ref string UnitFileName, ref CompilationUnit currentUnit, ILanguage previousUnitLanguage)
{
if (Path.GetExtension(UnitFileName).ToLower() == CompilerOptions.CompiledUnitExtension)
{
@ -3657,7 +3652,7 @@ namespace PascalABCCompiler
if (UnitTable.Count == 0) throw new ProgramModuleExpected(UnitFileName, null);
try
{
if ((currentUnit = ReadPCU(UnitFileName, caseSensitiveSearch)) != null)
if ((currentUnit = ReadPCU(UnitFileName, previousUnitLanguage)) != null)
{
AddCurrentUnitAndItsReferencesToUsesLists(unitsFromUsesSection, directUnitsFromUsesSection,
currentUnitNode, currentUnit, GetReferences(currentUnit));
@ -3683,7 +3678,7 @@ namespace PascalABCCompiler
throw new CompilerInternalError("PCUReader", e);
#endif
}
string SourceFileName = FindSourceFileName(Path.ChangeExtension(UnitFileName, null), null, out _, caseSensitiveSearch);
string SourceFileName = FindSourceFileName(Path.ChangeExtension(UnitFileName, null), null, out _, previousUnitLanguage);
if (SourceFileName == null)
throw new ReadPCUError(UnitFileName);
else
@ -3786,7 +3781,7 @@ namespace PascalABCCompiler
}
}
public CompilationUnit ReadPCU(string FileName, bool caseSensitiveSearch)
public CompilationUnit ReadPCU(string FileName, ILanguage currentUnitLanguage)
{
if (CompilerOptions.ForIntellisense && false)
{
@ -3797,14 +3792,14 @@ namespace PascalABCCompiler
return unit;
}
PCUReader pr = new PCUReader(this, pr_ChangeState);
unit = pr.GetCompilationUnit(FileName, CompilerOptions.Debug, caseSensitiveSearch);
unit = pr.GetCompilationUnit(FileName, CompilerOptions.Debug, currentUnitLanguage);
pcuCompilationUnits[FileName] = unit;
return unit;
}
else
{
PCUReader pr = new PCUReader(this, pr_ChangeState);
return pr.GetCompilationUnit(FileName, CompilerOptions.Debug, caseSensitiveSearch);
return pr.GetCompilationUnit(FileName, CompilerOptions.Debug, currentUnitLanguage);
}
}
@ -4010,10 +4005,10 @@ namespace PascalABCCompiler
return null;
return compilationUnit;
}*/
public bool NeedRecompiled(string pcu_name, string[] included, PCUReader pr, bool caseSensitive)
public bool NeedRecompiled(string pcu_name, string[] included, PCUReader pr, ILanguage currentUnitLanguage)
{
if (!Path.IsPathRooted(pcu_name)) throw new InvalidOperationException();
string pas_name = FindSourceFileName(Path.ChangeExtension(pcu_name, null), null, out _, caseSensitive);
string pas_name = FindSourceFileName(Path.ChangeExtension(pcu_name, null), null, out _, currentUnitLanguage);
var dir = Path.GetDirectoryName(pcu_name);
if (UnitTable[Path.ChangeExtension(pas_name, null)] != null)
@ -4024,7 +4019,7 @@ namespace PascalABCCompiler
{
//if (included[i].Contains("$"))
// continue;
var used_unit_fname = GetUnitFileName(Path.GetFileNameWithoutExtension(included[i]), included[i], dir, null, caseSensitive);
var used_unit_fname = GetUnitFileName(Path.GetFileNameWithoutExtension(included[i]), included[i], dir, null, currentUnitLanguage);
var used_unit_is_pcu = Path.GetExtension(used_unit_fname) == CompilerOptions.CompiledUnitExtension;
if (!used_unit_is_pcu)
@ -4045,7 +4040,7 @@ namespace PascalABCCompiler
//Console.WriteLine("{0} {1}",name,RecompileList.Count);
for (int i = 0; i < included.Length; i++)
{
string pcu_name2 = FindPCUFileName(included[i], dir, out _, caseSensitive);
string pcu_name2 = FindPCUFileName(included[i], dir, out _, currentUnitLanguage);
//TODO: Спросить у Сащи насчет < и <=.
if ((File.Exists(pcu_name2) && File.GetLastWriteTime(pcu_name) < File.GetLastWriteTime(pcu_name2) && !pr.AlreadyCompiled(pcu_name2)))

View file

@ -50,11 +50,6 @@ namespace PascalABCCompiler
{
get;
}
SupportedSourceFile[] SupportedSourceFiles
{
get;
}
SupportedSourceFile[] SupportedProjectFiles
{

View file

@ -7,6 +7,6 @@ namespace PascalABCCompiler.PCU
{
public static class PCUFileFormatVersion
{
public static System.Int16 Version = 122;
public static System.Int16 Version = 123;
}
}

View file

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Reflection;
using PascalABCCompiler.TreeConverter;
using PascalABCCompiler.TreeRealization;
using Languages.Facade;
namespace PascalABCCompiler.PCU
{
@ -217,10 +218,10 @@ namespace PascalABCCompiler.PCU
ReadPCUHeader();
}
public string GetFullUnitName(string UnitName, bool caseSensitiveSearch)
public string GetFullUnitName(string UnitName, ILanguage currentUnitLanguage)
{
var FullUnitName = comp.FindPCUFileName(UnitName, dir, out _, caseSensitiveSearch);
var FullUnitName = comp.FindPCUFileName(UnitName, dir, out _, currentUnitLanguage);
if (FullUnitName == null) throw new Errors.FileNotFound(UnitName, null);
return FullUnitName;
@ -229,25 +230,28 @@ namespace PascalABCCompiler.PCU
private PCUReader GetPCUReaderForUnitId(int id)
{
if (id == -1) return this;
string s = GetFullUnitName(pcu_file.incl_modules[id], pcu_file.languageCaseSensitive);
ILanguage currentUnitLanguage = LanguageProvider.Instance.SelectLanguageByName(pcu_file.languageName);
string s = GetFullUnitName(pcu_file.incl_modules[id], currentUnitLanguage);
if ( !units.TryGetValue(s, out var pr) )
{
pr = new PCUReader(this);
pr.GetCompilationUnit(s, this.readDebugInfo, pcu_file.languageCaseSensitive);
pr.GetCompilationUnit(s, this.readDebugInfo, currentUnitLanguage);
}
return pr;
}
//десериализация модуля
//читается только шапка PCU и заполняются имена сущностей модуля в таблицу символов
public CompilationUnit GetCompilationUnit(string FileName, bool readDebugInfo, bool caseSensitiveSearch)
public CompilationUnit GetCompilationUnit(string FileName, bool readDebugInfo, ILanguage currentUnitLanguage)
{
try
{
// Compiler.CombinePath всегда должно быть применено к имени файла, перед тем как кидать его сюда
if (!Path.IsPathRooted(FileName)) throw new InvalidOperationException();
FileName = GetFullUnitName(FileName, caseSensitiveSearch);
FileName = GetFullUnitName(FileName, currentUnitLanguage);
dir = Path.GetDirectoryName(FileName);
this.FileName = FileName;
@ -277,8 +281,9 @@ namespace PascalABCCompiler.PCU
ChangeState(this, PCUReaderWriterState.BeginReadTree, unit);
cun.scope = new WrappedUnitInterfaceScope(this);
//TODO сохранить в PCU
cun.scope.CaseSensitive = pcu_file.languageCaseSensitive;
bool unitLanguageCaseSensitive = LanguageProvider.Instance.SelectLanguageByName(pcu_file.languageName).CaseSensitive;
cun.scope.CaseSensitive = unitLanguageCaseSensitive;
if (string.Compare(unit_name, StringConstants.pascalSystemUnitName, true)==0)
PascalABCCompiler.TreeConverter.syntax_tree_visitor.init_system_module(cun);
@ -287,8 +292,7 @@ namespace PascalABCCompiler.PCU
cun.implementation_scope = new WrappedUnitImplementationScope(this, cun.scope);
//\ssyy
//TODO сохранить в PCU
cun.implementation_scope.CaseSensitive = pcu_file.languageCaseSensitive;
cun.implementation_scope.CaseSensitive = unitLanguageCaseSensitive;
string SourceFileName = pcu_file.SourceFileName;
if (Path.GetDirectoryName(SourceFileName) == "")
@ -354,7 +358,10 @@ namespace PascalABCCompiler.PCU
need = true;
return need;
}*/
if (comp.NeedRecompiled(FileName, pcu_file.incl_modules, this, pcu_file.languageCaseSensitive))
ILanguage currentUnitLanguage = LanguageProvider.Instance.SelectLanguageByName(pcu_file.languageName);
if (comp.NeedRecompiled(FileName, pcu_file.incl_modules, this, currentUnitLanguage))
{
//comp.RecompileList.Add(unit_name,unit_name);
comp.RecompileList.Add(FileName);
@ -366,7 +373,7 @@ namespace PascalABCCompiler.PCU
{
//if (pcu_file.incl_modules[i].Contains("$"))
// continue;
var used_unit_fname = comp.GetUnitFileName(Path.GetFileNameWithoutExtension(pcu_file.incl_modules[i]), pcu_file.incl_modules[i], dir, new SyntaxTree.SourceContext(0,0,0,0, FileName), pcu_file.languageCaseSensitive);
var used_unit_fname = comp.GetUnitFileName(Path.GetFileNameWithoutExtension(pcu_file.incl_modules[i]), pcu_file.incl_modules[i], dir, new SyntaxTree.SourceContext(0,0,0,0, FileName), currentUnitLanguage);
if (Path.GetExtension(used_unit_fname) != comp.CompilerOptions.CompiledUnitExtension) return true;
if ( !units.TryGetValue(used_unit_fname, out var pr) );
@ -377,7 +384,7 @@ namespace PascalABCCompiler.PCU
used_units.Add(used_unit_fname);
if (!already_compiled.Contains(used_unit_fname))
{
var sub_u = pr.GetCompilationUnit(used_unit_fname, this.readDebugInfo, pcu_file.languageCaseSensitive);
var sub_u = pr.GetCompilationUnit(used_unit_fname, this.readDebugInfo, currentUnitLanguage);
if (sub_u == null) return true;
this.unit.InterfaceUsedDirectUnits.Add(sub_u.SemanticTree, sub_u);
this.unit.InterfaceUsedUnits.AddElement(sub_u.SemanticTree, pcu_file.incl_modules[i]);
@ -580,7 +587,7 @@ namespace PascalABCCompiler.PCU
else
cur_doc = new document(pcu_file.SourceFileName);
pcu_file.languageCaseSensitive = br.ReadBoolean();
pcu_file.languageName = br.ReadString();
int num_names = br.ReadInt32();
pcu_file.names = new NameRef[num_names];
@ -2490,7 +2497,8 @@ namespace PascalABCCompiler.PCU
//Добавляем подключенные модули
for (int i = 0; i < uses_count; i++)
{
if ( units.TryGetValue(GetFullUnitName(pcu_file.incl_modules[i], pcu_file.languageCaseSensitive), out var pcu_r) );
if ( units.TryGetValue(GetFullUnitName(pcu_file.incl_modules[i],
LanguageProvider.Instance.SelectLanguageByName(pcu_file.languageName)), out var pcu_r) );
{
top_scopes.Add(pcu_r.cun.scope);
}

View file

@ -171,7 +171,7 @@ namespace PascalABCCompiler.PCU
public string SourceFileName;
public bool languageCaseSensitive;
public string languageName;
public NameRef[] names; //список имен интерфейсной части модуля
public string[] incl_modules; //список подключаемых модулей
@ -305,7 +305,7 @@ namespace PascalABCCompiler.PCU
GetUsedUnits();//заполняем список полключаемых модулей
pcu_file.languageCaseSensitive = Unit.Language.CaseSensitive;
pcu_file.languageName = Unit.Language.Name;
GetCountOfMembers();//заполняем список имен интерфейсных сущностей
WriteUnit();//пишем имя interface_namespace
@ -439,7 +439,7 @@ namespace PascalABCCompiler.PCU
if (pcu_file.IncludeDebugInfo)
fbw.Write(pcu_file.SourceFileName);
fbw.Write(pcu_file.languageCaseSensitive);
fbw.Write(pcu_file.languageName);
fbw.Write(pcu_file.names.Length);
for (int i=0; i<pcu_file.names.Length; i++)

View file

@ -19,72 +19,19 @@ namespace Languages.Integration
private static readonly LanguageProvider LanguageProvider = LanguageProvider.Instance;
/// <summary>
/// Имя директории, содержащей установленные плагины языков программирования
/// </summary>
private const string languageKitsDirectoryName = "LanguageKits";
/// <summary>
/// Событие, информирующее об успешной загрузке плагина языка
/// Событие, информирующее об успешной загрузке языкового пакета
/// </summary>
public static event Action<ILanguage> LanguageLoaded;
/// <summary>
/// Событие, информирующее об ошибке загрузки плагина языка
/// Событие, информирующее об ошибке загрузки языкового пакета
/// </summary>
public static event Action<string> LanguageLoadErrorOccured;
/// <summary>
/// Возвращает директорию, содержащую комплекты языков (если ее нет, то вернется null)
/// </summary>
private static DirectoryInfo GetLanguageKitsDirectory()
{
string binDirectoryPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string languageKitsDirectoryPath = Path.Combine(binDirectoryPath, languageKitsDirectoryName);
if (Directory.Exists(languageKitsDirectoryPath))
return new DirectoryInfo(languageKitsDirectoryPath);
return null;
}
/// <summary>
/// Загружает все языковые комплекты для использования (имя "главной" dll должно заканчиваться на Language)
/// </summary>
public static void LoadAllLanguageKits()
{
DirectoryInfo languageKitsDirectory = GetLanguageKitsDirectory();
if (languageKitsDirectory == null)
return;
foreach (var languageKit in languageKitsDirectory.GetDirectories())
{
FileInfo[] dllFiles = languageKit.GetFiles();
foreach (var dll in dllFiles)
{
if (dll.Name.EndsWith("LanguageInfo.dll"))
{
IntegrateLanguageFromAssembly(dll);
break;
}
}
}
}
/// <summary>
/// Загружает все языки, доступные в системе
/// Загружает все языки платформы из папки bin
/// </summary>
public static void LoadAllLanguages()
{
LoadStandardLanguages();
LoadAllLanguageKits();
}
/// <summary>
/// Загружает стандартные языки платформы из папки bin
/// </summary>
public static void LoadStandardLanguages()
{
string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().ManifestModule.FullyQualifiedName);

View file

@ -35,6 +35,12 @@ namespace PascalABCCompiler
public class FormatTools
{
public static string LanguageAndExtensionsFormatted(string languageName, string[] extensions)
{
return string.Format("{0} ({1})", languageName, ExtensionsToString(extensions, "*", ";"));
}
public static string ExtensionsToString(string[] Extensions,string Mask,string Delimer)
{
string res = "";

View file

@ -2,6 +2,7 @@ cd ..\bin
del ..\Release\PACNETConsole.zip
..\utils\pkzipc\pkzipc.exe -add ..\Release\PABCNETC.zip pabcnetc.exe pabcnetcclear.exe Compiler.dll CompilerTools.dll Errors.dll Localization.dll NETGenerator.dll ParserTools.dll ICSharpCode.NRefactory.dll SemanticTree.dll SyntaxTree.dll TreeConverter.dll OptimizerConversion.dll PascalABCParser.dll PascalABCLanguageInfo.dll licence.txt PascalABCNET.chm System.Threading.dll SyntaxTreeConverters.dll YieldHelpers.dll SyntaxVisitors.dll LambdaAnySynToSemConverter.dll LanguageIntegrator.dll StringConstants.dll
..\utils\pkzipc\pkzipc.exe -add -nozip -dir ..\Release\PABCNETC.zip Lib\*.pcu
..\utils\pkzipc\pkzipc.exe -add -nozip -dir ..\Release\PABCNETC.zip Lib\SPython\*.pcu
..\utils\pkzipc\pkzipc.exe -add -nozip -dir ..\Release\PABCNETC.zip Lng\*.dat
..\utils\pkzipc\pkzipc.exe -add -nozip -dir ..\Release\PABCNETC.zip Lng\*.LanguageName
..\utils\pkzipc\pkzipc.exe -add -nozip -dir ..\Release\PABCNETC.zip doc\*.*

View file

@ -108,7 +108,9 @@ SectionEnd
Section
${AddDirectory} "$INSTDIR\LibSource"
${AddDirectory} "$INSTDIR\LibSource\SPython"
${AddDirectory} "$INSTDIR\Lib"
${AddDirectory} "$INSTDIR\Lib\SPython"
${AddDirectory} "$INSTDIR\Highlighting"
${AddDirectory} "$INSTDIR\PT4"
${AddDirectory} "$INSTDIR\Ico"

View file

@ -1,7 +1,7 @@
uses
// SPython
//SPythonSystem, SPythonHidden,
time1,
time1, random1,
SPythonSystemPys, itertools, math
;

View file

@ -180,13 +180,6 @@
File ..\bin\Lib\Tasks1Arr.pcu
File ..\bin\Lib\WPF.pcu
File ..\bin\Lib\SPythonHidden.pcu
File ..\bin\Lib\SPythonSystem.pcu
File ..\bin\Lib\time1.pcu
File ..\bin\Lib\SPythonSystemPys.pcu
File ..\bin\Lib\itertools.pcu
File ..\bin\Lib\math.pcu
File ..\bin\Lib\PABCRtl.dll
File ..\bin\Lib\HelixToolkit.Wpf.dll
File ..\bin\Lib\HelixToolkit.dll
@ -280,14 +273,6 @@
${AddFile} "Tasks1Arr.pcu"
${AddFile} "WPF.pcu"
;SPython
${AddFile} "SPythonHidden.pcu"
${AddFile} "SPythonSystem.pcu"
${AddFile} "time1.pcu"
${AddFile} "SPythonSystemPys.pcu"
${AddFile} "itertools.pcu"
${AddFile} "math.pcu"
${AddFile} "turtle.png"
${AddFile} "PABCRtl.dll"
@ -299,6 +284,27 @@
${AddFile} "PABCRtl.pdb"
;SPython
Delete "$INSTDIR\Lib\SPython\*.pas"
Delete "$INSTDIR\Lib\SPython\*.pys"
SetOutPath "$INSTDIR\Lib\SPython"
File ..\bin\Lib\SPython\SPythonHidden.pcu
File ..\bin\Lib\SPython\SPythonSystem.pcu
File ..\bin\Lib\SPython\SPythonSystemPys.pcu
File ..\bin\Lib\SPython\time1.pcu
File ..\bin\Lib\SPython\random1.pcu
File ..\bin\Lib\SPython\itertools.pcu
File ..\bin\Lib\SPython\math.pcu
${AddFile} "SPythonHidden.pcu"
${AddFile} "SPythonSystem.pcu"
${AddFile} "SPythonSystemPys.pcu"
${AddFile} "time1.pcu"
${AddFile} "random1.pcu"
${AddFile} "itertools.pcu"
${AddFile} "math.pcu"
SetOutPath "$INSTDIR\Doc"
File ..\doc\NumLibABC.pdf
${AddFile} "NumLibABC.pdf"
@ -396,15 +402,6 @@
File ..\bin\Lib\Мозаика.pas
File ..\bin\Lib\WPF.pas
;SPython
File ..\bin\Lib\SPythonHidden.pas
File ..\bin\Lib\SPythonSystem.pas
File ..\bin\Lib\time1.pas
File ..\bin\Lib\SPythonSystemPys.pys
File ..\bin\Lib\itertools.pys
File ..\bin\Lib\math.pys
File ..\bin\Lib\__RedirectIOMode.vb
File ..\bin\Lib\VBSystem.vb
@ -485,19 +482,31 @@
${AddFile} "Мозаика.pas"
${AddFile} "WPF.pas"
${AddFile} "__RedirectIOMode.vb"
${AddFile} "VBSystem.vb"
;SPython
SetOutPath "$INSTDIR\LibSource\SPython"
File ..\bin\Lib\SPython\SPythonHidden.pas
File ..\bin\Lib\SPython\SPythonSystem.pas
File ..\bin\Lib\SPython\time1.pas
File ..\bin\Lib\SPython\SPythonSystemPys.pys
File ..\bin\Lib\SPython\random1.pys
File ..\bin\Lib\SPython\itertools.pys
File ..\bin\Lib\SPython\math.pys
${AddFile} "SPythonHidden.pas"
${AddFile} "SPythonSystem.pas"
${AddFile} "time1.pas"
${AddFile} "SPythonSystemPys.pys"
${AddFile} "random1.pys"
${AddFile} "itertools.pys"
${AddFile} "math.pys"
${AddFile} "__RedirectIOMode.vb"
${AddFile} "VBSystem.vb"
CreateDirectory "$COMMONSTARTMENU\PascalABC.NET"
CreateDirectory "$SMPROGRAMS\PascalABC.NET"
Push "OptimizerConversion.dll"

View file

@ -8,6 +8,7 @@ using System.IO;
using VisualPascalABCPlugins;
using System.Threading;
using Languages.Integration;
using Languages.Facade;
namespace VisualPascalABC
{
@ -174,10 +175,10 @@ namespace VisualPascalABC
if (standartCompiler == null)
return null;
string Filter = "", AllFilter = "";
foreach (PascalABCCompiler.SupportedSourceFile ssf in standartCompiler.SupportedSourceFiles)
foreach (ILanguage lang in LanguageProvider.Instance.Languages)
{
Filter = Tools.MakeFilter(Filter, ssf.LanguageName, ssf.Extensions);
AllFilter = Tools.MakeAllFilter(AllFilter, ssf.LanguageName, ssf.Extensions);
Filter = Tools.MakeFilter(Filter, lang.Name, lang.FilesExtensions);
AllFilter = Tools.MakeAllFilter(AllFilter, lang.Name, lang.FilesExtensions);
}
Filter += "Программы на C# (*.cs)|*.cs|";
AllFilter += "*.cs;";
@ -390,8 +391,9 @@ namespace VisualPascalABC
if (!(defaultCompilerType == PascalABCCompiler.CompilerType.Remote) || (standartCompiler.State == PascalABCCompiler.CompilerState.Ready && (remoteCompiler != null && remoteCompiler.State == PascalABCCompiler.CompilerState.Ready)))
StartingCompleted = true;
AddCompilerTextToCompilerMessages(sender, VECStringResources.Get("SUPPORTED_LANGUAGES") + Environment.NewLine);
foreach (PascalABCCompiler.SupportedSourceFile ssf in standartCompiler.SupportedSourceFiles)
AddCompilerTextToCompilerMessages(sender, string.Format(VECStringResources.Get("CM_LANGUAGE_{0}"), ssf) + Environment.NewLine);
foreach (ILanguage lang in LanguageProvider.Instance.Languages)
AddCompilerTextToCompilerMessages(sender, string.Format(VECStringResources.Get("CM_LANGUAGE_{0}"),
PascalABCCompiler.FormatTools.LanguageAndExtensionsFormatted(lang.Name, lang.FilesExtensions) + Environment.NewLine));
if (StartingCompleted)
{
ChangeVisualEnvironmentState(VisualEnvironmentState.FinishCompilerLoading, standartCompiler);

View file

@ -1,12 +1,13 @@
// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using Languages.Facade;
using Languages.Integration;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.IO;
using VisualPascalABCPlugins;
using Languages.Integration;
namespace VisualPascalABC
{
@ -172,10 +173,10 @@ namespace VisualPascalABC
if (standartCompiler == null)
return null;
string Filter = "", AllFilter = "";
foreach (PascalABCCompiler.SupportedSourceFile ssf in standartCompiler.SupportedSourceFiles)
foreach (ILanguage lang in LanguageProvider.Instance.Languages)
{
Filter = Tools.MakeFilter(Filter, ssf.LanguageName, ssf.Extensions);
AllFilter = Tools.MakeAllFilter(AllFilter, ssf.LanguageName, ssf.Extensions);
Filter = Tools.MakeFilter(Filter, lang.Name, lang.FilesExtensions);
AllFilter = Tools.MakeAllFilter(AllFilter, lang.Name, lang.FilesExtensions);
}
Filter += "Программы на C# (*.cs)|*.cs|";
AllFilter += "*.cs;";
@ -377,8 +378,9 @@ namespace VisualPascalABC
if (!(defaultCompilerType == PascalABCCompiler.CompilerType.Remote) || (standartCompiler.State == PascalABCCompiler.CompilerState.Ready && (remoteCompiler != null && remoteCompiler.State == PascalABCCompiler.CompilerState.Ready)))
StartingCompleted = true;
AddCompilerTextToCompilerMessages(sender, VECStringResources.Get("SUPPORTED_LANGUAGES") + Environment.NewLine);
foreach (PascalABCCompiler.SupportedSourceFile ssf in standartCompiler.SupportedSourceFiles)
AddCompilerTextToCompilerMessages(sender, string.Format(VECStringResources.Get("CM_LANGUAGE_{0}"), ssf) + Environment.NewLine);
foreach (ILanguage lang in LanguageProvider.Instance.Languages)
AddCompilerTextToCompilerMessages(sender, string.Format(VECStringResources.Get("CM_LANGUAGE_{0}"),
PascalABCCompiler.FormatTools.LanguageAndExtensionsFormatted(lang.Name, lang.FilesExtensions) + Environment.NewLine));
if (StartingCompleted)
{
ChangeVisualEnvironmentState(VisualEnvironmentState.FinishCompilerLoading, standartCompiler);

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,380 +0,0 @@
unit GraphABCHelper;
//#apptype windows
#reference 'System.Windows.Forms.dll'
#reference 'System.Drawing.dll'
#savepcu false
interface
uses System.Drawing;
type Color = System.Drawing.Color;
// Primitives
procedure Line(x1,y1,x2,y2: integer; gr: Graphics);
procedure Line(x1,y1,x2,y2: integer; c: Color; gr: Graphics);
procedure FillEllipse(x1,y1,x2,y2: integer; gr: Graphics);
procedure DrawEllipse(x1,y1,x2,y2: integer; gr: Graphics);
procedure FillRectangle(x1,y1,x2,y2: integer; gr: Graphics);
procedure FillRect(x1,y1,x2,y2: integer; gr: Graphics);
procedure DrawRectangle(x1,y1,x2,y2: integer; gr: Graphics);
procedure FillCircle(x,y,r: integer; gr: Graphics);
procedure DrawCircle(x,y,r: integer; gr: Graphics);
procedure DrawRoundRect(x1,y1,x2,y2,w,h: integer; gr: Graphics);
procedure FillRoundRect(x1,y1,x2,y2,w,h: integer; gr: Graphics);
procedure Ellipse(x1,y1,x2,y2: integer; gr: Graphics);
procedure Rectangle(x1,y1,x2,y2: integer; gr: Graphics);
procedure Circle(x,y,r: integer; gr: Graphics);
procedure RoundRect(x1,y1,x2,y2,w,h: integer; gr: Graphics);
procedure Arc(x,y,r,a1,a2: integer; gr: Graphics);
procedure Pie(x,y,r,a1,a2: integer; gr: Graphics);
procedure FillPie(x,y,r,a1,a2: integer; gr: Graphics);
procedure DrawPie(x,y,r,a1,a2: integer; gr: Graphics);
procedure DrawPolygon(a: array of Point; gr: Graphics);
procedure FillPolygon(a: array of Point; gr: Graphics);
procedure Polygon(a: array of Point; gr: Graphics);
procedure Polyline(a: array of Point; gr: Graphics);
procedure Curve(a: array of Point; gr: Graphics);
procedure DrawClosedCurve(a: array of Point; gr: Graphics);
procedure FillClosedCurve(a: array of Point; gr: Graphics);
procedure ClosedCurve(a: array of Point; gr: Graphics);
procedure TextOut(x,y: integer; s: string; gr: Graphics);
function GetView(b: Bitmap; r: System.Drawing.Rectangle): Bitmap;
function ImageIntersect(b1,b2: Bitmap): boolean;
var
CurrentTextBrush: SolidBrush;
implementation
uses System, System.Drawing, System.Drawing.Drawing2D, GraphABC;
var
sf: StringFormat;
ColorLinePen: System.Drawing.Pen;
function ImageIntersect(b1,b2: Bitmap): boolean;
// Предполагается, что b1 и b2 - одного размера
type
RGB = record
r,g,b: byte;
end;
PRGB = ^uint32;
label 1;
var
ptr1,ptr2: pointer;
iptr1,iptr2: integer;
p1,p2: PRGB;
rect: System.Drawing.Rectangle;
bmpData1,bmpData2: System.Drawing.Imaging.BitmapData;
begin
rect := new System.Drawing.Rectangle(0,0,b1.Width,b1.Height);
bmpData1 := b1.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, b1.PixelFormat);
ptr1 := bmpData1.Scan0.ToPointer;
iptr1 := integer(ptr1);
bmpData2 := b2.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, b2.PixelFormat);
ptr2 := bmpData2.Scan0.ToPointer;
iptr2 := integer(ptr2);
var pixelFormatSize := Image.GetPixelFormatSize(b1.PixelFormat) div 8;
var Offset := bmpData1.stride - b1.Width * pixelFormatSize;
Result := False;
for var y:=0 to b1.Height-1 do
begin
for var x:=0 to b1.Width-1 do
begin
p1 := PRGB(pointer(iptr1));
p2 := PRGB(pointer(iptr2));
//writeln(p1^.R,' ',p1^.G,' ',p1^.B,' ',p2^.R,' ',p2^.G,' ',p2^.B);
// if ((p1^.R and p1^.G and p1^.B)<>$FF) and ((p2^.R and p2^.G and p2^.B)<>$FF) then
if (p1^<>$FFFFFFFF) and (p2^<>$FFFFFFFF) then
begin
Result := True;
goto 1;
end;
iptr1 += pixelFormatSize;
iptr2 += pixelFormatSize;
end;
iptr1 += Offset;
iptr2 += Offset;
end;
1:
b2.UnlockBits(bmpData1);
b1.UnlockBits(bmpData1);
end;
function GetView(b: Bitmap; r: System.Drawing.Rectangle): Bitmap;
var
w,h,stride,padding,pixelFormatSize: integer;
ptr,start: System.IntPtr;
rect: System.Drawing.Rectangle;
bmpData: System.Drawing.Imaging.BitmapData;
begin
w := b.Width;
h := b.Height;
rect := new System.Drawing.Rectangle(0,0,w,h);
bmpData := b.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, b.PixelFormat);
ptr := bmpData.Scan0;
b.UnlockBits(bmpData);
pixelFormatSize := Image.GetPixelFormatSize(b.PixelFormat) div 8;
start := (System.IntPtr)(integer(ptr) + w * pixelFormatSize * r.Y + r.X * pixelFormatSize);
stride := w * pixelFormatSize;
padding := stride mod 4;
if padding<>0 then
stride := stride + 4 - padding; //pad out to multiple of 4
Result := new Bitmap(r.Width,r.Height,stride,b.PixelFormat,start);
end;
procedure Swap(var x1,x2: integer);
var t: integer;
begin
t := x1;
x1 := x2;
x2 := t;
end;
// Graphics Primitives
procedure Line(x1,y1,x2,y2: integer; c: Color; gr: Graphics);
begin
ColorLinePen.Color := c;
gr.DrawLine(ColorLinePen,x1,y1,x2,y2);
end;
procedure Line(x1,y1,x2,y2: integer; gr: Graphics);
begin
gr.DrawLine(Pen.NETPen,x1,y1,x2,y2);
end;
procedure FillRectangle(x1,y1,x2,y2: integer; gr: Graphics);
var sm: SmoothingMode;
begin
if x1>x2 then
Swap(x1,x2);
if y1>y2 then
Swap(y1,y2);
sm := gr.SmoothingMode;
gr.SmoothingMode := SmoothingMode.None;
if Brush.NETBrush<>nil then
gr.FillRectangle(Brush.NETBrush,x1,y1,x2-x1,y2-y1);
gr.SmoothingMode := sm;
end;
procedure FillRect(x1,y1,x2,y2: integer; gr: Graphics);
begin
FillRectangle(x1,y1,x2,y2,gr);
end;
procedure DrawRectangle(x1,y1,x2,y2: integer; gr: Graphics);
begin
if x1>x2 then
Swap(x1,x2);
if y1>y2 then
Swap(y1,y2);
gr.DrawRectangle(Pen.NETPen,x1,y1,x2-x1-1,y2-y1-1);
end;
procedure Rectangle(x1,y1,x2,y2: integer; gr: Graphics);
begin
if Brush.NETBrush <> nil then
FillRectangle(x1,y1,x2-1,y2-1,gr);
if Pen.NETPen.DashStyle <> DashStyle.Custom then
DrawRectangle(x1,y1,x2,y2,gr);
end;
procedure DrawEllipse(x1,y1,x2,y2: integer; gr: Graphics);
begin
if x1>x2 then
Swap(x1,x2);
if y1>y2 then
Swap(y1,y2);
gr.DrawEllipse(Pen.NETPen,x1,y1,x2-x1-1,y2-y1-1);
end;
procedure FillEllipse(x1,y1,x2,y2: integer; gr: Graphics);
begin
if x1>x2 then
Swap(x1,x2);
if y1>y2 then
Swap(y1,y2);
gr.FillEllipse(Brush.NETBrush,x1,y1,x2-x1-1,y2-y1-1);
end;
procedure Ellipse(x1,y1,x2,y2: integer; gr: Graphics);
begin
if Brush.NETBrush <> nil then
FillEllipse(x1,y1,x2,y2,gr);
if Pen.NETPen.DashStyle <> DashStyle.Custom then
DrawEllipse(x1,y1,x2,y2,gr);
end;
procedure DrawCircle(x,y,r: integer; gr: Graphics);
begin
gr.DrawEllipse(Pen.NETPen,x-r,y-r,x+r,y+r);
end;
procedure FillCircle(x,y,r: integer; gr: Graphics);
begin
gr.FillEllipse(Brush.NETBrush,x-r,y-r,x+r,y+r);
end;
procedure Circle(x,y,r: integer; gr: Graphics);
begin
FillCircle(x,y,r,gr);
DrawCircle(x,y,r,gr);
end;
function CreatePathForDrawRoundRect(x1,y1,x2,y2,w,h: integer): GraphicsPath;
var xx,yy: integer;
begin
if x1>x2 then
Swap(x1,x2);
if y1>y2 then
Swap(y1,y2);
xx := w div 2;
yy := h div 2;
Result := new GraphicsPath();
Result.AddLine(x1 + xx, y1, x2 - xx, y1);
Result.AddArc(x2 - w - 1, y1, w, h, 270, 90);
Result.AddLine(x2 - 1, y1 + yy, x2 - 1, y2 - yy);
Result.AddArc(x2 - w - 1, y2 - h - 1, w, h, 0, 90);
Result.AddLine(x2 - xx, y2 - 1, x1 + xx, y2 - 1);
Result.AddArc(x1, y2 - h - 1, w, h, 90, 90);
Result.AddLine(x1, y2 - yy, x1, y1 + yy);
Result.AddArc(x1, y1, w, h, 180, 90);
Result.CloseFigure();
end;
procedure DrawRoundRect(x1,y1,x2,y2,w,h: integer; gr: Graphics);
var path: GraphicsPath;
begin
path := CreatePathForDrawRoundRect(x1,y1,x2,y2,w,h);
gr.DrawPath(Pen.NETPen, path);
path.Dispose;
end;
procedure FillRoundRect(x1,y1,x2,y2,w,h: integer; gr: Graphics);
var path: GraphicsPath;
begin
path := CreatePathForDrawRoundRect(x1,y1,x2,y2,w,h);
gr.FillPath(Brush.NETBrush, path);
path.Dispose;
end;
procedure RoundRect(x1,y1,x2,y2,w,h: integer; gr: Graphics);
begin
if Brush.NETBrush <> nil then
FillRoundRect(x1,y1,x2,y2,w,h,gr);
if Pen.NETPen.DashStyle <> DashStyle.Custom then
DrawRoundRect(x1,y1,x2,y2,w,h,gr);
end;
procedure Arc(x,y,r,a1,a2: integer; gr: Graphics);
begin
a1:=360-a1;
a2:=360-a2;
if a2<a1 then
Swap(a1,a2);
gr.DrawArc(Pen.NETPen,x-r,y-r,2*r,2*r,a1,a2-a1);
end;
procedure DrawPie(x,y,r,a1,a2: integer; gr: Graphics);
begin
a1:=360-a1;
a2:=360-a2;
if a2<a1 then
Swap(a1,a2);
gr.DrawPie(Pen.NETPen,x-r,y-r,2*r,2*r,a1,a2-a1);
end;
procedure FillPie(x,y,r,a1,a2: integer; gr: Graphics);
begin
a1:=360-a1;
a2:=360-a2;
if a2<a1 then
Swap(a1,a2);
gr.FillPie(Brush.NETBrush,x-r,y-r,2*r,2*r,a1,a2-a1);
end;
procedure Pie(x,y,r,a1,a2: integer; gr: Graphics);
begin
if Brush.NETBrush <> nil then
FillPie(x,y,r,a1,a2,gr);
if Pen.NETPen.DashStyle <> DashStyle.Custom then
DrawPie(x,y,r,a1,a2,gr);
end;
procedure DrawPolygon(a: array of Point; gr: Graphics);
begin
gr.DrawPolygon(Pen.NETPen,a);
end;
procedure FillPolygon(a: array of Point; gr: Graphics);
begin
gr.FillPolygon(Brush.NETBrush,a);
end;
procedure Polygon(a: array of Point; gr: Graphics);
begin
if Brush.NETBrush <> nil then
FillPolygon(a,gr);
if Pen.NETPen.DashStyle <> DashStyle.Custom then
DrawPolygon(a,gr);
end;
procedure Polyline(a: array of Point; gr: Graphics);
begin
gr.DrawLines(Pen.NETPen,a);
end;
procedure Curve(a: array of Point; gr: Graphics);
begin
gr.DrawCurve(Pen.NETPen,a);
end;
procedure DrawClosedCurve(a: array of Point; gr: Graphics);
begin
gr.DrawClosedCurve(Pen.NETPen,a);
end;
procedure FillClosedCurve(a: array of Point; gr: Graphics);
begin
gr.FillClosedCurve(Brush.NETBrush,a);
end;
procedure ClosedCurve(a: array of Point; gr: Graphics);
begin
if Brush.NETBrush <> nil then
FillClosedCurve(a,gr);
if Pen.NETPen.DashStyle <> DashStyle.Custom then
DrawClosedCurve(a,gr);
end;
procedure TextOut(x,y: integer; s: string; gr: Graphics);
var sz: SizeF;
begin
sz := gr.MeasureString(s,Font.NETFont,0,sf);
if Brush.NETBrush <> nil then
FillRectangle(x,y,x+round(sz.Width),y+round(sz.Height)+1,gr);
gr.DrawString(s,Font.NETFont,CurrentTextBrush,x,y,sf);
end;
initialization
sf := new StringFormat(StringFormat.GenericTypographic);
sf.FormatFlags := StringFormatFlags.MeasureTrailingSpaces;
CurrentTextBrush := new SolidBrush(System.Drawing.Color.Black);
ColorLinePen := new System.Drawing.Pen(System.Drawing.Color.Black);
end.

File diff suppressed because it is too large Load diff

View file

@ -1,380 +0,0 @@
unit GraphABCHelper;
//#apptype windows
#reference 'System.Windows.Forms.dll'
#reference 'System.Drawing.dll'
#savepcu false
interface
uses System.Drawing;
type Color = System.Drawing.Color;
// Primitives
procedure Line(x1,y1,x2,y2: integer; gr: Graphics);
procedure Line(x1,y1,x2,y2: integer; c: Color; gr: Graphics);
procedure FillEllipse(x1,y1,x2,y2: integer; gr: Graphics);
procedure DrawEllipse(x1,y1,x2,y2: integer; gr: Graphics);
procedure FillRectangle(x1,y1,x2,y2: integer; gr: Graphics);
procedure FillRect(x1,y1,x2,y2: integer; gr: Graphics);
procedure DrawRectangle(x1,y1,x2,y2: integer; gr: Graphics);
procedure FillCircle(x,y,r: integer; gr: Graphics);
procedure DrawCircle(x,y,r: integer; gr: Graphics);
procedure DrawRoundRect(x1,y1,x2,y2,w,h: integer; gr: Graphics);
procedure FillRoundRect(x1,y1,x2,y2,w,h: integer; gr: Graphics);
procedure Ellipse(x1,y1,x2,y2: integer; gr: Graphics);
procedure Rectangle(x1,y1,x2,y2: integer; gr: Graphics);
procedure Circle(x,y,r: integer; gr: Graphics);
procedure RoundRect(x1,y1,x2,y2,w,h: integer; gr: Graphics);
procedure Arc(x,y,r,a1,a2: integer; gr: Graphics);
procedure Pie(x,y,r,a1,a2: integer; gr: Graphics);
procedure FillPie(x,y,r,a1,a2: integer; gr: Graphics);
procedure DrawPie(x,y,r,a1,a2: integer; gr: Graphics);
procedure DrawPolygon(a: array of Point; gr: Graphics);
procedure FillPolygon(a: array of Point; gr: Graphics);
procedure Polygon(a: array of Point; gr: Graphics);
procedure Polyline(a: array of Point; gr: Graphics);
procedure Curve(a: array of Point; gr: Graphics);
procedure DrawClosedCurve(a: array of Point; gr: Graphics);
procedure FillClosedCurve(a: array of Point; gr: Graphics);
procedure ClosedCurve(a: array of Point; gr: Graphics);
procedure TextOut(x,y: integer; s: string; gr: Graphics);
function GetView(b: Bitmap; r: System.Drawing.Rectangle): Bitmap;
function ImageIntersect(b1,b2: Bitmap): boolean;
var
CurrentTextBrush: SolidBrush;
implementation
uses System, System.Drawing, System.Drawing.Drawing2D, GraphABC;
var
sf: StringFormat;
ColorLinePen: System.Drawing.Pen;
function ImageIntersect(b1,b2: Bitmap): boolean;
// Предполагается, что b1 и b2 - одного размера
type
RGB = record
r,g,b: byte;
end;
PRGB = ^uint32;
label 1;
var
ptr1,ptr2: pointer;
iptr1,iptr2: integer;
p1,p2: PRGB;
rect: System.Drawing.Rectangle;
bmpData1,bmpData2: System.Drawing.Imaging.BitmapData;
begin
rect := new System.Drawing.Rectangle(0,0,b1.Width,b1.Height);
bmpData1 := b1.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, b1.PixelFormat);
ptr1 := bmpData1.Scan0.ToPointer;
iptr1 := integer(ptr1);
bmpData2 := b2.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, b2.PixelFormat);
ptr2 := bmpData2.Scan0.ToPointer;
iptr2 := integer(ptr2);
var pixelFormatSize := Image.GetPixelFormatSize(b1.PixelFormat) div 8;
var Offset := bmpData1.stride - b1.Width * pixelFormatSize;
Result := False;
for var y:=0 to b1.Height-1 do
begin
for var x:=0 to b1.Width-1 do
begin
p1 := PRGB(pointer(iptr1));
p2 := PRGB(pointer(iptr2));
//writeln(p1^.R,' ',p1^.G,' ',p1^.B,' ',p2^.R,' ',p2^.G,' ',p2^.B);
// if ((p1^.R and p1^.G and p1^.B)<>$FF) and ((p2^.R and p2^.G and p2^.B)<>$FF) then
if (p1^<>$FFFFFFFF) and (p2^<>$FFFFFFFF) then
begin
Result := True;
goto 1;
end;
iptr1 += pixelFormatSize;
iptr2 += pixelFormatSize;
end;
iptr1 += Offset;
iptr2 += Offset;
end;
1:
b2.UnlockBits(bmpData1);
b1.UnlockBits(bmpData1);
end;
function GetView(b: Bitmap; r: System.Drawing.Rectangle): Bitmap;
var
w,h,stride,padding,pixelFormatSize: integer;
ptr,start: System.IntPtr;
rect: System.Drawing.Rectangle;
bmpData: System.Drawing.Imaging.BitmapData;
begin
w := b.Width;
h := b.Height;
rect := new System.Drawing.Rectangle(0,0,w,h);
bmpData := b.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, b.PixelFormat);
ptr := bmpData.Scan0;
b.UnlockBits(bmpData);
pixelFormatSize := Image.GetPixelFormatSize(b.PixelFormat) div 8;
start := (System.IntPtr)(integer(ptr) + w * pixelFormatSize * r.Y + r.X * pixelFormatSize);
stride := w * pixelFormatSize;
padding := stride mod 4;
if padding<>0 then
stride := stride + 4 - padding; //pad out to multiple of 4
Result := new Bitmap(r.Width,r.Height,stride,b.PixelFormat,start);
end;
procedure Swap(var x1,x2: integer);
var t: integer;
begin
t := x1;
x1 := x2;
x2 := t;
end;
// Graphics Primitives
procedure Line(x1,y1,x2,y2: integer; c: Color; gr: Graphics);
begin
ColorLinePen.Color := c;
gr.DrawLine(ColorLinePen,x1,y1,x2,y2);
end;
procedure Line(x1,y1,x2,y2: integer; gr: Graphics);
begin
gr.DrawLine(Pen.NETPen,x1,y1,x2,y2);
end;
procedure FillRectangle(x1,y1,x2,y2: integer; gr: Graphics);
var sm: SmoothingMode;
begin
if x1>x2 then
Swap(x1,x2);
if y1>y2 then
Swap(y1,y2);
sm := gr.SmoothingMode;
gr.SmoothingMode := SmoothingMode.None;
if Brush.NETBrush<>nil then
gr.FillRectangle(Brush.NETBrush,x1,y1,x2-x1,y2-y1);
gr.SmoothingMode := sm;
end;
procedure FillRect(x1,y1,x2,y2: integer; gr: Graphics);
begin
FillRectangle(x1,y1,x2,y2,gr);
end;
procedure DrawRectangle(x1,y1,x2,y2: integer; gr: Graphics);
begin
if x1>x2 then
Swap(x1,x2);
if y1>y2 then
Swap(y1,y2);
gr.DrawRectangle(Pen.NETPen,x1,y1,x2-x1-1,y2-y1-1);
end;
procedure Rectangle(x1,y1,x2,y2: integer; gr: Graphics);
begin
if Brush.NETBrush <> nil then
FillRectangle(x1,y1,x2-1,y2-1,gr);
if Pen.NETPen.DashStyle <> DashStyle.Custom then
DrawRectangle(x1,y1,x2,y2,gr);
end;
procedure DrawEllipse(x1,y1,x2,y2: integer; gr: Graphics);
begin
if x1>x2 then
Swap(x1,x2);
if y1>y2 then
Swap(y1,y2);
gr.DrawEllipse(Pen.NETPen,x1,y1,x2-x1-1,y2-y1-1);
end;
procedure FillEllipse(x1,y1,x2,y2: integer; gr: Graphics);
begin
if x1>x2 then
Swap(x1,x2);
if y1>y2 then
Swap(y1,y2);
gr.FillEllipse(Brush.NETBrush,x1,y1,x2-x1-1,y2-y1-1);
end;
procedure Ellipse(x1,y1,x2,y2: integer; gr: Graphics);
begin
if Brush.NETBrush <> nil then
FillEllipse(x1,y1,x2,y2,gr);
if Pen.NETPen.DashStyle <> DashStyle.Custom then
DrawEllipse(x1,y1,x2,y2,gr);
end;
procedure DrawCircle(x,y,r: integer; gr: Graphics);
begin
gr.DrawEllipse(Pen.NETPen,x-r,y-r,x+r,y+r);
end;
procedure FillCircle(x,y,r: integer; gr: Graphics);
begin
gr.FillEllipse(Brush.NETBrush,x-r,y-r,x+r,y+r);
end;
procedure Circle(x,y,r: integer; gr: Graphics);
begin
FillCircle(x,y,r,gr);
DrawCircle(x,y,r,gr);
end;
function CreatePathForDrawRoundRect(x1,y1,x2,y2,w,h: integer): GraphicsPath;
var xx,yy: integer;
begin
if x1>x2 then
Swap(x1,x2);
if y1>y2 then
Swap(y1,y2);
xx := w div 2;
yy := h div 2;
Result := new GraphicsPath();
Result.AddLine(x1 + xx, y1, x2 - xx, y1);
Result.AddArc(x2 - w - 1, y1, w, h, 270, 90);
Result.AddLine(x2 - 1, y1 + yy, x2 - 1, y2 - yy);
Result.AddArc(x2 - w - 1, y2 - h - 1, w, h, 0, 90);
Result.AddLine(x2 - xx, y2 - 1, x1 + xx, y2 - 1);
Result.AddArc(x1, y2 - h - 1, w, h, 90, 90);
Result.AddLine(x1, y2 - yy, x1, y1 + yy);
Result.AddArc(x1, y1, w, h, 180, 90);
Result.CloseFigure();
end;
procedure DrawRoundRect(x1,y1,x2,y2,w,h: integer; gr: Graphics);
var path: GraphicsPath;
begin
path := CreatePathForDrawRoundRect(x1,y1,x2,y2,w,h);
gr.DrawPath(Pen.NETPen, path);
path.Dispose;
end;
procedure FillRoundRect(x1,y1,x2,y2,w,h: integer; gr: Graphics);
var path: GraphicsPath;
begin
path := CreatePathForDrawRoundRect(x1,y1,x2,y2,w,h);
gr.FillPath(Brush.NETBrush, path);
path.Dispose;
end;
procedure RoundRect(x1,y1,x2,y2,w,h: integer; gr: Graphics);
begin
if Brush.NETBrush <> nil then
FillRoundRect(x1,y1,x2,y2,w,h,gr);
if Pen.NETPen.DashStyle <> DashStyle.Custom then
DrawRoundRect(x1,y1,x2,y2,w,h,gr);
end;
procedure Arc(x,y,r,a1,a2: integer; gr: Graphics);
begin
a1:=360-a1;
a2:=360-a2;
if a2<a1 then
Swap(a1,a2);
gr.DrawArc(Pen.NETPen,x-r,y-r,2*r,2*r,a1,a2-a1);
end;
procedure DrawPie(x,y,r,a1,a2: integer; gr: Graphics);
begin
a1:=360-a1;
a2:=360-a2;
if a2<a1 then
Swap(a1,a2);
gr.DrawPie(Pen.NETPen,x-r,y-r,2*r,2*r,a1,a2-a1);
end;
procedure FillPie(x,y,r,a1,a2: integer; gr: Graphics);
begin
a1:=360-a1;
a2:=360-a2;
if a2<a1 then
Swap(a1,a2);
gr.FillPie(Brush.NETBrush,x-r,y-r,2*r,2*r,a1,a2-a1);
end;
procedure Pie(x,y,r,a1,a2: integer; gr: Graphics);
begin
if Brush.NETBrush <> nil then
FillPie(x,y,r,a1,a2,gr);
if Pen.NETPen.DashStyle <> DashStyle.Custom then
DrawPie(x,y,r,a1,a2,gr);
end;
procedure DrawPolygon(a: array of Point; gr: Graphics);
begin
gr.DrawPolygon(Pen.NETPen,a);
end;
procedure FillPolygon(a: array of Point; gr: Graphics);
begin
gr.FillPolygon(Brush.NETBrush,a);
end;
procedure Polygon(a: array of Point; gr: Graphics);
begin
if Brush.NETBrush <> nil then
FillPolygon(a,gr);
if Pen.NETPen.DashStyle <> DashStyle.Custom then
DrawPolygon(a,gr);
end;
procedure Polyline(a: array of Point; gr: Graphics);
begin
gr.DrawLines(Pen.NETPen,a);
end;
procedure Curve(a: array of Point; gr: Graphics);
begin
gr.DrawCurve(Pen.NETPen,a);
end;
procedure DrawClosedCurve(a: array of Point; gr: Graphics);
begin
gr.DrawClosedCurve(Pen.NETPen,a);
end;
procedure FillClosedCurve(a: array of Point; gr: Graphics);
begin
gr.FillClosedCurve(Brush.NETBrush,a);
end;
procedure ClosedCurve(a: array of Point; gr: Graphics);
begin
if Brush.NETBrush <> nil then
FillClosedCurve(a,gr);
if Pen.NETPen.DashStyle <> DashStyle.Custom then
DrawClosedCurve(a,gr);
end;
procedure TextOut(x,y: integer; s: string; gr: Graphics);
var sz: SizeF;
begin
sz := gr.MeasureString(s,Font.NETFont,0,sf);
if Brush.NETBrush <> nil then
FillRectangle(x,y,x+round(sz.Width),y+round(sz.Height)+1,gr);
gr.DrawString(s,Font.NETFont,CurrentTextBrush,x,y,sf);
end;
initialization
sf := new StringFormat(StringFormat.GenericTypographic);
sf.FormatFlags := StringFormatFlags.MeasureTrailingSpaces;
CurrentTextBrush := new SolidBrush(System.Drawing.Color.Black);
ColorLinePen := new System.Drawing.Pen(System.Drawing.Color.Black);
end.

View file

@ -1,11 +0,0 @@
cd ABCObjects
..\..\..\pabcnetc.exe ABCObjects.pas
cd ..
cd GraphABC
..\..\..\pabcnetc.exe GraphABC.pas
cd ..

Binary file not shown.

View file

@ -42,10 +42,13 @@ begin
Result := new LanguageTestsInfo(languageInformation.Name, languageInformation.FilesExtensions, languageInformation.CommentSymbol);
end;
function GetLibDir: string;
function GetLibDir(languageName : string): string;
begin
var dir := Path.GetDirectoryName(GetEXEFileName());
Result := dir + PathSeparator + 'Lib';
if languageName <> 'PascalABC.NET' then
Result := dir + PathSeparator + 'Lib' + PathSeparator + languageName
else
Result := dir + PathSeparator + 'Lib';
end;
function GetFilesByExtensions(path: string; extensions: array of string; searchOption: SearchOption := System.IO.SearchOption.TopDirectoryOnly): array of string;
@ -454,7 +457,7 @@ end;
procedure CopyLibFiles;
begin
var files := GetFilesByExtensions(GetLibDir(), CurrentLanguageInfo.languageExtensions);
var files := GetFilesByExtensions(GetLibDir(CurrentLanguageInfo.languageName), CurrentLanguageInfo.languageExtensions);
foreach f: string in files do
begin
&File.Copy(f, TestSuiteDir + PathSeparator + 'CompilationSamples' + PathSeparator + Path.GetFileName(f), true);
@ -482,7 +485,7 @@ end;
begin
//DeletePABCSystemPCU;
try
Languages.Integration.LanguageIntegrator.LoadStandardLanguages();
Languages.Integration.LanguageIntegrator.LoadAllLanguages();
TestSuiteDir := System.Environment.CurrentDirectory;

View file

@ -6,6 +6,7 @@ using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
using Languages.Facade;
namespace PascalABCCompiler
{
@ -370,17 +371,17 @@ namespace PascalABCCompiler
//GC.Collect();
WriteColorText(Compiler.Banner + "\nCopyright (c) 2005-2026 by Ivan Bondarev, Stanislav Mikhalkovich\n", ConsoleColor.Green);
Console.WriteLine("OK {0}ms", (DateTime.Now - ldt).TotalMilliseconds);
if (Compiler.SupportedSourceFiles.Length == 0)
if (LanguageProvider.Instance.Languages.Count == 0)
WriteColorText(StringResourcesGet("ERROR_PARSERS_NOT_FOUND")+Environment.NewLine, ConsoleColor.Red);
Compiler.InternalDebug.SkipPCUErrors = false;
}
public static void ShowConnectedParsers()
{
if (Compiler.SupportedSourceFiles.Length > 0)
if (LanguageProvider.Instance.Languages.Count > 0)
{
Console.Write(StringResourcesGet("CONNECTED_PARSERS"));
foreach (PascalABCCompiler.SupportedSourceFile ssf in Compiler.SupportedSourceFiles)
Console.Write(ssf+"; ");
foreach (ILanguage lang in LanguageProvider.Instance.Languages)
Console.Write(FormatTools.LanguageAndExtensionsFormatted(lang.Name, lang.FilesExtensions)+"; ");
Console.WriteLine();
}
}

View file

@ -28,16 +28,16 @@ namespace PascalABCCompiler
return StringResources.Get(StringsPrefix + Key);
}
public static void ShowConnectedParsers()
/*public static void ShowConnectedParsers()
{
if (Compiler.SupportedSourceFiles.Length > 0)
if (LanguageProvider.Instance.Languages.Count > 0)
{
Console.Write(StringResourcesGet("CONNECTED_PARSERS"));
foreach (PascalABCCompiler.SupportedSourceFile ssf in Compiler.SupportedSourceFiles)
Console.Write(ssf+"; ");
foreach (ILanguage lang in LanguageProvider.Instance.Languages)
Console.Write(FormatTools.LanguageAndExtensionsFormatted(lang.Name, lang.FilesExtensions)+"; ");
Console.WriteLine();
}
}
}*/
public static bool CheckAndSplitDirective(string directive, out string name, out string value)
{