Compare commits
2 commits
master
...
features/s
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b013f24d12 | ||
|
|
1313d75374 |
44
.github/workflows/buildandruntests.yml
vendored
44
.github/workflows/buildandruntests.yml
vendored
|
|
@ -1,44 +0,0 @@
|
|||
name: Build & Run all tests (release)
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
release:
|
||||
types:
|
||||
- created
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: cmd
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
name: Prepare and build on Windows Server VM
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Install dependencies into Virtual Environment...
|
||||
run: _RegisterHelixNUnit.bat
|
||||
|
||||
- name: Build project in Release-mode, compile Pas-units, run tests
|
||||
run: _RebuildReleaseAndRunTestsForGitHubActions.bat
|
||||
timeout-minutes: 40
|
||||
env:
|
||||
PABCNET_BUILD_MODE: Release
|
||||
PABCNET_RUN_TESTS: false
|
||||
PABCNET_INC_BUILD: false
|
||||
PABCNET_VERBOSE: false
|
||||
|
||||
#- name: Publish artifacts (5/5)...
|
||||
# uses: actions/upload-artifact@v2
|
||||
# with:
|
||||
# name: All_distros
|
||||
# path: Release
|
||||
35
.github/workflows/buildandruntestslinux.yml
vendored
35
.github/workflows/buildandruntestslinux.yml
vendored
|
|
@ -1,35 +0,0 @@
|
|||
name: Build & Run all tests on Ubuntu (release)
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
release:
|
||||
types:
|
||||
- created
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: sh
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
name: Prepare and build on Ubuntu VM
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Build project in Release-mode, compile Pas-units, run tests
|
||||
run: ./_RebuildReleaseAndRunTests.sh
|
||||
timeout-minutes: 40
|
||||
env:
|
||||
PABCNET_BUILD_MODE: Release
|
||||
PABCNET_RUN_TESTS: false
|
||||
PABCNET_INC_BUILD: false
|
||||
PABCNET_VERBOSE: false
|
||||
|
||||
#- name: Publish artifacts (5/5)...
|
||||
# uses: actions/upload-artifact@v2
|
||||
# with:
|
||||
# name: All_distros
|
||||
# path: Release
|
||||
190
.gitignore
vendored
190
.gitignore
vendored
|
|
@ -1,154 +1,52 @@
|
|||
|
||||
.vs
|
||||
|
||||
*/**/bin
|
||||
bin/Lib/*.pcu
|
||||
bin/Lib/*.xml
|
||||
bin/Lib/*.dll
|
||||
bin/*.dll
|
||||
bin/*.pdb
|
||||
bin/*.config
|
||||
bin/*.xml
|
||||
bin/log.txt
|
||||
bin/CompilerController.ini
|
||||
|
||||
# general ignore
|
||||
*.pcu
|
||||
*.pdb
|
||||
**/_vti_cnf
|
||||
**/_vti_pvt
|
||||
|
||||
# vs internal files
|
||||
**/.vs/*
|
||||
TestSuite/CompilationSamples/*.pcu
|
||||
TestSuite/CompilationSamples/*.pdb
|
||||
TestSuite/CompilationSamples/*.exe
|
||||
TestSuite/CompilationSamples/*.xml
|
||||
TestSuite/exe
|
||||
TestSuite/formatter_tests/output
|
||||
|
||||
TestSuite/usesunits/*.pcu
|
||||
|
||||
TestSuite/pabcrtl_tests/*.pdb
|
||||
TestSuite/pabcrtl_tests/*.exe
|
||||
|
||||
# dirs for build temp files
|
||||
**/obj/*
|
||||
**/bin/*
|
||||
!/bin/*
|
||||
/bin/*.pdb
|
||||
!/Utils/NSIS/Unicode/Bin/*
|
||||
!/Utils/NodesGeneratorNew/NodesGenerator_old/bin/*
|
||||
!/Utils/NodesGeneratorNew/Scintilla/Sources/bin/*
|
||||
!/Utils/Old/NodesGeneratorOld/bin/*
|
||||
!/Utils/Old/NodesGeneratorOld0/bin/*
|
||||
!/YMC/bin/*
|
||||
|
||||
|
||||
|
||||
# local user files
|
||||
*.csproj.user
|
||||
/bin/CompilerController.ini
|
||||
|
||||
|
||||
|
||||
# binary files, generated by build
|
||||
**/CodeCompletion.dll
|
||||
**/CodeTemplatesPlugin.dll
|
||||
**/Compiler.dll
|
||||
**/CompilerController.dll
|
||||
**/CompilerTools.dll
|
||||
**/Errors.dll
|
||||
**/GPPG.dll
|
||||
**/HelpBuilder.dll
|
||||
**/InternalErrorReport.dll
|
||||
**/LambdaAnySynToSemConverter.dll
|
||||
**/LanguageConverter.dll
|
||||
**/Localization.dll
|
||||
**/NETGenerator.dll
|
||||
**/OptimizerConversion.dll
|
||||
**/PABCRtl.dll
|
||||
**/LanguageIntegrator.dll
|
||||
**/StringConstants.dll
|
||||
**/ParserTools.dll
|
||||
**/PascalABCParser.dll
|
||||
**/PascalABCLanguageInfo.dll
|
||||
**/PluginsSupport.dll
|
||||
**/PluginsSupportLinux.dll
|
||||
**/Properties.Resources.Designer.cs.dll
|
||||
**/PT4Provider.dll
|
||||
**/SemanticTree.dll
|
||||
**/SemanticTreeVisualisator.dll
|
||||
**/SyntaxTree.dll
|
||||
**/SyntaxTreeConverters.dll
|
||||
**/SyntaxTreeVisualisator.dll
|
||||
**/SyntaxVisitors.dll
|
||||
**/TeacherControlPlugin.dll
|
||||
**/TestPlugin.dll
|
||||
**/TreeConverter.dll
|
||||
**/VBNETParser.dll
|
||||
**/PABCCoreUtils.dll
|
||||
**/pabcnetc.exe
|
||||
**/pabcnetc.exe.config
|
||||
**/pabcnetcclear.exe
|
||||
**/pabcnetcclear.exe.config
|
||||
**/PascalABCNET.exe
|
||||
**/PascalABCNET.exe.config
|
||||
**/PascalABCNETLinux.exe
|
||||
**/PascalABCNETLinux.exe.config
|
||||
|
||||
**/SPythonLanguageInfo.dll
|
||||
**/SPythonParser.dll
|
||||
**/SPythonParser.dll.config
|
||||
**/SPythonStandardTreeConverter.dll
|
||||
**/SPythonSyntaxTreeVisitor.dll
|
||||
|
||||
# external .dll files copied to bin
|
||||
/bin/AvalonDock.dll
|
||||
/bin/PT4Tools.dll
|
||||
/bin/Debugger.Core.dll
|
||||
/bin/ICSharpCode.AvalonEdit.dll
|
||||
/bin/ICSharpCode.Core.dll
|
||||
/bin/ICSharpCode.Core.Presentation.dll
|
||||
/bin/ICSharpCode.Core.WinForms.dll
|
||||
/bin/ICSharpCode.NRefactory.dll
|
||||
/bin/ICSharpCode.SharpDevelop.dll
|
||||
/bin/ICSharpCode.SharpDevelop.Dom.dll
|
||||
/bin/ICSharpCode.SharpDevelop.Widgets.dll
|
||||
/bin/ICSharpCode.TextEditor.dll
|
||||
/bin/ICSharpCode.TextEditorLinux.dll
|
||||
/bin/WeifenLuo.WinFormsUI.Docking.dll
|
||||
/bin/WeifenLuo.WinFormsUI.DockingLinux.dll
|
||||
/bin/WeifenLuo.WinFormsUI.Docking.ThemeVS2005.dll
|
||||
/bin/WeifenLuo.WinFormsUI.Docking.ThemeVS2005Linux.dll
|
||||
|
||||
# from nuget
|
||||
/bin/ICSharpCode.SharpZipLib.dll
|
||||
/bin/SharpDisasm.dll
|
||||
/bin/Mono.Cecil.dll
|
||||
/bin/Mono.Cecil.Mdb.dll
|
||||
/bin/Mono.Cecil.Pdb.dll
|
||||
/bin/Mono.Cecil.Rocks.dll
|
||||
/bin/Microsoft.Bcl.HashCode.dll
|
||||
/bin/System.Buffers.dll
|
||||
/bin/System.Collections.Immutable.dll
|
||||
/bin/System.Formats.Nrbf.dll
|
||||
/bin/System.Memory.dll
|
||||
/bin/System.Numerics.Vectors.dll
|
||||
/bin/System.Reflection.Metadata.dll
|
||||
/bin/System.Resources.Extensions.dll
|
||||
/bin/System.Runtime.CompilerServices.Unsafe.dll
|
||||
/bin/System.ValueTuple.dll
|
||||
#TODO копируется только при сборке pabcnetc.sln - это норм?
|
||||
# - в самом проекте написано что его надо удалить...
|
||||
/bin/YieldConversionSyntax.dll
|
||||
|
||||
# Debug-only intellisense problems
|
||||
/bin/log.txt
|
||||
|
||||
|
||||
# Regenerated before being run by .bat
|
||||
#TODO remove this from index
|
||||
#/bin/TestRunner.exe
|
||||
/bin/GitIgnoreTester.exe
|
||||
|
||||
|
||||
|
||||
# this is added to index at "/bin/lib"
|
||||
/ReleaseGenerators/nunit.framework.dll
|
||||
|
||||
|
||||
|
||||
# NSIS
|
||||
!/Utils/NSIS2/Bin/*
|
||||
|
||||
|
||||
|
||||
#TODO Метаданные .dll, наверное их забывает удалить после тестирования их генерации?
|
||||
/bin/mscorlib.txt
|
||||
/bin/System.Data.dll.txt
|
||||
/bin/System.dll.txt
|
||||
/bin/System.Xml.dll.txt
|
||||
|
||||
#TODO Why?
|
||||
/AddIns/ICSharpCode.SharpDevelop.addin
|
||||
ReleaseGenerators/*.pdb
|
||||
ReleaseGenerators/PABCRtl/*.dll
|
||||
ReleaseGenerators/PABCRtl/*.pcu
|
||||
ReleaseGenerators/PABCRtl/*.pdb
|
||||
|
||||
**/obj
|
||||
|
||||
ReleaseGenerators/RebuildStandartModules.exe
|
||||
TestSuite/CompilationSamples/ClientServer.pas
|
||||
TestSuite/CompilationSamples/PABCExtensions.pas
|
||||
TestSuite/CompilationSamples/PT4MakerNetX.pas
|
||||
TestSuite/CompilationSamples/Speech.pas
|
||||
TestSuite/CompilationSamples/Робот.pas
|
||||
TestSuite/CompilationSamples/Чертежник.pas
|
||||
TestSuite/CompilationSamples/Controls.pas
|
||||
TestSuite/CompilationSamples/GraphWPF.pas
|
||||
TestSuite/CompilationSamples/NumLibABC.pas
|
||||
bin/PascalABCNET.exe
|
||||
bin/System.Data.dll.txt
|
||||
bin/System.Xml.dll.txt
|
||||
bin/System.dll.txt
|
||||
bin/mscorlib.txt
|
||||
bin/pabcnetc.exe
|
||||
bin/pabcnetcclear.exe
|
||||
|
|
|
|||
|
|
@ -1,35 +0,0 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// Общие сведения об этой сборке предоставляются следующим набором
|
||||
// набора атрибутов. Измените значения этих атрибутов для изменения сведений,
|
||||
// связанные со сборкой.
|
||||
[assembly: AssemblyTitle("SPythonLanguage")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("SPythonLanguage")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2026")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми
|
||||
// для компонентов COM. Если необходимо обратиться к типу в этой сборке через
|
||||
// COM, задайте атрибуту ComVisible значение TRUE для этого типа.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM
|
||||
[assembly: Guid("dff88e9f-afb3-4986-84fe-77f8a04cb6f0")]
|
||||
|
||||
// Сведения о версии сборки состоят из указанных ниже четырех значений:
|
||||
//
|
||||
// Основной номер версии
|
||||
// Дополнительный номер версии
|
||||
// Номер сборки
|
||||
// Редакция
|
||||
//
|
||||
// Можно задать все значения или принять номера сборки и редакции по умолчанию
|
||||
// используя "*", как показано ниже:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,53 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
using Languages.Facade;
|
||||
using PascalABCCompiler.SyntaxTreeConverters;
|
||||
using PascalABCCompiler.SystemLibrary;
|
||||
using PascalABCCompiler.TreeConverter;
|
||||
|
||||
namespace Languages.SPython
|
||||
{
|
||||
public class SPythonLanguage : BaseLanguage
|
||||
{
|
||||
public SPythonLanguage() : base(
|
||||
|
||||
languageInformation: new Frontend.Data.SPythonLanguageInformation(),
|
||||
languageIntellisenseSupport: new Frontend.Data.SPythonIntellisenseSupport(),
|
||||
parser: new SPythonParser.SPythonLanguageParser(),
|
||||
docParser: null,
|
||||
|
||||
syntaxTreeConverters: new List<ISyntaxTreeConverter>() { new Frontend.Converters.StandardSyntaxTreeConverter(), new SyntaxSemanticVisitors.LambdaAnyConverter() }
|
||||
)
|
||||
{
|
||||
((SPythonParser.SPythonLanguageParser)Parser).SyntaxTreeConvertersForIntellisense = SyntaxTreeConverters;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// TODO: требуется проверка и настройка работы EVA
|
||||
/// </summary>
|
||||
public override void SetSemanticConstants()
|
||||
{
|
||||
SemanticRulesConstants.ClassBaseType = SystemLibrary.object_type;
|
||||
SemanticRulesConstants.StructBaseType = SystemLibrary.value_type;
|
||||
SemanticRulesConstants.AddResultVariable = true;
|
||||
SemanticRulesConstants.ZeroBasedStrings = true;
|
||||
SemanticRulesConstants.FastStrings = false;
|
||||
SemanticRulesConstants.InitStringAsEmptyString = true;
|
||||
SemanticRulesConstants.UseDivisionAssignmentOperatorsForIntegerTypes = false;
|
||||
SemanticRulesConstants.ManyVariablesOneInitializator = false;
|
||||
SemanticRulesConstants.OrderIndependedMethodNames = true;
|
||||
SemanticRulesConstants.OrderIndependedFunctionNames = false;
|
||||
SemanticRulesConstants.OrderIndependedTypeNames = false;
|
||||
SemanticRulesConstants.EnableExitProcedure = true;
|
||||
SemanticRulesConstants.StrongPointersTypeCheckForDotNet = true;
|
||||
SemanticRulesConstants.AllowChangeLoopVariable = false;
|
||||
SemanticRulesConstants.AllowGlobalVisibilityForPABCDll = true;
|
||||
SemanticRulesConstants.AllowMethodCallsWithoutParentheses = false;
|
||||
}
|
||||
|
||||
public override void SetSyntaxTreeToSemanticTreeConverter()
|
||||
{
|
||||
SyntaxTreeToSemanticTreeConverter = new SPythonSyntaxTreeVisitor.spython_syntax_tree_visitor(LanguageProvider.Instance.MainLanguage.SyntaxTreeToSemanticTreeConverter);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net40</TargetFramework>
|
||||
|
||||
<RootNamespace>Languages.SPython</RootNamespace>
|
||||
|
||||
<OutputPath>..\..\..\bin\</OutputPath>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\LambdaAnySynToSemConverter\LambdaAnySynToSemConverter.csproj" />
|
||||
<ProjectReference Include="..\..\..\LanguageIntegrator\LanguageIntegrator.csproj" />
|
||||
<ProjectReference Include="..\..\..\Localization\Localization.csproj" />
|
||||
<ProjectReference Include="..\..\..\ParserTools\ParserTools.csproj" />
|
||||
<ProjectReference Include="..\..\..\SyntaxTree\SyntaxTree.csproj" />
|
||||
<ProjectReference Include="..\..\..\SyntaxVisitors\SyntaxVisitors.csproj" />
|
||||
<ProjectReference Include="..\..\..\TreeConverter\TreeConverter.csproj" />
|
||||
<ProjectReference Include="..\SemanticAnalyzers\SPythonSyntaxTreeVisitor\SPythonSyntaxTreeVisitor.csproj" />
|
||||
<ProjectReference Include="..\SPythonParserKrylovMovchan\SPythonParser.csproj" />
|
||||
<ProjectReference Include="..\SyntaxTreeConverters\SPythonStandardTreeConverter\SPythonStandardTreeConverter.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
using PascalABCCompiler.Parsers;
|
||||
using PascalABCCompiler.ParserTools.Directives;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Languages.SPython.Frontend.Data
|
||||
{
|
||||
internal class SPythonLanguageInformation : ILanguageInformation
|
||||
{
|
||||
public string Name => "SPython";
|
||||
|
||||
public string Version => "0.0.1";
|
||||
|
||||
public string Copyright => "Copyright © 2023-2026 by Vladislav Krylov, Egor Movchan";
|
||||
|
||||
public string[] FilesExtensions => new string[] { ".pys" };
|
||||
|
||||
public string[] SystemUnitNames => new string[] { "SPythonSystem", "SPythonHidden", "SPythonSystemPys" };
|
||||
|
||||
public bool SyntaxTreeIsConvertedAfterUsedModulesCompilation => true;
|
||||
|
||||
public BaseKeywords KeywordsStorage { get; } = new SPythonParser.SPythonKeywords();
|
||||
|
||||
public Dictionary<string, DirectiveInfo> ValidDirectives { get; protected set; }
|
||||
|
||||
public string CommentSymbol => "#";
|
||||
|
||||
public bool CaseSensitive => true;
|
||||
|
||||
private readonly Dictionary<string, string> specialModulesAliases = new Dictionary<string, string>
|
||||
{
|
||||
{ "time", "time1" },
|
||||
{ "random", "random1" },
|
||||
};
|
||||
|
||||
public Dictionary<string, string> SpecialModulesAliases => specialModulesAliases;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using PascalABCCompiler.Errors;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace SPythonParser
|
||||
{
|
||||
public class SPythonUnexpectedToken : SyntaxError
|
||||
{
|
||||
private string _message;
|
||||
private string _expected;
|
||||
public SPythonUnexpectedToken(string _file_name, string expected, SourceContext _source_context, syntax_tree_node _node)
|
||||
: base("", _file_name, _source_context, _node)
|
||||
{
|
||||
_message = string.Format(StringResources.Get("EXPECTED{0}"), expected);
|
||||
_expected = expected;
|
||||
}
|
||||
|
||||
public override string Message
|
||||
{
|
||||
get
|
||||
{
|
||||
return _message;
|
||||
}
|
||||
}
|
||||
|
||||
public string Expected
|
||||
{
|
||||
get
|
||||
{
|
||||
return _expected;
|
||||
}
|
||||
set
|
||||
{
|
||||
_expected = value;
|
||||
_message = string.Format(StringResources.Get("EXPECTED{0}"), _expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,238 +0,0 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Collections.Generic;
|
||||
using SyntaxVisitors;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace SPythonParser
|
||||
{
|
||||
public class IndentArranger
|
||||
{
|
||||
private int lineCounter = -1;
|
||||
|
||||
// количество пробелов соответствующее одному \t (в одном отступе)
|
||||
private const int indentSpaceNumber = 4;
|
||||
private const string indentToken = "#{";
|
||||
private const string unindentToken = "#}";
|
||||
private const string badIndentToken = "#!";
|
||||
private const string programBeginWithIndentToken = "#b";
|
||||
private const string endOfLineToken = "#;";
|
||||
private const string endOfFIleToken = "#$";
|
||||
public const string createdFileNameAddition = "_processed";
|
||||
|
||||
// регулярное выражение разбивающее строку программы на группы, последняя из которых - комментарий в конце строки
|
||||
private static readonly Regex programLineRegex = new Regex("^(([^\n\"\'#])+|(\'([^\'\n\\\\]|\\\\.)*\')|(\"([^\"\n\\\\]|\\\\.)*\"))*(#.*)?$");
|
||||
|
||||
private static readonly Regex reg = new Regex(@"'([^'\\]*(\\.[^'\\]*)*)'|""([^""\\]*(\\.[^""\\]*)*)""");
|
||||
|
||||
|
||||
public IndentArranger() {}
|
||||
|
||||
public void ProcessSourceText(ref string sourceText)
|
||||
{
|
||||
//string[] programLines = sourceText.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
|
||||
// В редакторе в особых случаях добавляется \n вместо \r\n
|
||||
string[] programLines = sourceText.Split(new string[] { "\n" }, StringSplitOptions.None);
|
||||
|
||||
// удаляем комментарии в тексте программы
|
||||
EraseComments(ref programLines);
|
||||
|
||||
// добавляем токены для начала/конца отступов и ; в конце stmt
|
||||
ArrangeIndents(ref programLines);
|
||||
|
||||
sourceText = String.Join("\n", programLines);
|
||||
|
||||
// нужен токен в конце для правильного позиционирования ошибок,
|
||||
// допущенных в конце программы
|
||||
sourceText += endOfFIleToken;
|
||||
|
||||
// создание файла с полученным текстом для дебага
|
||||
//File.WriteAllText("./processed_file.txt", sourceText);
|
||||
}
|
||||
|
||||
private void EraseComments(ref string[] programLines)
|
||||
{
|
||||
for (int i = 0; i < programLines.Length; ++i)
|
||||
{
|
||||
Match programLineMatch = programLineRegex.Match(programLines[i]);
|
||||
if (programLineMatch.Success)
|
||||
{
|
||||
Group programLineComment = programLineMatch.Groups[programLineMatch.Groups.Count - 1];
|
||||
if (programLineComment.Success)
|
||||
programLines[i] = programLines[i].Substring(0, programLineComment.Index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int bracketCount = 0;
|
||||
int prevBracketCount = 0;
|
||||
|
||||
private void CountBrackets(string programLine)
|
||||
{
|
||||
string cleanLine = reg.Replace(programLine, match => "");
|
||||
|
||||
foreach (char c in cleanLine)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '(':
|
||||
case '{':
|
||||
case '[':
|
||||
++bracketCount;
|
||||
break;
|
||||
|
||||
case ')':
|
||||
case '}':
|
||||
case ']':
|
||||
--bracketCount;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// считывает первый токен в строке (с первого символа латиницы или _)
|
||||
// возвращает тип этого токена
|
||||
private bool IsFirstTokenElseOrElif(string line)
|
||||
{
|
||||
int beginIndex = 0;
|
||||
for (beginIndex = 0; beginIndex < line.Length; ++beginIndex)
|
||||
if (!Char.IsWhiteSpace(line[beginIndex]))
|
||||
break;
|
||||
if (line.Length < beginIndex + 4) return false;
|
||||
|
||||
// получаем строковое представление токена
|
||||
string firstToken = line.Substring(beginIndex, 4);
|
||||
return firstToken == "else" || firstToken == "elif";
|
||||
}
|
||||
|
||||
private void ArrangeIndents(ref string[] programLines)
|
||||
{
|
||||
Stack<int> indentStack = new Stack<int>();
|
||||
indentStack.Push(0);
|
||||
bool skipped_first = false;
|
||||
|
||||
foreach (var line in programLines)
|
||||
{
|
||||
lineCounter++;
|
||||
prevBracketCount = bracketCount;
|
||||
CountBrackets(line);
|
||||
if (lineCounter > 0 && LineEndsWithBackSlash(ref programLines[lineCounter - 1]))
|
||||
continue;
|
||||
if (prevBracketCount != 0)
|
||||
continue;
|
||||
|
||||
bool isEmptyLine = true; // строка не содержит символов кроме \s\t\n\r
|
||||
int currentLineSpaceCounter = 0;
|
||||
|
||||
for (int i = 0; i < line.Length; ++i)
|
||||
{
|
||||
if (line[i] == '\t')
|
||||
{
|
||||
// один \t выравнивает до следующего отступа
|
||||
currentLineSpaceCounter += indentSpaceNumber;
|
||||
currentLineSpaceCounter &= ~(indentSpaceNumber - 1);
|
||||
}
|
||||
else if (char.IsWhiteSpace(line[i]))
|
||||
currentLineSpaceCounter++;
|
||||
else
|
||||
{
|
||||
isEmptyLine = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isEmptyLine) continue;
|
||||
|
||||
int previosSpaceCounter = indentStack.Peek();
|
||||
// текущий отступ соответствует предыдущему отступу
|
||||
if (currentLineSpaceCounter == previosSpaceCounter)
|
||||
{
|
||||
if (!skipped_first)
|
||||
{
|
||||
skipped_first = true;
|
||||
continue;
|
||||
}
|
||||
AddSemicolonIfNeeded(ref programLines[lineCounter - 1]);
|
||||
}
|
||||
// текущий отступ соответствует увеличению
|
||||
else if (currentLineSpaceCounter > previosSpaceCounter)
|
||||
{
|
||||
if (skipped_first && lineCounter != 0)
|
||||
{
|
||||
programLines[lineCounter - 1] += indentToken;
|
||||
indentStack.Push(currentLineSpaceCounter);
|
||||
}
|
||||
else
|
||||
programLines[lineCounter] = programBeginWithIndentToken;
|
||||
}
|
||||
// оставшиеся случаи: отступ некорректный или уменьшение на один или несколько отступов
|
||||
else
|
||||
{
|
||||
int unindentCounter = 0;
|
||||
while (currentLineSpaceCounter < previosSpaceCounter)
|
||||
{
|
||||
indentStack.Pop();
|
||||
unindentCounter++;
|
||||
previosSpaceCounter = indentStack.Peek();
|
||||
}
|
||||
|
||||
// текущий отступ соответствует уменьшению на один или несколько отступов
|
||||
if (currentLineSpaceCounter == previosSpaceCounter)
|
||||
{
|
||||
// если сейчас ветка elif/else, то это не конец команды
|
||||
// поэтому ставить ; в конце не надо (она будет после блока elif/else)
|
||||
bool isEndOfStatement = !IsFirstTokenElseOrElif(line);
|
||||
|
||||
unindentCounter--;
|
||||
AddSemicolonIfNeeded(ref programLines[lineCounter - 1]);
|
||||
|
||||
programLines[lineCounter - 1] += unindentToken +
|
||||
string.Concat(Enumerable.Repeat(endOfLineToken + unindentToken, unindentCounter))
|
||||
+ (isEndOfStatement ? endOfLineToken : "");
|
||||
}
|
||||
// количество пробелов в строке является некорректным
|
||||
// (не соответствует количеству пробелов в строке с любым отступом)
|
||||
else // currentLineSpaceCounter > indentStack.Peek()
|
||||
{
|
||||
if (lineCounter != 0)
|
||||
programLines[lineCounter - 1] += badIndentToken;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (lineCounter != -1 && indentStack.Count() > 1)
|
||||
{
|
||||
// закрытие всех отступов в конце файла
|
||||
AddSemicolonIfNeeded(ref programLines[lineCounter]);
|
||||
programLines[lineCounter] += unindentToken +
|
||||
string.Concat(Enumerable.Repeat(endOfLineToken + unindentToken, indentStack.Count() - 2));
|
||||
}
|
||||
}
|
||||
|
||||
private int IndexOfLastSignificantSymbol(string s)
|
||||
{
|
||||
int i = s.Length - 1;
|
||||
while (i > -1 && Char.IsWhiteSpace(s[i])) --i;
|
||||
return i;
|
||||
}
|
||||
|
||||
private bool LineEndsWithBackSlash(ref string s)
|
||||
{
|
||||
int i = IndexOfLastSignificantSymbol(s);
|
||||
if (i == -1 || s[i] != '\\')
|
||||
return false;
|
||||
s = s.Substring(0, i);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void AddSemicolonIfNeeded(ref string s)
|
||||
{
|
||||
int i = IndexOfLastSignificantSymbol(s);
|
||||
if (i == -1 || s[i] != ';')
|
||||
s += endOfLineToken;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
using PascalABCCompiler.Parsers;
|
||||
using SPythonParserYacc;
|
||||
|
||||
namespace SPythonParser
|
||||
{
|
||||
|
||||
public class SPythonKeywords : BaseKeywords
|
||||
{
|
||||
|
||||
protected override string FileName => "keywordsmap.pys";
|
||||
|
||||
public SPythonKeywords() : base(true)
|
||||
{
|
||||
CreateNewKeyword("if", Tokens.IF);
|
||||
CreateNewKeyword("elif", Tokens.ELIF);
|
||||
CreateNewKeyword("else", Tokens.ELSE);
|
||||
CreateNewKeyword("while", Tokens.WHILE);
|
||||
CreateNewKeyword("for", Tokens.FOR);
|
||||
CreateNewKeyword("in", Tokens.IN);
|
||||
CreateNewKeyword("def", Tokens.DEF, KeywordKind.Function, true);
|
||||
CreateNewKeyword("return", Tokens.RETURN);
|
||||
CreateNewKeyword("break", Tokens.BREAK);
|
||||
CreateNewKeyword("continue", Tokens.CONTINUE);
|
||||
CreateNewKeyword("and", Tokens.AND);
|
||||
CreateNewKeyword("or", Tokens.OR);
|
||||
CreateNewKeyword("not", Tokens.NOT);
|
||||
CreateNewKeyword("import", Tokens.IMPORT /*, KeywordKind.Uses*/);
|
||||
CreateNewKeyword("from", Tokens.FROM);
|
||||
CreateNewKeyword("global", Tokens.GLOBAL);
|
||||
CreateNewKeyword("True", Tokens.TRUE);
|
||||
CreateNewKeyword("False", Tokens.FALSE);
|
||||
CreateNewKeyword("as", Tokens.AS);
|
||||
CreateNewKeyword("pass", Tokens.PASS);
|
||||
CreateNewKeyword("class", Tokens.CLASS, isTypeKeyword: true);
|
||||
CreateNewKeyword("lambda", Tokens.LAMBDA);
|
||||
CreateNewKeyword("exit", Tokens.EXIT);
|
||||
CreateNewKeyword("new", Tokens.NEW, KeywordKind.New);
|
||||
CreateNewKeyword("is", Tokens.IS);
|
||||
CreateNewKeyword("decltype", Tokens.DECLTYPE);
|
||||
}
|
||||
|
||||
protected override int GetIdToken() => (int)Tokens.ID;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// Общие сведения об этой сборке предоставляются следующим набором
|
||||
// набора атрибутов. Измените значения этих атрибутов для изменения сведений,
|
||||
// связанные с этой сборкой.
|
||||
[assembly: AssemblyTitle("SPythonParser")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("SPythonParser")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2026")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми
|
||||
// для компонентов COM. Если необходимо обратиться к типу в этой сборке через
|
||||
// из модели COM задайте для атрибута ComVisible этого типа значение true.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Следующий GUID представляет идентификатор typelib, если этот проект доступен из модели COM
|
||||
[assembly: Guid("81fe2baa-d100-4596-a392-f03bbe30f829")]
|
||||
|
||||
// Сведения о версии сборки состоят из указанных ниже четырех значений:
|
||||
//
|
||||
// Основной номер версии
|
||||
// Дополнительный номер версии
|
||||
// Номер сборки
|
||||
// Номер редакции
|
||||
//
|
||||
// Можно задать все значения или принять номера сборки и редакции по умолчанию
|
||||
// используя "*", как показано ниже:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,240 +0,0 @@
|
|||
%using SPythonParser;
|
||||
%using QUT.Gppg;
|
||||
%using PascalABCCompiler.SyntaxTree;
|
||||
%using PascalABCCompiler.ParserTools;
|
||||
%using SPythonParserYacc;
|
||||
%using SPythonParser;
|
||||
|
||||
%namespace SPythonParser
|
||||
|
||||
Alpha [[:IsLetter:]_]
|
||||
NonZeroDigit [1-9]
|
||||
Digit 0|{NonZeroDigit}
|
||||
AlphaDigit {Alpha}|{Digit}
|
||||
INTNUM ({NonZeroDigit}(_?{Digit})*)|0
|
||||
REALNUM ({INTNUM}?\.{INTNUM})|({INTNUM}\.)
|
||||
STRINGNUM (\'([^\'\n\\]|\\.)*\')|(\"([^\"\n\\]|\\.)*\")
|
||||
FSTRINGNUM f((\'([^\'\n\\]|\\.)*\')|(\"([^\"\n\\]|\\.)*\"))
|
||||
ID {Alpha}{AlphaDigit}*
|
||||
BIGINTNUM {INTNUM}bi
|
||||
|
||||
%{
|
||||
private SPythonKeywords keywords;
|
||||
public SPythonParserTools parserTools;
|
||||
public List<string> Defines = new List<string>();
|
||||
private int last_line_needed_colon = -1;
|
||||
private LexLocation currentLexLocation;
|
||||
private LexLocation prevLexLocation
|
||||
= new LexLocation(-1, -1, -1, -1, "");
|
||||
|
||||
public Scanner(string text, SPythonParserTools parserTools, PascalABCCompiler.Parsers.BaseKeywords keywords, List<string> defines = null)
|
||||
{
|
||||
this.parserTools = parserTools;
|
||||
this.keywords = (SPythonKeywords)keywords;
|
||||
if (defines != null)
|
||||
this.Defines.AddRange(defines);
|
||||
SetSource(text, 0);
|
||||
}
|
||||
%}
|
||||
|
||||
%%
|
||||
|
||||
{INTNUM} {
|
||||
yylval = new SPythonParserYacc.ValueType();
|
||||
currentLexLocation = CurrentLexLocation;
|
||||
yylval.ex = parserTools.create_spy_int_const(yytext,currentLexLocation);
|
||||
return (int)Tokens.INTNUM;
|
||||
}
|
||||
|
||||
{BIGINTNUM} {
|
||||
yylval = new SPythonParserYacc.ValueType();
|
||||
currentLexLocation = CurrentLexLocation;
|
||||
yylval.ex = parserTools.create_bigint_const(yytext,currentLexLocation);
|
||||
return (int)Tokens.BIGINT;
|
||||
}
|
||||
|
||||
{REALNUM} {
|
||||
yylval = new SPythonParserYacc.ValueType();
|
||||
currentLexLocation = CurrentLexLocation;
|
||||
yylval.ex = parserTools.create_double_const(yytext,currentLexLocation);
|
||||
return (int)Tokens.REALNUM;
|
||||
}
|
||||
|
||||
{STRINGNUM} {
|
||||
yylval = new SPythonParserYacc.ValueType();
|
||||
currentLexLocation = CurrentLexLocation;
|
||||
yylval.stn = parserTools.create_string_const(yytext,currentLexLocation);
|
||||
return (int)Tokens.STRINGNUM;
|
||||
}
|
||||
|
||||
{FSTRINGNUM} {
|
||||
yylval = new SPythonParserYacc.ValueType();
|
||||
currentLexLocation = CurrentLexLocation;
|
||||
yylval.ex = parserTools.create_fstring(yytext,currentLexLocation);
|
||||
return (int)Tokens.FSTRINGNUM;
|
||||
}
|
||||
|
||||
{ID} {
|
||||
string cur_yytext = yytext;
|
||||
int res = keywords.KeywordOrIDToken(cur_yytext);
|
||||
currentLexLocation = CurrentLexLocation;
|
||||
yylval = new SPythonParserYacc.ValueType();
|
||||
switch (res)
|
||||
{
|
||||
case (int)Tokens.ID:
|
||||
yylval.id = parserTools.create_ident(cur_yytext, currentLexLocation);
|
||||
break;
|
||||
case (int)Tokens.AND:
|
||||
yylval.op = new op_type_node(Operators.LogicalAND, currentLexLocation);
|
||||
yylval.op.text = cur_yytext;
|
||||
break;
|
||||
case (int)Tokens.OR:
|
||||
yylval.op = new op_type_node(Operators.LogicalOR, currentLexLocation);
|
||||
yylval.op.text = cur_yytext;
|
||||
break;
|
||||
case (int)Tokens.NOT:
|
||||
yylval.op = new op_type_node(Operators.LogicalNOT, currentLexLocation);
|
||||
yylval.op.text = cur_yytext;
|
||||
break;
|
||||
case (int)Tokens.IF:
|
||||
case (int)Tokens.ELIF:
|
||||
case (int)Tokens.ELSE:
|
||||
case (int)Tokens.WHILE:
|
||||
case (int)Tokens.FOR:
|
||||
case (int)Tokens.DEF:
|
||||
last_line_needed_colon = CurrentLexLocation.StartLine;
|
||||
break;
|
||||
case (int)Tokens.CLASS:
|
||||
case (int)Tokens.LAMBDA:
|
||||
parserTools.AddErrorFromResource("UNSUPPORTED_CONSTRUCTION_{0}", currentLexLocation, yytext);
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
"//=" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.AssignmentIntDivision); return (int)Tokens.INTDIVISIONEQUAL; }
|
||||
|
||||
"+=" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.AssignmentAddition); return (int)Tokens.PLUSEQUAL; }
|
||||
"-=" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.AssignmentSubtraction); return (int)Tokens.MINUSEQUAL; }
|
||||
"*=" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.AssignmentMultiplication); return (int)Tokens.STAREQUAL; }
|
||||
"/=" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.AssignmentDivision); return (int)Tokens.DIVEQUAL; }
|
||||
|
||||
"+" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.Plus); return (int)Tokens.PLUS; }
|
||||
"-" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.Minus); return (int)Tokens.MINUS; }
|
||||
"*" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.Multiplication); return (int)Tokens.STAR; }
|
||||
"//" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.IntegerDivision); return (int)Tokens.SLASHSLASH; }
|
||||
"/" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.Division); return (int)Tokens.DIVIDE; }
|
||||
"%" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.ModulusRemainder); return (int)Tokens.PERCENTAGE; }
|
||||
|
||||
"<=" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.LessEqual); return (int)Tokens.LESSEQUAL; }
|
||||
">=" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.GreaterEqual); return (int)Tokens.GREATEREQUAL; }
|
||||
"<" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.Less); return (int)Tokens.LESS; }
|
||||
">" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.Greater); return (int)Tokens.GREATER; }
|
||||
"==" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.Equal); return (int)Tokens.EQUAL; }
|
||||
"!=" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.NotEqual); return (int)Tokens.NOTEQUAL; }
|
||||
"=" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.Assignment); return (int)Tokens.ASSIGN; }
|
||||
|
||||
//"~" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.BitwiseNOT); return (int)Tokens.BINNOT; }
|
||||
"~" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.LogicalNOT); return (int)Tokens.BINNOT; }
|
||||
//"&" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.BitwiseAND); return (int)Tokens.BINAND; }
|
||||
"&" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.LogicalAND); return (int)Tokens.BINAND; }
|
||||
//"|" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.BitwiseOR); return (int)Tokens.BINOR; }
|
||||
"|" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.LogicalOR); return (int)Tokens.BINOR; }
|
||||
"<<" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.BitwiseLeftShift); return (int)Tokens.SHL; }
|
||||
">>" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.BitwiseRightShift); return (int)Tokens.SHR; }
|
||||
"^" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.BitwiseXOR); return (int)Tokens.BINXOR; }
|
||||
|
||||
//"&" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.BitwiseAND); return (int)Tokens.BINAND; }
|
||||
"&=" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.AssignmentBitwiseAND); return (int)Tokens.BINANDEQUAL; }
|
||||
//"|" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.BitwiseOR); return (int)Tokens.BINOR; }
|
||||
"|=" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.AssignmentBitwiseOR); return (int)Tokens.BINOREQUAL; }
|
||||
"<<=" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.AssignmentBitwiseLeftShift); return (int)Tokens.SHLEQUAL; }
|
||||
">>=" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.AssignmentBitwiseRightShift); return (int)Tokens.SHREQUAL; }
|
||||
"^=" { yylval = new SPythonParserYacc.ValueType(); yylval.op = new op_type_node(Operators.AssignmentBitwiseXOR); return (int)Tokens.BINXOREQUAL; }
|
||||
|
||||
|
||||
"#{" { yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.INDENT; }
|
||||
"#}" { yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.UNINDENT; }
|
||||
"#;" { yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.END_OF_LINE; }
|
||||
|
||||
"{" { yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.LBRACE; }
|
||||
"}" { yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.RBRACE; }
|
||||
"[" { yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.LBRACKET; }
|
||||
"]" { yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.RBRACKET; }
|
||||
|
||||
"->" { yylval = new SPythonParserYacc.ValueType(); yylval.ti = new token_info(yytext); return (int)Tokens.ARROW; }
|
||||
|
||||
"." { yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.DOT; }
|
||||
"," { yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.COMMA; }
|
||||
":" { yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.COLON; }
|
||||
";" { yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.SEMICOLON; }
|
||||
"(" { yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.LPAR; }
|
||||
")" { yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.RPAR; }
|
||||
"**" { yylval = new SPythonParserYacc.ValueType(); return (int)Tokens.STARSTAR; }
|
||||
|
||||
\<\<expression\>\> { return (int)Tokens.tkParseModeExpression; }
|
||||
\<\<statement\>\> { return (int)Tokens.tkParseModeStatement; }
|
||||
\<\<type\>\> { return (int)Tokens.tkParseModeType; }
|
||||
|
||||
"#!" {
|
||||
parserTools.AddErrorFromResource("WRONG_INDENT",
|
||||
new LexLocation(CurrentLexLocation.StartLine + 1, 0, CurrentLexLocation.StartLine + 1, 0));
|
||||
return (int)Tokens.EOF;
|
||||
}
|
||||
|
||||
"#b" {
|
||||
parserTools.AddErrorFromResource("PROGRAM_BEGIN_WITH_INDENT",
|
||||
CurrentLexLocation);
|
||||
return (int)Tokens.EOF;
|
||||
}
|
||||
|
||||
"#$" {
|
||||
return (int)Tokens.END_OF_FILE;
|
||||
}
|
||||
|
||||
[^ \r\n] {
|
||||
parserTools.AddErrorFromResource("UNEXPECTED_TOKEN_{0}", CurrentLexLocation, yytext);
|
||||
return (int)Tokens.EOF;
|
||||
}
|
||||
|
||||
%{
|
||||
//yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
|
||||
prevLexLocation = yylloc;
|
||||
if (currentLexLocation != null)
|
||||
yylloc = currentLexLocation;
|
||||
else
|
||||
yylloc = CurrentLexLocation;
|
||||
|
||||
currentLexLocation = null;
|
||||
%}
|
||||
|
||||
%%
|
||||
|
||||
public LexLocation CurrentLexLocation
|
||||
{
|
||||
get {
|
||||
return new LexLocation(tokLin, tokCol, tokELin, tokECol, parserTools.currentFileName);
|
||||
}
|
||||
}
|
||||
|
||||
public override void yyerror(string format, params object[] args)
|
||||
{
|
||||
string expected = parserTools.ExpectedToken(last_line_needed_colon == prevLexLocation.StartLine, args);
|
||||
LexLocation lexLocation = parserTools.GetLexLocation(
|
||||
yytext, expected, prevLexLocation, CurrentLexLocation);
|
||||
|
||||
if (yytext == "#{" && expected == "END_OF_LINE") {
|
||||
parserTools.AddErrorFromResource("WRONG_INDENT", lexLocation);
|
||||
}
|
||||
else {
|
||||
string errorMsg = parserTools.CreateErrorString(yytext, expected);
|
||||
parserTools.AddError(errorMsg, lexLocation);
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool yywrap()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1,123 +0,0 @@
|
|||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
using PascalABCCompiler.Parsers;
|
||||
using SPythonParserYacc;
|
||||
using PascalABCCompiler.SyntaxTreeConverters;
|
||||
|
||||
|
||||
|
||||
namespace SPythonParser
|
||||
{
|
||||
|
||||
public class SPythonLanguageParser : BaseParser
|
||||
{
|
||||
public List<ISyntaxTreeConverter> SyntaxTreeConvertersForIntellisense { get; set; }
|
||||
|
||||
protected override syntax_tree_node BuildTreeInNormalMode(string FileName, string Text, bool compilingNotMainProgram, List<string> DefinesList = null)
|
||||
{
|
||||
syntax_tree_node root = Parse(Text, FileName, false, compilingNotMainProgram, DefinesList);
|
||||
|
||||
if (Errors.Count > 0)
|
||||
return null;
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
public syntax_tree_node Parse(string Text, string fileName, bool buildTreeForFormatter = false, bool compilingNotMainProgram = false, List<string> definesList = null)
|
||||
{
|
||||
#if DEBUG
|
||||
#if _ERR
|
||||
FileInfo f = new FileInfo(FileName);
|
||||
var sv = Path.ChangeExtension(FileName,".grmtrack1");
|
||||
var sw = new StreamWriter(sv);
|
||||
Console.SetError(sw);
|
||||
#endif
|
||||
#endif
|
||||
SPythonParserTools parserTools = new SPythonParserTools(Errors, Warnings, LanguageInformation.ValidDirectives, buildTreeForFormatter, false,
|
||||
Path.GetFullPath(fileName), CompilerDirectives); // контекст сканера и парсера
|
||||
|
||||
|
||||
IndentArranger ia = new IndentArranger();
|
||||
ia.ProcessSourceText(ref Text);
|
||||
|
||||
var scanner = new Scanner(Text, parserTools, LanguageInformation.KeywordsStorage, definesList);
|
||||
|
||||
SPythonGPPGParser parser = new SPythonGPPGParser(scanner, parserTools, compilingNotMainProgram);
|
||||
|
||||
if (!parser.Parse())
|
||||
if (Errors.Count == 0)
|
||||
parserTools.AddErrorFromResource("UNEXPECTED_SYNTAX_ERROR", null);
|
||||
#if DEBUG
|
||||
#if _ERR
|
||||
sw.Close();
|
||||
#endif
|
||||
#endif
|
||||
return parser.root;
|
||||
}
|
||||
|
||||
protected override syntax_tree_node BuildTreeInTypeExprMode(string FileName, string Text)
|
||||
{
|
||||
Text = string.Concat("<<type>>", Text);
|
||||
|
||||
var expr = Parse(Text, FileName) as expression;
|
||||
|
||||
if (expr == null)
|
||||
return null;
|
||||
|
||||
foreach (ISyntaxTreeConverter converter in SyntaxTreeConvertersForIntellisense)
|
||||
{
|
||||
expr = (expression)converter.Convert(expr, true);
|
||||
}
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
||||
protected override syntax_tree_node BuildTreeInExprMode(string FileName, string Text)
|
||||
{
|
||||
if (Text == string.Empty)
|
||||
return null;
|
||||
|
||||
Text = string.Concat("<<expression>>", Text);
|
||||
|
||||
var expr = Parse(Text, FileName) as expression;
|
||||
|
||||
if (expr == null)
|
||||
return null;
|
||||
|
||||
foreach (ISyntaxTreeConverter converter in SyntaxTreeConvertersForIntellisense)
|
||||
{
|
||||
expr = (expression)converter.Convert(expr, true);
|
||||
}
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
||||
protected override syntax_tree_node BuildTreeInSpecialMode(string FileName, string Text, bool compilingNotMainProgram)
|
||||
{
|
||||
return Parse(Text, FileName, compilingNotMainProgram: compilingNotMainProgram);
|
||||
}
|
||||
|
||||
protected override syntax_tree_node BuildTreeInFormatterMode(string FileName, string Text)
|
||||
{
|
||||
return Parse(Text, FileName, true);
|
||||
}
|
||||
|
||||
protected override syntax_tree_node BuildTreeInStatementMode(string FileName, string Text)
|
||||
{
|
||||
Text = string.Concat("<<statement>>", Text);
|
||||
|
||||
var st = Parse(Text, FileName) as statement;
|
||||
|
||||
if (st == null)
|
||||
return null;
|
||||
|
||||
foreach (ISyntaxTreeConverter converter in SyntaxTreeConvertersForIntellisense)
|
||||
{
|
||||
st = (statement)converter.Convert(st, true);
|
||||
}
|
||||
|
||||
return st;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net40</TargetFramework>
|
||||
|
||||
<RootNamespace>Languages.SPython.Frontend.Wrapping</RootNamespace>
|
||||
|
||||
<OutputPath>..\..\..\bin\</OutputPath>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Errors\Errors.csproj" />
|
||||
<ProjectReference Include="..\..\..\LanguageIntegrator\LanguageIntegrator.csproj" />
|
||||
<ProjectReference Include="..\..\..\Localization\Localization.csproj" />
|
||||
<ProjectReference Include="..\..\..\ParserTools\ParserTools.csproj" />
|
||||
<ProjectReference Include="..\..\..\SyntaxTree\SyntaxTree.csproj" />
|
||||
<ProjectReference Include="..\..\..\SyntaxVisitors\SyntaxVisitors.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,410 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
using PascalABCCompiler.ParserTools;
|
||||
using PascalABCCompiler.Parsers;
|
||||
using System.Text;
|
||||
using PascalABCCompiler.Errors;
|
||||
using PascalABCCompiler.ParserTools.Directives;
|
||||
using QUT.Gppg;
|
||||
using System.Text.RegularExpressions;
|
||||
using Languages.Facade;
|
||||
using static System.Net.Mime.MediaTypeNames;
|
||||
|
||||
namespace SPythonParser
|
||||
{
|
||||
public static class StringResources
|
||||
{
|
||||
private static string prefix = "SPYTHONPARSER_";
|
||||
public static string Get(string Id)
|
||||
{
|
||||
string ret = PascalABCCompiler.StringResources.Get(prefix + Id);
|
||||
if (ret == prefix + Id)
|
||||
return Id;
|
||||
else
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public class SymbolTable
|
||||
{
|
||||
private SymbolTable outerScope;
|
||||
private SortedSet<string> symbols = new SortedSet<string>();
|
||||
public SymbolTable(SymbolTable outerScope = null)
|
||||
{
|
||||
this.outerScope = outerScope;
|
||||
}
|
||||
|
||||
public bool Contains(string ident)
|
||||
{
|
||||
SymbolTable curr = this;
|
||||
|
||||
while (curr != null)
|
||||
{
|
||||
if (curr.symbols.Contains(ident))
|
||||
return true;
|
||||
curr = curr.outerScope;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Add(string ident)
|
||||
{
|
||||
symbols.Add(ident);
|
||||
}
|
||||
|
||||
public SymbolTable OuterScope { get { return outerScope; } }
|
||||
}
|
||||
public class SPythonParserTools : BaseParserTools
|
||||
{
|
||||
public bool build_tree_for_formatter = false;
|
||||
public bool build_tree_for_format_strings = false;
|
||||
|
||||
public override Dictionary<string, string> TokenNum { get; protected set; }
|
||||
|
||||
private void InitializeTokenNum()
|
||||
{
|
||||
TokenNum = new Dictionary<string, string>();
|
||||
TokenNum["STATEMENT"] = StringResources.Get("STMT");
|
||||
TokenNum["EXPRESSION"] = StringResources.Get("EXPR");
|
||||
TokenNum["EOF"] = StringResources.Get("EOF1");
|
||||
TokenNum["ID"] = StringResources.Get("IDENTIFIER");
|
||||
TokenNum["INTNUM"] = StringResources.Get("INTNUM");
|
||||
TokenNum["REALNUM"] = StringResources.Get("REALNUM");
|
||||
TokenNum["STRINGNUM"] = StringResources.Get("STRINGNUM");
|
||||
TokenNum["END_OF_FILE"] = StringResources.Get("#$");
|
||||
TokenNum["#$"] = StringResources.Get("#$");
|
||||
TokenNum["INDENT"] = StringResources.Get("#{");
|
||||
TokenNum["#{"] = StringResources.Get("#{");
|
||||
TokenNum["UNINDENT"] = StringResources.Get("#}");
|
||||
TokenNum["#}"] = StringResources.Get("#}");
|
||||
TokenNum["END_OF_LINE"] = StringResources.Get("#;");
|
||||
TokenNum["#;"] = StringResources.Get("#;");
|
||||
//TokenNum["tkStringLiteral"] = StringResources.Get("TKSTRINGLITERAL");
|
||||
TokenNum["IN"] = "'in'";
|
||||
TokenNum["IMPORT"] = "'import'";
|
||||
TokenNum["SEMICOLON"] = "';'";
|
||||
TokenNum["ASSIGN"] = "'='";
|
||||
TokenNum["COLON"] = "':'";
|
||||
TokenNum["DOT"] = "'.'";
|
||||
TokenNum["LPAR"] = "'('";
|
||||
TokenNum["RPAR"] = "')'";
|
||||
TokenNum["LBRACKET"] = "'['";
|
||||
TokenNum["RBRACKET"] = "']'";
|
||||
TokenNum["tkQuestion"] = "'?'";
|
||||
TokenNum["COMMA"] = "','";
|
||||
TokenNum["PERCENTAGE"] = "'%'";
|
||||
TokenNum["DIVIDE"] = "'/'";
|
||||
TokenNum["MINUS"] = "'-'";
|
||||
TokenNum["PLUS"] = "'+'";
|
||||
TokenNum["SLASHSLASH"] = "'//'";
|
||||
TokenNum["STAR"] = "'*'";
|
||||
TokenNum["EQUAL"] = "'=='";
|
||||
TokenNum["NOTEQUAL"] = "'!='";
|
||||
TokenNum["GREATER"] = "'>'";
|
||||
TokenNum["GREATEREQUAL"] = "'>='";
|
||||
TokenNum["LESS"] = "'<'";
|
||||
TokenNum["LESSEQUAL"] = "'<='";
|
||||
TokenNum["ARROW"] = "'->'";
|
||||
}
|
||||
|
||||
public SPythonParserTools(List<Error> errors, List<CompilerWarning> warnings,
|
||||
Dictionary<string, DirectiveInfo> validDirectives, bool buildTreeForFormatter = false, bool buildTreeForFormatterStrings = false,
|
||||
string currentFileName = null, List<compiler_directive> compilerDirectives = null)
|
||||
: base(errors, warnings, validDirectives, buildTreeForFormatter, buildTreeForFormatterStrings, currentFileName, compilerDirectives)
|
||||
{
|
||||
|
||||
InitializeTokenNum();
|
||||
}
|
||||
|
||||
public int TokenPriority(string tok)
|
||||
{
|
||||
switch (tok)
|
||||
{
|
||||
case "END_OF_LINE":
|
||||
return 300;
|
||||
case "STATEMENT":
|
||||
return 100;
|
||||
case "EXPRESSION":
|
||||
return 100;
|
||||
case "EQUAL":
|
||||
return 90;
|
||||
case "COLON":
|
||||
return 200;
|
||||
case "ASSIGN":
|
||||
return 70;
|
||||
case "ID":
|
||||
return 60;
|
||||
case "LPAR":
|
||||
return 100;
|
||||
case "RPAR":
|
||||
return 130;
|
||||
case "DOT":
|
||||
return 20;
|
||||
case "RBRACKET":
|
||||
return 10;
|
||||
case "GREATER":
|
||||
return 5;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected override string ReplaceSpecialSymbols(string text)
|
||||
{
|
||||
StringBuilder new_text = new StringBuilder(text);
|
||||
int curr = 0;
|
||||
for (int i = 0; i < text.Length; ++i)
|
||||
{
|
||||
if (text[i] != '\\') new_text[curr++] = text[i];
|
||||
else switch (text[i + 1])
|
||||
{
|
||||
case 'a': new_text[curr++] = '\a'; ++i; break;
|
||||
case '0': new_text[curr++] = '\0'; ++i; break;
|
||||
case 'b': new_text[curr++] = '\b'; ++i; break;
|
||||
case 't': new_text[curr++] = '\t'; ++i; break;
|
||||
case 'n': new_text[curr++] = '\n'; ++i; break;
|
||||
case 'v': new_text[curr++] = '\v'; ++i; break;
|
||||
case 'f': new_text[curr++] = '\f'; ++i; break;
|
||||
case 'r': new_text[curr++] = '\r'; ++i; break;
|
||||
|
||||
case '\'': new_text[curr++] = '\''; ++i; break;
|
||||
case '"': new_text[curr++] = '"'; ++i; break;
|
||||
case '\\': new_text[curr++] = '\\'; ++i; break;
|
||||
|
||||
default: new_text[curr++] = '\\'; break;
|
||||
}
|
||||
}
|
||||
return new_text.ToString().Substring(0, curr);
|
||||
}
|
||||
|
||||
public override literal create_string_const(string text, SourceContext sc)
|
||||
{
|
||||
literal lt;
|
||||
text = ReplaceSpecialSymbols(text.Substring(1, text.Length - 2));
|
||||
lt = new string_const(text);
|
||||
lt.source_context = sc;
|
||||
return lt;
|
||||
}
|
||||
|
||||
private int num1 = 0;
|
||||
|
||||
public ident NewId(string prefix, SourceContext sc = null)
|
||||
{
|
||||
num1++;
|
||||
return new ident(prefix + num1.ToString(),sc);
|
||||
}
|
||||
|
||||
private expression RemoveBracesAndContent(string input, SourceContext sc)
|
||||
{
|
||||
var regex = new Regex(@"\{([^}]+)\}");
|
||||
var parts = new List<expression>();
|
||||
|
||||
int lastIndex = 0;
|
||||
foreach (Match m in regex.Matches(input))
|
||||
{
|
||||
var innerRegex = new Regex(@"^([^:]*)(?::(.*))?$");
|
||||
|
||||
SourceContext expr_sc = new SourceContext(sc.LeftSourceContext, sc.RightSourceContext);
|
||||
expr_sc.begin_position.column_num += m.Index + 3;
|
||||
|
||||
var raw = m.Groups[1].Value;
|
||||
var innerMatch = innerRegex.Match(raw);
|
||||
|
||||
if (!innerMatch.Success)
|
||||
{
|
||||
AddErrorFromResource("ILL_FORMED_FSTRING_{0}", expr_sc, raw);
|
||||
return null;
|
||||
}
|
||||
|
||||
string expr_text = innerMatch.Groups[1].Value;
|
||||
string format = innerMatch.Groups[2].Success ? innerMatch.Groups[2].Value : null;
|
||||
|
||||
SourceContext format_sc = new SourceContext(sc.LeftSourceContext, sc.RightSourceContext);
|
||||
format_sc.begin_position.column_num += m.Index + 4 + expr_text.Length;
|
||||
|
||||
if (format != null)
|
||||
{
|
||||
var formatRegex = new Regex(@"^(x|X|d|b|\.(0|([1-9][0-9]*))f)$");
|
||||
var formatMatch = formatRegex.Match(format);
|
||||
if (!formatMatch.Success)
|
||||
AddErrorFromResource("FSTRING_UNNKOWN_FORMAT_{0}", format_sc, format);
|
||||
format = formatMatch.Value;
|
||||
}
|
||||
|
||||
if (m.Index > lastIndex)
|
||||
{
|
||||
var text = input.Substring(lastIndex, m.Index - lastIndex);
|
||||
if (text != "")
|
||||
parts.Add(new string_const(text, sc));
|
||||
}
|
||||
|
||||
List<Error> errors = new List<Error>();
|
||||
expression expr =
|
||||
LanguageProvider.Instance.SelectLanguageByExtension(currentFileName).Parser
|
||||
.GetExpression(currentFileName, expr_text, errors, new List<CompilerWarning>());
|
||||
|
||||
if (expr == null)
|
||||
{
|
||||
AddErrorFromResource("FSTRING_NESTED_EXPRESSION_{0}_PARSING_FAILURE", expr_sc, expr_text);
|
||||
expr = new expression();
|
||||
}
|
||||
|
||||
expr.source_context = expr_sc;
|
||||
method_call mc;
|
||||
if (format == null)
|
||||
{
|
||||
mc = new method_call(new ident("str"), new expression_list(expr, sc), sc);
|
||||
}
|
||||
else
|
||||
{
|
||||
mc = new method_call(new ident("!format"),
|
||||
new expression_list(new List<expression> { expr, new string_const(format, sc) }, sc), sc);
|
||||
}
|
||||
parts.Add(mc);
|
||||
lastIndex = m.Index + m.Length;
|
||||
}
|
||||
|
||||
if (lastIndex < input.Length)
|
||||
{
|
||||
var text = input.Substring(lastIndex);
|
||||
if (text != "")
|
||||
parts.Add(new string_const(text, sc));
|
||||
}
|
||||
|
||||
expression result = parts[parts.Count - 1];
|
||||
for (int i = parts.Count - 2; i >= 0; i--)
|
||||
{
|
||||
result = new bin_expr(parts[i], result, Operators.Plus, sc);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public expression create_fstring(string text, SourceContext sc)
|
||||
{
|
||||
text = ReplaceSpecialSymbols(text.Substring(2, text.Length - 3));
|
||||
expression res = RemoveBracesAndContent(text, sc);
|
||||
res.source_context = sc;
|
||||
return res;
|
||||
}
|
||||
|
||||
public LexLocation GetLexLocation(string found, string expected, LexLocation prev_loc, LexLocation curr_loc)
|
||||
{
|
||||
// жертвы, чтобы достать имя файла
|
||||
SourceContext sc = curr_loc;
|
||||
if (found == "#{" && expected == "END_OF_LINE" ||
|
||||
found == "#;" && expected == "INDENT")
|
||||
return new LexLocation(curr_loc.StartLine + 1, 0, curr_loc.StartLine + 1, 0, sc.FileName);
|
||||
if (found == "#{" || found == "#;")
|
||||
return new LexLocation(prev_loc.EndLine, prev_loc.EndColumn, prev_loc.EndLine, prev_loc.EndColumn + 1, sc.FileName);
|
||||
return curr_loc;
|
||||
}
|
||||
|
||||
public string ExpectedToken(bool line_needs_colon, params object[] args) {
|
||||
string found = args[0].ToString();
|
||||
List<string> tokens = new List<string>(args.Skip(1).Cast<string>());
|
||||
|
||||
if (tokens.Count != 1) {
|
||||
tokens = tokens.Except((new string[] { found })).ToList();
|
||||
}
|
||||
|
||||
// Это - временное решение, пока эти слова относятся к идентификаторам (что неправильно)
|
||||
//if (tokens.Contains("ID"))
|
||||
// tokens = tokens.Except((new string[] { "tkAbstract", "tkOverload", "tkReintroduce", "tkOverride", "tkVirtual", "tkAt", "tkOn", "tkName", "tkForward", "tkRead", "tkWrite" })).ToList();
|
||||
|
||||
if (tokens.Contains("FOR") && tokens.Contains("IF") && tokens.Contains("WHILE") && tokens.Contains("DEF"))
|
||||
return "STATEMENT";
|
||||
|
||||
if (tokens.Contains("ID") && tokens.Contains("INTNUM") && tokens.Contains("REALNUM") && tokens.Contains("STRINGNUM"))
|
||||
return "EXPRESSION";
|
||||
|
||||
if (line_needs_colon && tokens.Contains("COLON"))
|
||||
return "COLON";
|
||||
|
||||
tokens = tokens.OrderByDescending(s => TokenPriority(s)).ToList();
|
||||
|
||||
return tokens.First();
|
||||
}
|
||||
|
||||
public const_node create_spy_int_const(string text, SourceContext sc) {
|
||||
|
||||
return create_int_const(text.Replace("_", ""), sc);
|
||||
}
|
||||
|
||||
public string CreateErrorString(string yytext, string exp_token)
|
||||
{
|
||||
if (yytext.Equals("#;") && exp_token.Equals("INDENT"))
|
||||
{
|
||||
return StringResources.Get("LINE_WITHOUT_INDENT");
|
||||
}
|
||||
|
||||
if (yytext.Equals("#{") && !exp_token.Equals("END_OF_LINE"))
|
||||
{
|
||||
yytext = "#;";
|
||||
}
|
||||
if (exp_token.Equals("INDENT"))
|
||||
{
|
||||
exp_token = "END_OF_LINE";
|
||||
}
|
||||
|
||||
string prefix = "";
|
||||
if (yytext != "")
|
||||
prefix = StringResources.Get("FOUND{0}");
|
||||
else
|
||||
prefix = StringResources.Get("FOUNDEOF");
|
||||
|
||||
var ExpectedString = StringResources.Get("EXPECTED{1}");
|
||||
|
||||
if (exp_token.Equals("STATEMENT") ||
|
||||
exp_token.Equals("ID") ||
|
||||
exp_token.Equals("INDENT") ||
|
||||
exp_token.Equals("UNINDENT") ||
|
||||
exp_token.Equals("UNINDENT") ||
|
||||
exp_token.Equals("END_OF_LINE") ||
|
||||
exp_token.Equals("END_OF_FILE"))
|
||||
ExpectedString = StringResources.Get("EXPECTEDR{1}");
|
||||
else if (exp_token.Equals("STRINGNUM"))
|
||||
ExpectedString = StringResources.Get("EXPECTEDF{1}");
|
||||
var MaxTokHuman = ConvertToHumanName(exp_token);
|
||||
|
||||
if (yytext == "#{" || yytext == "#}" || yytext == "#;" || yytext == "#$")
|
||||
{
|
||||
prefix = StringResources.Get("FOUNDM{0}");
|
||||
yytext = ConvertToHumanName(yytext);
|
||||
return string.Format(prefix + ExpectedString, yytext, MaxTokHuman);
|
||||
}
|
||||
|
||||
return string.Format(prefix + ExpectedString, "'" + yytext + "'", MaxTokHuman);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* public string CreateErrorString(string yytext, LexLocation yyloc, params object[] args)
|
||||
{
|
||||
string expected = String.Join(", ", args.Skip(1).Select(x => x.ToString()));
|
||||
string err = $"PARSER ERROR \"{yytext}\" AT LINE #{yyloc.StartLine}: EXPECTED {expected}, FOUND {args[0]}";
|
||||
return err;
|
||||
}*/
|
||||
|
||||
protected override string GetFromStringResources(string id)
|
||||
{
|
||||
return StringResources.Get(id);
|
||||
}
|
||||
|
||||
protected override string ExtractDirectiveTextWithoutSpecialSymbols(string directive)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public typecast_node NewAsIsExpr(syntax_tree_node term, op_typecast typecast_op, type_definition simple_or_template_type_reference, LexLocation loc)
|
||||
{
|
||||
var naie = new typecast_node((addressed_value)term, simple_or_template_type_reference, typecast_op, loc);
|
||||
|
||||
return naie;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,4 +0,0 @@
|
|||
call generateParser.bat
|
||||
dotnet build -c Release --no-incremental -v d SPythonParser.csproj
|
||||
|
||||
@IF %ERRORLEVEL% NEQ 0 PAUSE
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
cls
|
||||
..\..\..\Utils\GPLex_GPPG\Gplex.exe /unicode SPythonLexer.lex
|
||||
..\..\..\Utils\GPLex_GPPG\Gppg.exe /verbose /no-lines /gplex SPythonParser.y
|
||||
pause
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using PascalABCCompiler.Errors;
|
||||
using PascalABCCompiler.TreeConverter;
|
||||
using PascalABCCompiler.TreeRealization;
|
||||
|
||||
namespace SPythonSyntaxTreeVisitor
|
||||
{
|
||||
class SPythonSemanticError : SimpleSemanticError
|
||||
{
|
||||
public SPythonSemanticError(location loc, string ErrResourceString, params object[] values) : base(loc, ErrResourceString, values) { }
|
||||
public override string ToString()
|
||||
{
|
||||
string err_res = ErrorResourceString;
|
||||
if (!ErrorResourceString.StartsWith("SPYTHONSEMANTIC_"))
|
||||
{
|
||||
err_res = "SEMANTICERROR_" + ErrorResourceString;
|
||||
}
|
||||
if (values != null)
|
||||
return string.Format(PascalABCCompiler.StringResources.Get(err_res), values);
|
||||
else
|
||||
return string.Format(PascalABCCompiler.StringResources.Get(err_res), "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// Общие сведения об этой сборке предоставляются следующим набором
|
||||
// набора атрибутов. Измените значения этих атрибутов для изменения сведений,
|
||||
// связанные со сборкой.
|
||||
[assembly: AssemblyTitle("SPythonSyntaxTreeVisitor")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("SPythonSyntaxTreeVisitor")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2026")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми
|
||||
// для компонентов COM. Если необходимо обратиться к типу в этой сборке через
|
||||
// COM, задайте атрибуту ComVisible значение TRUE для этого типа.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM
|
||||
[assembly: Guid("d38a21e0-1d61-4905-82b3-1800e1991d57")]
|
||||
|
||||
// Сведения о версии сборки состоят из указанных ниже четырех значений:
|
||||
//
|
||||
// Основной номер версии
|
||||
// Дополнительный номер версии
|
||||
// Номер сборки
|
||||
// Редакция
|
||||
//
|
||||
// Можно задать все значения или принять номера сборки и редакции по умолчанию
|
||||
// используя "*", как показано ниже:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net40</TargetFramework>
|
||||
|
||||
<RootNamespace>Languages.SPython.Backend.Conversion</RootNamespace>
|
||||
|
||||
<OutputPath>..\..\..\..\bin\</OutputPath>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\CompilerTools\CompilerTools.csproj" />
|
||||
<ProjectReference Include="..\..\..\..\Errors\Errors.csproj" />
|
||||
<ProjectReference Include="..\..\..\..\Localization\Localization.csproj" />
|
||||
<ProjectReference Include="..\..\..\..\SemanticTree\SemanticTree.csproj" />
|
||||
<ProjectReference Include="..\..\..\..\SyntaxTree\SyntaxTree.csproj" />
|
||||
<ProjectReference Include="..\..\..\..\SyntaxVisitors\SyntaxVisitors.csproj" />
|
||||
<ProjectReference Include="..\..\..\..\TreeConverter\TreeConverter.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -1,330 +0,0 @@
|
|||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.Errors;
|
||||
using PascalABCCompiler.SemanticTree;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
using PascalABCCompiler.SystemLibrary;
|
||||
using PascalABCCompiler.TreeConverter;
|
||||
using PascalABCCompiler.TreeRealization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using static PascalABCCompiler.StringConstants;
|
||||
|
||||
namespace SPythonSyntaxTreeVisitor
|
||||
{
|
||||
// Возможно, стоит заменить на декоратор или стратегию вместо наследования EVA
|
||||
public class spython_syntax_tree_visitor : syntax_tree_visitor
|
||||
{
|
||||
syntax_tree_visitor mainVisitor;
|
||||
|
||||
public spython_syntax_tree_visitor(syntax_tree_visitor mainSyntaxTreeVisitor) : base(false)
|
||||
{
|
||||
|
||||
mainVisitor = mainSyntaxTreeVisitor;
|
||||
convertion_data_and_alghoritms = mainSyntaxTreeVisitor.convertion_data_and_alghoritms;
|
||||
ret = mainSyntaxTreeVisitor.ret;
|
||||
context = mainSyntaxTreeVisitor.context;
|
||||
contextChanger = mainSyntaxTreeVisitor.contextChanger;
|
||||
|
||||
OnLeave = RunAdditionalChecks;
|
||||
}
|
||||
|
||||
type_intersection_node boolToIntIntersectionPrev;
|
||||
|
||||
type_intersection_node intToBoolIntersectionPrev;
|
||||
|
||||
public override void BeforeCompilationActions()
|
||||
{
|
||||
base.BeforeCompilationActions();
|
||||
|
||||
UpdateStandardTypes();
|
||||
}
|
||||
|
||||
public override void PostCompilationActions()
|
||||
{
|
||||
base.PostCompilationActions();
|
||||
|
||||
RestoreStandardTypes();
|
||||
}
|
||||
|
||||
private void UpdateStandardTypes()
|
||||
{
|
||||
// Неявное преобразование из int в bool и из bool в int
|
||||
|
||||
boolToIntIntersectionPrev = SystemLibrary.bool_type.remove_intersection_node(SystemLibrary.integer_type);
|
||||
|
||||
intToBoolIntersectionPrev = SystemLibrary.integer_type.remove_intersection_node(SystemLibrary.bool_type);
|
||||
|
||||
var newIntersection = new type_intersection_node(type_compare.less_type);
|
||||
|
||||
newIntersection.this_to_another = new type_conversion(new basic_function_node(basic_function_type.booltoi, SystemLibrary.integer_type, false), false);
|
||||
|
||||
newIntersection.another_to_this = new type_conversion(new basic_function_node(basic_function_type.itobool, SystemLibrary.bool_type, false), false);
|
||||
|
||||
SystemLibrary.bool_type.add_intersection_node(SystemLibrary.integer_type, newIntersection, false);
|
||||
}
|
||||
|
||||
private void RestoreStandardTypes()
|
||||
{
|
||||
SystemLibrary.bool_type.remove_intersection_node(SystemLibrary.integer_type);
|
||||
|
||||
if (boolToIntIntersectionPrev != null)
|
||||
SystemLibrary.bool_type.add_intersection_node(SystemLibrary.integer_type, boolToIntIntersectionPrev, false);
|
||||
|
||||
if (intToBoolIntersectionPrev != null)
|
||||
SystemLibrary.integer_type.add_intersection_node(SystemLibrary.bool_type, intToBoolIntersectionPrev, false);
|
||||
}
|
||||
|
||||
private void RunAdditionalChecks(syntax_tree_node node)
|
||||
{
|
||||
switch (node)
|
||||
{
|
||||
case bin_expr _bin_expr:
|
||||
expression_node left = convert_strong(_bin_expr.left);
|
||||
expression_node right = convert_strong(_bin_expr.right);
|
||||
if (_bin_expr.operation_type == Operators.Plus)
|
||||
{
|
||||
if ((left.type.name == "string" && right.type.name == "integer") || (left.type.name == "integer" && right.type.name == "string"))
|
||||
{
|
||||
AddError(left.location, "SPYTHONSEMANTIC_NOT_ALLOWED_{0}_DIFF_TYPES_{1}_{2}", '+', left.type, right.type); ;
|
||||
//base.AddError(left.location, "SPYTHONSEMANTIC_NOT_ALLOWED_{0}_DIFF_TYPES_{1}_{2}", Operators.Plus, left.type, right.type); ;
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
protected override void get_system_module(common_unit_node psystem_unit)
|
||||
{
|
||||
init_system_module(psystem_unit);
|
||||
|
||||
//esli zapustili v otladke, to vosstanovim mnozhestvo i procedury sozdanija diapasonov, inache ne budet rabotat
|
||||
if (debugging)
|
||||
{
|
||||
List<SymbolInfo> si = SystemLibInitializer.CreateDiapason.SymbolInfo;
|
||||
si = SystemLibInitializer.CreateObjDiapason.SymbolInfo;
|
||||
si = SystemLibInitializer.TypedSetType.SymbolInfo;
|
||||
}
|
||||
|
||||
// SystemUnitAssigned = true; - убрали для SPython
|
||||
CreateSpecialFields(psystem_unit);
|
||||
}
|
||||
|
||||
// Инициализируем только переменные экземпляра, не влияем на глобальное состояние в отличие от визитора Паскаля EVA
|
||||
protected override void internal_reset()
|
||||
{
|
||||
_system_unit = mainVisitor._system_unit;
|
||||
SystemLibrary.system_unit = _system_unit;
|
||||
ResetSelfFields();
|
||||
}
|
||||
|
||||
public override void AddError(location loc, string ErrResourceString, params object[] values)
|
||||
{
|
||||
Error err = new SPythonSemanticError(loc, ErrResourceString, values);
|
||||
if (ErrResourceString == "FORWARD_DECLARATION_{0}_AS_BASE_TYPE")
|
||||
{
|
||||
throw err;
|
||||
}
|
||||
else
|
||||
{
|
||||
base.AddError(err);
|
||||
}
|
||||
}
|
||||
|
||||
private type_node ConvertTypeNameToSPythonTypeName(type_node tn)
|
||||
{
|
||||
string new_name = tn.PrintableName;
|
||||
new_name = new_name
|
||||
.Replace(",", ", ")
|
||||
.Replace("<", "[")
|
||||
.Replace(">", "]")
|
||||
.Replace("Tuple", "tuple")
|
||||
.Replace("List", "list")
|
||||
.Replace("NewSet", "set")
|
||||
.Replace("Dictionary", "dict")
|
||||
.Replace("empty_list", "list[anytype]")
|
||||
.Replace("empty_set", "set[anytype]")
|
||||
.Replace("empty_dict", "dict[anytype]")
|
||||
.Replace("integer", "int")
|
||||
.Replace("string", "str")
|
||||
.Replace("real", "float")
|
||||
.Replace("boolean", "bool")
|
||||
.Replace("System.Numerics.BigInteger", "bigint")
|
||||
;
|
||||
return new common_type_node(new_name, type_access_level.tal_public, null, null, tn.location);
|
||||
}
|
||||
|
||||
public override void AddError(Error err, bool shouldReturn = false)
|
||||
{
|
||||
// TODO : Add Error Rerouting according to SPython semantics
|
||||
switch (err)
|
||||
{
|
||||
case OperatorCanNotBeAppliedToThisTypes _op_err:
|
||||
if (_op_err.operator_name == "mod")
|
||||
base.AddError(new OperatorCanNotBeAppliedToThisTypes("%", _op_err.left, _op_err.right, _op_err.loc), shouldReturn);
|
||||
else if (_op_err.operator_name == "div")
|
||||
base.AddError(new OperatorCanNotBeAppliedToThisTypes("//", _op_err.left, _op_err.right, _op_err.loc), shouldReturn);
|
||||
else
|
||||
break;
|
||||
return;
|
||||
case FunctionExpectedProcedureMeet _proc_meet:
|
||||
base.AddError(new SPythonSemanticError(_proc_meet.loc, "SPYTHONSEMANTIC_FUNCTION_{0}_NO_RETURN", _proc_meet.function.name));
|
||||
return;
|
||||
case CanNotConvertTypes conv_err:
|
||||
base.AddError(new CanNotConvertTypes(conv_err.expression_node,
|
||||
ConvertTypeNameToSPythonTypeName(conv_err.from),
|
||||
ConvertTypeNameToSPythonTypeName(conv_err.to),
|
||||
conv_err.loc));
|
||||
return;
|
||||
}
|
||||
base.AddError(err, shouldReturn);
|
||||
|
||||
}
|
||||
|
||||
public override void visit(assign _assign)
|
||||
{
|
||||
|
||||
if (_assign.from is bin_expr be &&
|
||||
_assign.to is ident il &&
|
||||
be.left is ident ir &&
|
||||
il.name == ir.name)
|
||||
{
|
||||
expression_node to = convert_strong(_assign.to);
|
||||
SourceContext sc = _assign.source_context;
|
||||
|
||||
if (to.type.is_generic_type_instance && to.type.name.StartsWith("set"))
|
||||
{
|
||||
if (be.operation_type == Operators.LogicalAND)
|
||||
{
|
||||
var replace = new method_call(new dot_node(new semantic_addr_value(to, to.location), new ident("!andEqual")),
|
||||
new expression_list(be.right), sc);
|
||||
base.visit(replace);
|
||||
return;
|
||||
}
|
||||
if (be.operation_type == Operators.LogicalOR)
|
||||
{
|
||||
var replace = new method_call(new dot_node(new semantic_addr_value(to, to.location), new ident("!orEqual")),
|
||||
new expression_list(be.right), sc);
|
||||
base.visit(replace);
|
||||
return;
|
||||
}
|
||||
if (be.operation_type == Operators.BitwiseXOR)
|
||||
{
|
||||
var replace = new method_call(new dot_node(new semantic_addr_value(to, to.location), new ident("!xorEqual")),
|
||||
new expression_list(be.right), sc);
|
||||
base.visit(replace);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
base.visit(_assign);
|
||||
}
|
||||
|
||||
public override void visit(bin_expr _bin_expr)
|
||||
{
|
||||
expression_node left = convert_strong(_bin_expr.left);
|
||||
expression_node right = convert_strong(_bin_expr.right);
|
||||
|
||||
var new_bin_expr = new bin_expr(new semantic_addr_value(left), new semantic_addr_value(right), _bin_expr.operation_type, _bin_expr.source_context);
|
||||
|
||||
RunAdditionalChecks(new_bin_expr);
|
||||
|
||||
switch (_bin_expr.operation_type)
|
||||
{
|
||||
/*case Operators.Plus:
|
||||
if (left.type == right.type && left.type.name == "boolean")
|
||||
{
|
||||
var int_left = new method_call(new ident("int"), new expression_list(new semantic_addr_value(left, left.location)), left.location);
|
||||
var int_right = new method_call(new ident("int"), new expression_list(new semantic_addr_value(right, right.location)), right.location);
|
||||
var bti_bin_expr = new bin_expr(int_left, int_right, _bin_expr.operation_type, _bin_expr.source_context);
|
||||
visit(bti_bin_expr);
|
||||
return;
|
||||
}
|
||||
break;*/
|
||||
case Operators.Division:
|
||||
if (left.type == right.type && left.type.name == string_type_name)
|
||||
{
|
||||
var mcn = new method_call(new dot_node(new semantic_addr_value(left, left.location), new ident("IndexOf")),
|
||||
new expression_list(new semantic_addr_value(right, right.location)), _bin_expr.source_context);
|
||||
visit(mcn);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case Operators.IntegerDivision:
|
||||
|
||||
var possibleTypes = new string[] { integer_type_name, real_type_name, biginteger_type_name };
|
||||
|
||||
var possibleCombinations = possibleTypes.SelectMany(t => possibleTypes, (t1, t2) => Tuple.Create(t1, t2))
|
||||
.Where(tt => !tt.Equals(Tuple.Create(real_type_name, biginteger_type_name))
|
||||
&& !tt.Equals(Tuple.Create(biginteger_type_name, real_type_name)));
|
||||
|
||||
if (possibleCombinations.Contains(Tuple.Create(left.type.name, right.type.name)))
|
||||
{
|
||||
var exprlist = new expression_list(); exprlist.source_context = _bin_expr.source_context;
|
||||
exprlist.Add(new semantic_addr_value(left, left.location));
|
||||
exprlist.Add(new semantic_addr_value(right, right.location));
|
||||
var floornode = new method_call(new ident("!Div"), exprlist, _bin_expr.source_context);
|
||||
visit(floornode);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case Operators.ModulusRemainder:
|
||||
|
||||
possibleTypes = new string[] { integer_type_name, real_type_name, biginteger_type_name };
|
||||
|
||||
possibleCombinations = possibleTypes.SelectMany(t => possibleTypes, (t1, t2) => Tuple.Create(t1, t2))
|
||||
.Where(tt => !tt.Equals(Tuple.Create(real_type_name, biginteger_type_name))
|
||||
&& !tt.Equals(Tuple.Create(biginteger_type_name, real_type_name)));
|
||||
|
||||
if (possibleCombinations.Contains(Tuple.Create(left.type.name, right.type.name)))
|
||||
{
|
||||
var exprlist = new expression_list(); exprlist.source_context = _bin_expr.source_context;
|
||||
exprlist.Add(new semantic_addr_value(left, left.location));
|
||||
exprlist.Add(new semantic_addr_value(right, right.location));
|
||||
var modnode = new method_call(new ident("!Mod"), exprlist, _bin_expr.source_context);
|
||||
visit(modnode);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
base.visit(new_bin_expr);
|
||||
}
|
||||
|
||||
// Реализация глобальных переменных для семантики. Возможно, пригодится позже EVA
|
||||
/*public override void visit(var_def_statement _var_def_statement)
|
||||
{
|
||||
if (_var_def_statement.vars_type != null)
|
||||
{
|
||||
var loc = get_location(_var_def_statement.vars_type);
|
||||
type_node tn = find_type(_var_def_statement.vars_type as named_type_reference, loc);
|
||||
_var_def_statement.vars_type = new semantic_type_node(tn);
|
||||
}
|
||||
base.visit(_var_def_statement);
|
||||
}
|
||||
|
||||
public override void visit(ident _ident)
|
||||
{
|
||||
var si = context.find_first(_ident.name)?.sym_info as var_definition_node;
|
||||
if (si != null && si.type.name == "@UnknownType")
|
||||
{
|
||||
var loc = get_location(_ident);
|
||||
AddError(loc, "SPYTHONSEMANTIC_USING_VARIABLE_BEFORE_ASSIGNMENT");
|
||||
}
|
||||
base.visit(_ident);
|
||||
}*/
|
||||
|
||||
/*public override void visit(named_type_reference _named_type_reference)
|
||||
{
|
||||
var loc = get_location(_named_type_reference);
|
||||
type_node tn = find_type(_named_type_reference, loc);
|
||||
if (tn.name == "UnknownType")
|
||||
{
|
||||
base.AddError(loc, "USING_VARIABLE_BEFORE_ASSIGNMENT");
|
||||
}
|
||||
var _new_ntr = new semantic_addr_value(tn);
|
||||
base.visit(_named_type_reference);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace Languages.SPython.Frontend.Converters
|
||||
{
|
||||
internal class AddForwardDeclarationsVisitor : BaseChangeVisitor
|
||||
{
|
||||
private declarations decls;
|
||||
|
||||
public override void Enter(syntax_tree_node stn)
|
||||
{
|
||||
if (stn is program_module pm)
|
||||
{
|
||||
decls = pm.program_block.defs;
|
||||
}
|
||||
if (stn is interface_node intn)
|
||||
{
|
||||
decls = intn.interface_definitions;
|
||||
}
|
||||
|
||||
base.Enter(stn);
|
||||
}
|
||||
|
||||
public override void visit(procedure_header _procedure_header)
|
||||
{
|
||||
SourceContext context = _procedure_header.source_context;
|
||||
var pd = new procedure_definition(_procedure_header.TypedClone(), null, context);
|
||||
pd.proc_header.proc_attributes.Add(new procedure_attribute(proc_attribute.attr_forward, context));
|
||||
decls.Add(pd, context);
|
||||
}
|
||||
|
||||
public override void visit(function_header _function_header)
|
||||
{
|
||||
visit(_function_header as procedure_header);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
using PascalABCCompiler.SyntaxTree;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Languages.SPython.Frontend.Converters
|
||||
{
|
||||
internal class AssignmentCharAsStringVisitor : BaseChangeVisitor
|
||||
{
|
||||
public AssignmentCharAsStringVisitor() { }
|
||||
|
||||
public override void visit(assign _assign)
|
||||
{
|
||||
if (_assign.from is string_const sc
|
||||
&& sc.Value.Length == 1)
|
||||
{
|
||||
_assign.from = new method_call(new ident("str"), new expression_list(sc, sc.source_context), sc.source_context);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
using PascalABCCompiler.SyntaxTree;
|
||||
using PascalABCCompiler.SyntaxTreeConverters;
|
||||
using System;
|
||||
|
||||
namespace Languages.SPython.Frontend.Converters
|
||||
{
|
||||
internal class BitwiseAssignmentDesugarVisitor : BaseChangeVisitor
|
||||
{
|
||||
public BitwiseAssignmentDesugarVisitor() { }
|
||||
|
||||
public override void visit(assign _assign)
|
||||
{
|
||||
Operators bin_op_type;
|
||||
|
||||
switch (_assign.operator_type)
|
||||
{
|
||||
case Operators.AssignmentBitwiseAND: {
|
||||
bin_op_type = Operators.LogicalAND;
|
||||
break; }
|
||||
case Operators.AssignmentBitwiseOR: {
|
||||
bin_op_type = Operators.LogicalOR;
|
||||
break; }
|
||||
case Operators.AssignmentBitwiseXOR: {
|
||||
bin_op_type = Operators.BitwiseXOR;
|
||||
break; }
|
||||
case Operators.AssignmentBitwiseLeftShift: {
|
||||
bin_op_type = Operators.BitwiseLeftShift;
|
||||
break; }
|
||||
case Operators.AssignmentBitwiseRightShift: {
|
||||
bin_op_type = Operators.BitwiseRightShift;
|
||||
break; }
|
||||
case Operators.AssignmentIntDivision: {
|
||||
bin_op_type = Operators.IntegerDivision;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
return; }
|
||||
}
|
||||
|
||||
SourceContext sc = _assign.source_context;
|
||||
bin_expr from = new bin_expr(_assign.to.TypedClone(), _assign.from, bin_op_type, sc);
|
||||
assign new_assign = new assign(_assign.to, from, sc);
|
||||
Replace(_assign, new_assign);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,104 +0,0 @@
|
|||
using PascalABCCompiler.SyntaxTree;
|
||||
using System.Collections.Generic;
|
||||
using PascalABCCompiler.CoreUtils;
|
||||
|
||||
namespace Languages.SPython.Frontend.Converters
|
||||
{
|
||||
internal class CompoundComparisonDesugarVisitor : BaseChangeVisitor
|
||||
{
|
||||
private int curr_sl_index;
|
||||
|
||||
private readonly GeneratedNamesManager generatedNamesManager;
|
||||
|
||||
public CompoundComparisonDesugarVisitor(GeneratedNamesManager generatedNamesManager)
|
||||
{
|
||||
this.generatedNamesManager = generatedNamesManager;
|
||||
}
|
||||
|
||||
public override void visit(statement_list sl)
|
||||
{
|
||||
if (sl == null) return;
|
||||
for (var i = sl.subnodes_count - 1; i >= 0; i--)
|
||||
{
|
||||
curr_sl_index = i;
|
||||
ProcessNode(sl[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private static statement_list GetCurrentStatementList(syntax_tree_node curr)
|
||||
{
|
||||
while (!(curr is statement_list)) curr = curr.Parent;
|
||||
return curr as statement_list;
|
||||
}
|
||||
|
||||
private static bool IsComparison(bin_expr _bin_expr)
|
||||
{
|
||||
Operators Operator = _bin_expr.operation_type;
|
||||
switch (Operator)
|
||||
{
|
||||
case Operators.Less:
|
||||
case Operators.Greater:
|
||||
case Operators.LessEqual:
|
||||
case Operators.GreaterEqual:
|
||||
case Operators.Equal:
|
||||
case Operators.NotEqual:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool IsCompoundComparison(bin_expr _bin_expr)
|
||||
{
|
||||
return (_bin_expr.left is bin_expr left) && IsComparison(_bin_expr) && IsComparison(left);
|
||||
}
|
||||
|
||||
|
||||
private string NewIdentName()
|
||||
{
|
||||
return generatedNamesManager.GenerateName("%");
|
||||
}
|
||||
|
||||
public override void visit(bin_expr _bin_expr)
|
||||
{
|
||||
if (IsCompoundComparison(_bin_expr))
|
||||
{
|
||||
// transform
|
||||
//
|
||||
// ((left comp1 middle) comp2 right)
|
||||
//
|
||||
// to
|
||||
//
|
||||
// var id: typeof(middle);
|
||||
// ((left comp1 !assign(id, middle)) && (id comp2 right))
|
||||
//
|
||||
// then recursive call for left
|
||||
// P.S. !assign(a, b) assigns b to a and return a
|
||||
|
||||
bin_expr left_comp_middle = _bin_expr.left as bin_expr;
|
||||
expression left = left_comp_middle.left;
|
||||
Operators comp1 = left_comp_middle.operation_type;
|
||||
expression middle = left_comp_middle.right;
|
||||
Operators comp2 = _bin_expr.operation_type;
|
||||
expression right = _bin_expr.right;
|
||||
ident id = new ident(NewIdentName(), middle.source_context);
|
||||
type_definition td = new same_type_node(middle.TypedClone(), middle.source_context);
|
||||
var_def_statement vds = new var_def_statement(id, td, middle.source_context);
|
||||
statement_list curr_statement_list = GetCurrentStatementList(_bin_expr);
|
||||
int index = curr_sl_index - curr_statement_list.subnodes_without_list_elements_count;
|
||||
curr_statement_list.list.Insert(index, new var_statement(vds, middle.source_context));
|
||||
curr_sl_index++;
|
||||
|
||||
addressed_value method_name = new ident("!assign", middle.source_context);
|
||||
expression_list el = new expression_list(new List<expression> { id, middle }, middle.source_context);
|
||||
method_call method_call = new method_call(method_name, el, middle.source_context);
|
||||
bin_expr new_left = new bin_expr(left, method_call, comp1, new SourceContext(left.source_context, method_call.source_context));
|
||||
bin_expr new_right = new bin_expr(id, right, comp2, new SourceContext(id.source_context, right.source_context));
|
||||
bin_expr new_bin_expr = new bin_expr(new_left, new_right, Operators.LogicalAND, _bin_expr.source_context);
|
||||
_bin_expr.Parent.ReplaceDescendant(_bin_expr, new_bin_expr);
|
||||
new_bin_expr.left.visit(this);
|
||||
}
|
||||
else
|
||||
base.visit(_bin_expr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
using PascalABCCompiler.SyntaxTree;
|
||||
using System;
|
||||
|
||||
namespace Languages.SPython.Frontend.Converters
|
||||
{
|
||||
public class EraseSpythonOnlyNodesVisitor : BaseChangeVisitor
|
||||
{
|
||||
public EraseSpythonOnlyNodesVisitor() {}
|
||||
|
||||
public override void visit(global_statement _global_statement)
|
||||
{
|
||||
DeleteInStatementList(_global_statement);
|
||||
}
|
||||
|
||||
public override void visit(import_statement _import_statement)
|
||||
{
|
||||
var upper = UpperNode();
|
||||
if (upper is interface_node _interface_node)
|
||||
_interface_node.interface_definitions.ReplaceDescendant<syntax_tree_node, syntax_tree_node>(
|
||||
_import_statement, new empty_statement());
|
||||
else Replace(_import_statement, new empty_statement());
|
||||
}
|
||||
|
||||
public override void visit(from_import_statement _from_import_statement)
|
||||
{
|
||||
var upper = UpperNode();
|
||||
if (upper is interface_node _interface_node)
|
||||
_interface_node.interface_definitions.ReplaceDescendant<syntax_tree_node, syntax_tree_node>(
|
||||
_from_import_statement, new empty_statement());
|
||||
else Replace(_from_import_statement, new empty_statement());
|
||||
}
|
||||
|
||||
public override void visit(tuple_node tup)
|
||||
{
|
||||
var dn = new ident("!CreateTuple", tup.source_context);
|
||||
var mc = new method_call(dn, tup.el, tup.source_context);
|
||||
|
||||
//var sug = new sugared_expression(tup, mc, tup.source_context); - нет никакой семантической проверки - всё - на уровне синтаксиса!
|
||||
|
||||
//ReplaceUsingParent(tup, mc); - исправление #1199. Оказывается, ReplaceUsingParent и Replace не эквивалентны - у копии Parent на старого родителя
|
||||
Replace(tup, mc);
|
||||
visit(mc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
using PascalABCCompiler.SyntaxTree;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Languages.SPython.Frontend.Converters
|
||||
{
|
||||
internal class FindFunctionsNamesVisitor : BaseChangeVisitor
|
||||
{
|
||||
public HashSet<string> definedFunctionsNames = new HashSet<string>();
|
||||
|
||||
public override void visit(procedure_definition pd)
|
||||
{
|
||||
definedFunctionsNames.Add(pd.proc_header.name.meth_name.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
using PascalABCCompiler.SyntaxTree;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Languages.SPython.Frontend.Converters
|
||||
{
|
||||
internal class FunctionsWithNamedParametersDesugarVisitor : BaseChangeVisitor
|
||||
{
|
||||
public FunctionsWithNamedParametersDesugarVisitor() { }
|
||||
|
||||
public override void visit(method_call _method_call)
|
||||
{
|
||||
if (_method_call.parameters is expression_list exprl) {
|
||||
expression_list args = new expression_list();
|
||||
expression_list kwargs_names_array = new expression_list();
|
||||
expression_list kwargs = new expression_list();
|
||||
|
||||
foreach (var expr in exprl.expressions)
|
||||
{
|
||||
if (expr is name_assign_expr nae)
|
||||
{
|
||||
kwargs_names_array.Add(new string_const(nae.name.name));
|
||||
kwargs_names_array.source_context
|
||||
= new SourceContext(kwargs_names_array.source_context, expr.source_context);
|
||||
kwargs.Add(nae.expr);
|
||||
kwargs.source_context
|
||||
= new SourceContext(kwargs.source_context, expr.source_context);
|
||||
}
|
||||
else if (kwargs.expressions.Count() == 0)
|
||||
{
|
||||
args.Add(expr);
|
||||
args.source_context = new SourceContext(args.source_context, expr.source_context);
|
||||
}
|
||||
else throw new SPythonSyntaxVisitorError("ARG_AFTER_KWARGS", expr.source_context);
|
||||
}
|
||||
|
||||
if (kwargs.expressions.Count() != 0)
|
||||
{
|
||||
array_const_new acn = new array_const_new(kwargs_names_array, '|');
|
||||
kwargs.expressions.Insert(0, acn);
|
||||
|
||||
ident method_name = new ident();
|
||||
if (_method_call.dereferencing_value is ident id)
|
||||
{
|
||||
method_name = id;
|
||||
}
|
||||
else if (_method_call.dereferencing_value is dot_node dnn)
|
||||
{
|
||||
method_name = dnn.right as ident;
|
||||
}
|
||||
|
||||
ident class_name = new ident("!" + method_name);
|
||||
new_expr ne = new new_expr(new named_type_reference(class_name), kwargs, false, null);
|
||||
|
||||
dot_node dn = new dot_node(ne, new ident(method_name.name), _method_call.source_context);
|
||||
method_call new_method_call = new method_call(dn, args, _method_call.source_context);
|
||||
Replace(_method_call, new_method_call);
|
||||
return;
|
||||
}
|
||||
}
|
||||
base.visit(_method_call);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
using PascalABCCompiler.CoreUtils;
|
||||
|
||||
namespace Languages.SPython.Frontend.Converters
|
||||
{
|
||||
internal class GeneratorObjectDesugarVisitor : BaseChangeVisitor
|
||||
{
|
||||
private syntax_tree_node root;
|
||||
private bool replaceRoot = false;
|
||||
private syntax_tree_node lastDesugaredNode = null;
|
||||
private readonly GeneratedNamesManager generatedNamesManager;
|
||||
|
||||
public GeneratorObjectDesugarVisitor(syntax_tree_node root, GeneratedNamesManager generatedNamesManager)
|
||||
{
|
||||
this.root = root;
|
||||
this.generatedNamesManager = generatedNamesManager;
|
||||
}
|
||||
|
||||
public syntax_tree_node UpdatedRoot()
|
||||
{
|
||||
if (replaceRoot) return lastDesugaredNode;
|
||||
return root;
|
||||
}
|
||||
|
||||
public override void visit(generator_object _generator_object)
|
||||
{
|
||||
base.visit(_generator_object);
|
||||
|
||||
dot_node dn;
|
||||
ident_list idList;
|
||||
formal_parameters formalPars;
|
||||
statement_list sl;
|
||||
function_lambda_definition lambda;
|
||||
method_call mc;
|
||||
|
||||
// [ expr1 for ident in expr2 if expr3 ] -> expr2.Where(ident -> expr3).Select(ident -> expr1)
|
||||
if (_generator_object._condition != null)
|
||||
{
|
||||
string ident_name = _generator_object._ident.name;
|
||||
idList = new ident_list(new ident(ident_name), _generator_object._ident.source_context);
|
||||
formalPars = new formal_parameters(new typed_parameters(idList, new lambda_inferred_type(new lambda_any_type_node_syntax(), _generator_object._ident.source_context), parametr_kind.none, null, _generator_object._ident.source_context), _generator_object._ident.source_context);
|
||||
|
||||
dn = new dot_node(_generator_object._range as addressed_value, (new ident("Where")) as addressed_value, _generator_object.source_context);
|
||||
|
||||
sl = new statement_list(new assign(StringConstants.result_var_name, _generator_object._condition, _generator_object._condition.source_context), _generator_object._condition.source_context); //!
|
||||
sl.expr_lambda_body = true;
|
||||
lambda = new function_lambda_definition(
|
||||
CreateLambdaName(), formalPars,
|
||||
new lambda_inferred_type(new lambda_any_type_node_syntax(), _generator_object._ident.source_context), sl, _generator_object.source_context);
|
||||
|
||||
mc = new method_call(dn as addressed_value, new expression_list(lambda as expression), _generator_object.source_context);
|
||||
dn = new dot_node(mc as addressed_value, (new ident("Select")) as addressed_value, _generator_object.source_context);
|
||||
}
|
||||
// [ expr1 for ident in expr2 ] -> expr2.Select(ident -> expr1)
|
||||
else
|
||||
dn = new dot_node(_generator_object._range as addressed_value, (new ident("Select")) as addressed_value, _generator_object.source_context);
|
||||
|
||||
|
||||
idList = new ident_list(_generator_object._ident, _generator_object._ident.source_context);
|
||||
formalPars = new formal_parameters(new typed_parameters(idList, new lambda_inferred_type(new lambda_any_type_node_syntax(), _generator_object._ident.source_context), parametr_kind.none, null, _generator_object._ident.source_context), _generator_object._ident.source_context);
|
||||
|
||||
sl = new statement_list(new assign(StringConstants.result_var_name, _generator_object._expr, _generator_object._expr.source_context), _generator_object._expr.source_context);
|
||||
sl.expr_lambda_body = true;
|
||||
|
||||
lambda = new function_lambda_definition(
|
||||
CreateLambdaName(), formalPars,
|
||||
new lambda_inferred_type(new lambda_any_type_node_syntax(), _generator_object._ident.source_context), sl, _generator_object.source_context);
|
||||
|
||||
|
||||
method_call replaceTo = new method_call(dn as addressed_value, new expression_list(lambda as expression), _generator_object.source_context);
|
||||
|
||||
if (root != _generator_object)
|
||||
Replace(_generator_object, replaceTo);
|
||||
else
|
||||
{
|
||||
replaceRoot = true;
|
||||
lastDesugaredNode = replaceTo;
|
||||
}
|
||||
}
|
||||
|
||||
private string CreateLambdaName()
|
||||
{
|
||||
return generatedNamesManager.GenerateName(StringConstants.lambdaPrefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
using PascalABCCompiler.SyntaxTree;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Languages.SPython.Frontend.Converters
|
||||
{
|
||||
internal class ImportToUsesVisitor : BaseChangeVisitor
|
||||
{
|
||||
Dictionary<string, SourceContext> modulesNames = new Dictionary<string, SourceContext>();
|
||||
|
||||
public ImportToUsesVisitor() { }
|
||||
|
||||
private Dictionary<string, string> specialModulesAliases = Facade.LanguageProvider.Instance.SelectLanguageByName("SPython").LanguageInformation.SpecialModulesAliases;
|
||||
|
||||
private string GetNameToImport(string nameToImport)
|
||||
{
|
||||
if (!specialModulesAliases.ContainsKey(nameToImport))
|
||||
return nameToImport;
|
||||
else
|
||||
return specialModulesAliases[nameToImport];
|
||||
}
|
||||
|
||||
private void AddName(ident id)
|
||||
{
|
||||
string nameToImport = GetNameToImport(id.name);
|
||||
if (!modulesNames.ContainsKey(nameToImport))
|
||||
modulesNames.Add(nameToImport, id.source_context);
|
||||
}
|
||||
|
||||
public override void visit(import_statement _import_statement)
|
||||
{
|
||||
foreach (as_statement as_Statement in _import_statement.modules_names.as_statements)
|
||||
AddName(as_Statement.real_name);
|
||||
}
|
||||
|
||||
public override void visit(from_import_statement _from_import_statement)
|
||||
{
|
||||
AddName(_from_import_statement.module_name);
|
||||
}
|
||||
|
||||
public void AddUsesToUsesList(uses_list _uses_list)
|
||||
{
|
||||
foreach (string module_name in modulesNames.Keys)
|
||||
{
|
||||
SourceContext sc = modulesNames[module_name];
|
||||
uses_list us = new uses_list(new unit_or_namespace(module_name, sc), sc);
|
||||
us[0].source_context = sc;
|
||||
_uses_list.AddUsesList(us, sc);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Exit(syntax_tree_node stn)
|
||||
{
|
||||
if (stn is program_module pm)
|
||||
{
|
||||
AddUsesToUsesList(pm.used_units);
|
||||
}
|
||||
if (stn is unit_module um)
|
||||
{
|
||||
AddUsesToUsesList(um.interface_part.uses_modules);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,205 +0,0 @@
|
|||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Languages.SPython.Frontend.Converters
|
||||
{
|
||||
internal class KwargsFunctionDesugarVisitor: BaseChangeVisitor
|
||||
{
|
||||
public KwargsFunctionDesugarVisitor() { }
|
||||
|
||||
private declarations decls;
|
||||
private declarations current_decls;
|
||||
|
||||
public override void Enter(syntax_tree_node stn)
|
||||
{
|
||||
if (stn is program_module pm)
|
||||
{
|
||||
decls = pm.program_block.defs;
|
||||
}
|
||||
if (stn is interface_node intn)
|
||||
{
|
||||
decls = intn.interface_definitions;
|
||||
}
|
||||
if (stn is declarations_as_statement das)
|
||||
{
|
||||
current_decls = das.defs;
|
||||
}
|
||||
|
||||
base.Enter(stn);
|
||||
}
|
||||
|
||||
private typed_parameters LastParameter(procedure_definition pd)
|
||||
{
|
||||
return pd.proc_header.parameters.Last();
|
||||
}
|
||||
|
||||
private bool HasParameters(procedure_definition pd)
|
||||
{
|
||||
return pd.proc_header.parameters != null;
|
||||
}
|
||||
|
||||
private bool IsKwargsParameter(typed_parameters tp)
|
||||
{
|
||||
return tp.param_kind == parametr_kind.kwargs_parameter;
|
||||
}
|
||||
|
||||
private bool HasKwargsParameter(procedure_definition pd)
|
||||
{
|
||||
if (!HasParameters(pd))
|
||||
return false;
|
||||
|
||||
foreach (typed_parameters param in pd.proc_header.parameters.params_list)
|
||||
{
|
||||
if (IsKwargsParameter(param))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
string renameFrom = "";
|
||||
|
||||
private void RenameKwargParametor(procedure_definition pd)
|
||||
{
|
||||
renameFrom = LastParameter(pd).idents.idents[0].name;
|
||||
var body = pd.proc_body;
|
||||
base.visit(pd);
|
||||
renameFrom = "";
|
||||
}
|
||||
|
||||
public override void visit(ident id)
|
||||
{
|
||||
// сомнительно, лучше сделать другим визитором
|
||||
if (renameFrom != "" && id.name == renameFrom)
|
||||
{
|
||||
id.name = "!kwargs";
|
||||
}
|
||||
}
|
||||
|
||||
private void AddNoKwargsVersion(procedure_definition pd)
|
||||
{
|
||||
procedure_definition noKwargsVersion = pd.TypedClone();
|
||||
typed_parameters kwargs_parameter = LastParameter(noKwargsVersion);
|
||||
noKwargsVersion.proc_header.parameters.Remove(kwargs_parameter);
|
||||
ident name = noKwargsVersion.proc_header.name.meth_name;
|
||||
ident class_name = "!" + name;
|
||||
|
||||
if (IsForwardDeclaration(noKwargsVersion.proc_header))
|
||||
{
|
||||
decls.Add(noKwargsVersion);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<typed_parameters> tp_list = noKwargsVersion.proc_header.parameters.params_list;
|
||||
expression_list args = new expression_list();
|
||||
foreach (typed_parameters tp in tp_list)
|
||||
{
|
||||
foreach (ident id in tp.idents.list)
|
||||
{
|
||||
args.Add(id);
|
||||
}
|
||||
}
|
||||
|
||||
new_expr ne = new new_expr(new named_type_reference(class_name), null, false, null);
|
||||
|
||||
dot_node dn = new dot_node(ne, new ident(name.name));
|
||||
method_call method_call = new method_call(dn, args);
|
||||
|
||||
statement stmt;
|
||||
|
||||
if (pd.proc_header is function_header)
|
||||
{
|
||||
stmt = new assign(new ident(StringConstants.result_var_name), method_call, Operators.Assignment);
|
||||
}
|
||||
else
|
||||
{
|
||||
stmt = new procedure_call(method_call, false);
|
||||
}
|
||||
|
||||
statement_list stmtlist = new statement_list(stmt);
|
||||
|
||||
declarations empty_declarations = new declarations();
|
||||
block block = new block(empty_declarations, stmtlist);
|
||||
noKwargsVersion.proc_body = block;
|
||||
current_decls.Add(noKwargsVersion);
|
||||
}
|
||||
}
|
||||
|
||||
void CheckIfKwargParametorIsUsedCorrectly(procedure_definition pd)
|
||||
{
|
||||
var params_list = pd.proc_header.parameters.params_list;
|
||||
for (int i = 0; i < params_list.Count() - 1; ++i)
|
||||
{
|
||||
if (IsKwargsParameter(params_list[i]))
|
||||
{
|
||||
throw new SPythonSyntaxVisitorError("KWARG_PARAMETOR_NOT_LAST",
|
||||
params_list[i].source_context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void visit(procedure_definition pd)
|
||||
{
|
||||
if (!HasKwargsParameter(pd))
|
||||
return;
|
||||
|
||||
// Проверяем что kwarg-параметр только последний
|
||||
CheckIfKwargParametorIsUsedCorrectly(pd);
|
||||
|
||||
RenameKwargParametor(pd);
|
||||
|
||||
declaration d = CreateTypeDefinitionForKwargsFunction(pd);
|
||||
AddNoKwargsVersion(pd);
|
||||
Replace(pd, d);
|
||||
}
|
||||
|
||||
private bool IsForwardDeclaration(procedure_header _procedure_header)
|
||||
{
|
||||
foreach (procedure_attribute attr in _procedure_header.proc_attributes.proc_attributes)
|
||||
if (attr.attribute_type is proc_attribute.attr_forward)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private declaration CreateTypeDefinitionForKwargsFunction(procedure_definition pd)
|
||||
{
|
||||
procedure_definition new_pd = pd.TypedClone();
|
||||
typed_parameters kwargs_parameter = LastParameter(new_pd);
|
||||
new_pd.proc_header.parameters.Remove(kwargs_parameter);
|
||||
ident name = new_pd.proc_header.name.meth_name;
|
||||
ident class_name = "!" + name;
|
||||
|
||||
if (IsForwardDeclaration(new_pd.proc_header))
|
||||
{
|
||||
// base class type
|
||||
template_param_list tpl = new template_param_list(kwargs_parameter.vars_type, kwargs_parameter.source_context);
|
||||
ident base_class_name = new ident("kwargs_gen`1");
|
||||
named_type_reference ntr = new named_type_reference(base_class_name);
|
||||
template_type_reference ttr = new template_type_reference(ntr, tpl);
|
||||
named_type_reference_list ntrl = new named_type_reference_list(ttr);
|
||||
|
||||
// class body
|
||||
access_modifer_node amn = new access_modifer_node(access_modifer.public_modifer);
|
||||
new_pd.proc_header.name.meth_name = new_pd.proc_header.name.meth_name;
|
||||
class_members cm = new class_members(new_pd.proc_header);
|
||||
class_body_list cbl = new class_body_list(cm);
|
||||
|
||||
// type class declaration
|
||||
class_definition cd = new class_definition(ntrl, cbl);
|
||||
type_declaration td = new type_declaration(class_name, cd);
|
||||
type_declarations result = new type_declarations(td);
|
||||
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_pd.proc_header.name = new method_name(null, class_name, name, null);
|
||||
return new_pd;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace Languages.SPython.Frontend.Converters
|
||||
{
|
||||
internal class MapDesugarVisitor : BaseChangeVisitor
|
||||
{
|
||||
public MapDesugarVisitor() { }
|
||||
|
||||
public override void visit(method_call mc)
|
||||
{
|
||||
base.visit(mc);
|
||||
|
||||
if (mc.dereferencing_value is ident map && map.name == "map" &&
|
||||
mc.parameters.Count == 2 && mc.parameters[0] is addressed_value av &&
|
||||
mc.parameters[1] is expression range)
|
||||
{
|
||||
ident ident = new ident("!map_iterable_element", mc.source_context);
|
||||
expression expr = new method_call(av, new expression_list(ident), mc.source_context);
|
||||
|
||||
generator_object go = new generator_object(expr, ident, range, null, mc.source_context);
|
||||
|
||||
Replace(mc, go);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,266 +0,0 @@
|
|||
using PascalABCCompiler.SyntaxTree;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Languages.SPython.Frontend.Converters
|
||||
{
|
||||
internal class NameCorrectVisitor : SymbolTableFillingVisitor
|
||||
{
|
||||
public HashSet<string> variablesUsedAsGlobal = new HashSet<string>();
|
||||
|
||||
private readonly bool forIntellisense;
|
||||
|
||||
public NameCorrectVisitor(string unitName, bool forIntellisense, Dictionary<string, Dictionary<string, bool>> namesFromUsedUnits, HashSet<string> definedFunctionsNames) : base(unitName, forIntellisense, namesFromUsedUnits)
|
||||
{
|
||||
this.forIntellisense = forIntellisense;
|
||||
foreach (string definedFunctionName in definedFunctionsNames)
|
||||
{
|
||||
symbolTable.Add(definedFunctionName, NameKind.ForwardDeclaredFunction);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Enter(syntax_tree_node stn)
|
||||
{
|
||||
if (stn is ident && stn.Parent is dot_node dn && dn.right == stn)
|
||||
{
|
||||
visitNode = false;
|
||||
}
|
||||
|
||||
base.Enter(stn);
|
||||
}
|
||||
|
||||
public override void visit(var_statement _var_statement)
|
||||
{
|
||||
if (symbolTable.IsOutermostScope())
|
||||
{
|
||||
// не работает для нескольких переменных (var a1, a2, ...: type;)
|
||||
ident id = _var_statement.var_def.vars.idents[0];
|
||||
symbolTable.Add(id.name, NameKind.GlobalVariable);
|
||||
ProcessNode(_var_statement.var_def);
|
||||
}
|
||||
else base.visit(_var_statement);
|
||||
}
|
||||
|
||||
public override void visit(name_assign_expr _name_assign_expr)
|
||||
{
|
||||
ProcessNode(_name_assign_expr[1]);
|
||||
}
|
||||
|
||||
public override void visit(unit_or_namespace _unit_or_namespace)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void visit(unit_name _unit_name)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void visit(global_statement _global_statement)
|
||||
{
|
||||
if (!forIntellisense)
|
||||
{
|
||||
foreach (ident _ident in _global_statement.idents.idents)
|
||||
{
|
||||
NameKind nameType = symbolTable[_ident.name];
|
||||
switch (nameType)
|
||||
{
|
||||
case NameKind.GlobalVariable:
|
||||
case NameKind.ImportedVariableAlias:
|
||||
case NameKind.ImportedNotVariableAlias:
|
||||
break;
|
||||
case NameKind.Unknown:
|
||||
throw new SPythonSyntaxVisitorError("UNKNOWN_NAME_{0}",
|
||||
_ident.source_context, _ident.name);
|
||||
default:
|
||||
throw new SPythonSyntaxVisitorError("SCOPE_CONTAINS_NAME_{0}",
|
||||
_ident.source_context, _ident.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
base.visit(_global_statement);
|
||||
}
|
||||
|
||||
public override void visit(named_type_reference _named_type_reference)
|
||||
{
|
||||
if (forIntellisense)
|
||||
return;
|
||||
|
||||
ident id = _named_type_reference.names[0];
|
||||
string name = id.name;
|
||||
|
||||
if (name == "int" || name == "str" || name == "bool" || name == "float")
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NameKind nameKind = symbolTable[name];
|
||||
switch (nameKind)
|
||||
{
|
||||
case NameKind.ModuleAlias:
|
||||
id.name = symbolTable.AliasToRealName(id.name);
|
||||
break;
|
||||
|
||||
case NameKind.ImportedVariableAlias:
|
||||
case NameKind.ImportedNotVariableAlias:
|
||||
_named_type_reference.names.Insert(0, new ident(symbolTable.AliasToModuleName(id.name), id.source_context));
|
||||
_named_type_reference.names[1].name = symbolTable.AliasToRealName(_named_type_reference.names[1].name);
|
||||
break;
|
||||
|
||||
case NameKind.Unknown:
|
||||
throw new SPythonSyntaxVisitorError("UNKNOWN_NAME_{0}",
|
||||
id.source_context, id.name);
|
||||
}
|
||||
}
|
||||
|
||||
// функция нужна для классов list, dict и set из-за наличия одноименных функций в другом модуле
|
||||
public override void visit(template_type_reference _template_type_reference)
|
||||
{
|
||||
if (forIntellisense)
|
||||
return;
|
||||
|
||||
named_type_reference _named_type_reference = _template_type_reference.name;
|
||||
string name = _named_type_reference.names[0].name + '`';
|
||||
|
||||
NameKind nameKind = symbolTable[name];
|
||||
|
||||
// синонимы типов без '`'
|
||||
if (nameKind == NameKind.Unknown)
|
||||
{
|
||||
name = name.TrimEnd('`');
|
||||
nameKind = symbolTable[name];
|
||||
}
|
||||
|
||||
switch (nameKind)
|
||||
{
|
||||
case NameKind.ModuleAlias:
|
||||
_named_type_reference.names[0].name = symbolTable.AliasToRealName(name);
|
||||
break;
|
||||
|
||||
case NameKind.ImportedVariableAlias:
|
||||
case NameKind.ImportedNotVariableAlias:
|
||||
_named_type_reference.names.Insert(0, new ident(symbolTable.AliasToModuleName(name), _named_type_reference.names[0].source_context));
|
||||
_named_type_reference.names[1].name = symbolTable.AliasToRealName(name);
|
||||
break;
|
||||
|
||||
case NameKind.Unknown:
|
||||
throw new SPythonSyntaxVisitorError("UNKNOWN_NAME_{0}",
|
||||
_named_type_reference.names[0].source_context, name);
|
||||
}
|
||||
}
|
||||
|
||||
public override void visit(ident _ident)
|
||||
{
|
||||
SourceContext sc = _ident.source_context;
|
||||
NameKind nameKind = symbolTable[_ident.name];
|
||||
switch (nameKind)
|
||||
{
|
||||
case NameKind.ModuleAlias:
|
||||
if (forIntellisense)
|
||||
break;
|
||||
|
||||
_ident.name = symbolTable.AliasToRealName(_ident.name);
|
||||
break;
|
||||
|
||||
case NameKind.ImportedVariableAlias:
|
||||
case NameKind.ImportedNotVariableAlias:
|
||||
if (forIntellisense)
|
||||
break;
|
||||
|
||||
Replace(_ident, new dot_node(new ident(symbolTable.AliasToModuleName(_ident.name), sc)
|
||||
, new ident(symbolTable.AliasToRealName(_ident.name), sc), sc));
|
||||
break;
|
||||
|
||||
case NameKind.GlobalVariable:
|
||||
if (symbolTable.IsInFunctionBody &&
|
||||
!variablesUsedAsGlobal.Contains(_ident.name))
|
||||
variablesUsedAsGlobal.Add(_ident.name);
|
||||
break;
|
||||
|
||||
case NameKind.ForwardDeclaredFunction:
|
||||
if (forIntellisense)
|
||||
break;
|
||||
|
||||
if (!symbolTable.IsInFunctionBody)
|
||||
throw new SPythonSyntaxVisitorError("FUNCTION_{0}_USED_BEFORE_DECLARATION",
|
||||
sc, _ident.name);
|
||||
break;
|
||||
|
||||
case NameKind.Unknown:
|
||||
if (forIntellisense)
|
||||
break;
|
||||
|
||||
throw new SPythonSyntaxVisitorError("UNKNOWN_NAME_{0}",
|
||||
sc, _ident.name);
|
||||
}
|
||||
}
|
||||
|
||||
// кидает ошибки если инициализировать пустой коллекцией
|
||||
// не указывая типа переменной
|
||||
private void CheckInitializationWithEmptyCollection(assign _assign)
|
||||
{
|
||||
// a = []
|
||||
// a = !empty_list()
|
||||
// a = {}
|
||||
// a = !empty_dict()
|
||||
// a = set()
|
||||
if (_assign.from is method_call mc &&
|
||||
mc.dereferencing_value is ident id &&
|
||||
mc.parameters == null)
|
||||
{
|
||||
if (id.name == "!empty_list")
|
||||
{
|
||||
throw new SPythonSyntaxVisitorError("IMPOSSIBLE_TO_INFER_LIST_TYPE",
|
||||
_assign.from.source_context);
|
||||
}
|
||||
else if (id.name == "!empty_dict")
|
||||
{
|
||||
throw new SPythonSyntaxVisitorError("IMPOSSIBLE_TO_INFER_DICT_TYPE",
|
||||
_assign.from.source_context);
|
||||
}
|
||||
if (id.name == "set")
|
||||
{
|
||||
throw new SPythonSyntaxVisitorError("IMPOSSIBLE_TO_INFER_SET_TYPE",
|
||||
_assign.from.source_context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//public override void visit(assign_tuple _assign_tuple)
|
||||
//{
|
||||
//
|
||||
//}
|
||||
|
||||
public override void visit(assign _assign)
|
||||
{
|
||||
if (_assign.operator_type == Operators.Assignment && _assign.to is ident _ident)
|
||||
{
|
||||
if (!symbolTable.IsVisibleToAssign(_ident.name))
|
||||
{
|
||||
// инициализация новой переменной с присвоением
|
||||
if (symbolTable.IsOutermostScope())
|
||||
symbolTable.Add(_ident.name, NameKind.GlobalVariable);
|
||||
else
|
||||
symbolTable.Add(_ident.name, NameKind.LocalVariable);
|
||||
|
||||
if (!forIntellisense)
|
||||
CheckInitializationWithEmptyCollection(_assign);
|
||||
|
||||
var _var_statement = SyntaxTreeBuilder.BuildVarStatementNodeFromAssignNode(_assign);
|
||||
|
||||
ReplaceStatement(_assign, _var_statement);
|
||||
|
||||
ProcessNode(_var_statement);
|
||||
return;
|
||||
}
|
||||
else if (symbolTable.IsInFunctionBody
|
||||
&& symbolTable[_ident.name] == NameKind.GlobalVariable
|
||||
&& !variablesUsedAsGlobal.Contains(_ident.name))
|
||||
{
|
||||
variablesUsedAsGlobal.Add(_ident.name);
|
||||
}
|
||||
}
|
||||
base.visit(_assign);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// Общие сведения об этой сборке предоставляются следующим набором
|
||||
// набора атрибутов. Измените значения этих атрибутов для изменения сведений,
|
||||
// связанные со сборкой.
|
||||
[assembly: AssemblyTitle("SPythonStandardTreeConverter")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("SPythonStandardTreeConverter")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2026")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми
|
||||
// для компонентов COM. Если необходимо обратиться к типу в этой сборке через
|
||||
// COM, задайте атрибуту ComVisible значение TRUE для этого типа.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM
|
||||
[assembly: Guid("431aa1a0-81b9-4d93-9cb1-219bdf7825c9")]
|
||||
|
||||
// Сведения о версии сборки состоят из указанных ниже четырех значений:
|
||||
//
|
||||
// Основной номер версии
|
||||
// Дополнительный номер версии
|
||||
// Номер сборки
|
||||
// Редакция
|
||||
//
|
||||
// Можно задать все значения или принять номера сборки и редакции по умолчанию
|
||||
// используя "*", как показано ниже:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
using PascalABCCompiler.SyntaxTree;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Languages.SPython.Frontend.Converters
|
||||
{
|
||||
public class RetainUsedGlobalVariablesVisitor : BaseChangeVisitor
|
||||
{
|
||||
private HashSet<string> variablesUsedAsGlobal = new HashSet<string>();
|
||||
private int scopeCounter = 0;
|
||||
private declarations decls;
|
||||
private bool isUnitCompiled = false;
|
||||
|
||||
public RetainUsedGlobalVariablesVisitor(HashSet<string> variablesUsedAsGlobal)
|
||||
{
|
||||
this.variablesUsedAsGlobal = variablesUsedAsGlobal;
|
||||
}
|
||||
|
||||
// нужны методы из BaseChangeVisitor, но порядок обхода из WalkingVisitorNew
|
||||
public override void DefaultVisit(syntax_tree_node n)
|
||||
{
|
||||
for (var i = 0; i < n.subnodes_count; i++)
|
||||
ProcessNode(n[i]);
|
||||
}
|
||||
|
||||
public override void Enter(syntax_tree_node stn)
|
||||
{
|
||||
if (stn is statement_list)
|
||||
{
|
||||
scopeCounter++;
|
||||
}
|
||||
if (stn is program_module pm)
|
||||
{
|
||||
decls = pm.program_block.defs;
|
||||
}
|
||||
if (stn is interface_node intn)
|
||||
{
|
||||
isUnitCompiled = true;
|
||||
decls = intn.interface_definitions;
|
||||
}
|
||||
|
||||
base.Enter(stn);
|
||||
}
|
||||
|
||||
public override void Exit(syntax_tree_node stn)
|
||||
{
|
||||
if (stn is statement_list)
|
||||
{
|
||||
scopeCounter--;
|
||||
}
|
||||
base.Exit(stn);
|
||||
}
|
||||
|
||||
public override void visit(var_statement _var_statement)
|
||||
{
|
||||
ident id = _var_statement.var_def.vars.idents[0];
|
||||
if (scopeCounter == 1 && (isUnitCompiled || variablesUsedAsGlobal.Contains(id.name)))
|
||||
{
|
||||
//variablesUsedAsGlobal.Remove(id.name);
|
||||
SourceContext sc = _var_statement.source_context;
|
||||
statement replace_to = new empty_statement();
|
||||
type_definition td = _var_statement.var_def.vars_type;
|
||||
if (_var_statement.var_def.inital_value != null)
|
||||
{
|
||||
replace_to = new assign(id, _var_statement.var_def.inital_value, sc);
|
||||
}
|
||||
if (td == null)
|
||||
{
|
||||
(replace_to as assign).first_assignment_defines_type = true;
|
||||
td = new named_type_reference(new ident("integer"));
|
||||
}
|
||||
var vds = new var_def_statement(new ident_list(id, id.source_context), td, null, definition_attribute.None, false, sc);
|
||||
decls.Add(new variable_definitions(vds, sc), sc);
|
||||
|
||||
ReplaceStatement(_var_statement, replace_to);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace Languages.SPython.Frontend.Converters
|
||||
{
|
||||
internal class ReturnDesugarVisitor : BaseChangeVisitor
|
||||
{
|
||||
public ReturnDesugarVisitor() { }
|
||||
|
||||
public override void visit(return_statement _return_statement)
|
||||
{
|
||||
SourceContext sc = _return_statement.source_context;
|
||||
|
||||
// return;
|
||||
if (_return_statement.expr == null)
|
||||
{
|
||||
procedure_call pc = new procedure_call(new ident("exit", sc), true, sc);
|
||||
Replace(_return_statement, pc);
|
||||
}
|
||||
// return expr;
|
||||
else
|
||||
{
|
||||
statement res_assign = new assign(new ident(StringConstants.result_var_name), _return_statement.expr, Operators.Assignment, sc);
|
||||
statement exit_call = new procedure_call(new ident("exit"), true, sc);
|
||||
statement_list new_statement = new statement_list(res_assign, sc);
|
||||
new_statement.Add(exit_call, sc);
|
||||
Replace(_return_statement, new_statement);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net40</TargetFramework>
|
||||
|
||||
<RootNamespace>Languages.SPython.Frontend.Converters</RootNamespace>
|
||||
|
||||
<OutputPath>..\..\..\..\bin\</OutputPath>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\CoreUtils\PABCCoreUtils.csproj" />
|
||||
<ProjectReference Include="..\..\..\..\Errors\Errors.csproj" />
|
||||
<ProjectReference Include="..\..\..\..\LanguageIntegrator\LanguageIntegrator.csproj" />
|
||||
<ProjectReference Include="..\..\..\..\Localization\Localization.csproj" />
|
||||
<ProjectReference Include="..\..\..\..\StringConstants\StringConstants.csproj" />
|
||||
<ProjectReference Include="..\..\..\..\SyntaxTree\SyntaxTree.csproj" />
|
||||
<ProjectReference Include="..\..\..\..\SyntaxVisitors\SyntaxVisitors.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -1,154 +0,0 @@
|
|||
using Languages.Pascal.Frontend.Converters;
|
||||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
using PascalABCCompiler.SyntaxTreeConverters;
|
||||
using SyntaxVisitors;
|
||||
using SyntaxVisitors.SugarVisitors;
|
||||
using System;
|
||||
using PascalABCCompiler.CoreUtils;
|
||||
|
||||
namespace Languages.SPython.Frontend.Converters
|
||||
{
|
||||
public class StandardSyntaxTreeConverter : BaseSyntaxTreeConverter
|
||||
{
|
||||
public override string Name { get; } = "Standard";
|
||||
|
||||
protected override syntax_tree_node ApplyConversions(syntax_tree_node root, bool forIntellisense)
|
||||
{
|
||||
var generatedNamesManager = new GeneratedNamesManager();
|
||||
|
||||
// кидает ошибки за использование
|
||||
// неподдерживаемых конструкций языка
|
||||
if (!forIntellisense)
|
||||
new UnsupportedConstructsVisitor().ProcessNode(root);
|
||||
|
||||
// добавление всех import ..., from ... import ...
|
||||
// как uses в начале программы для сбора имён из этих модулей
|
||||
if (!forIntellisense)
|
||||
new ImportToUsesVisitor().ProcessNode(root);
|
||||
|
||||
// замена
|
||||
// name bin_bit_op= expr
|
||||
// на
|
||||
// name = name bin_bit_op (expr)
|
||||
new BitwiseAssignmentDesugarVisitor().ProcessNode(root);
|
||||
|
||||
// замена return; на { exit(); }
|
||||
// замена return expr; на { result := expr; exit(); }
|
||||
new ReturnDesugarVisitor().ProcessNode(root);
|
||||
|
||||
// замена вызова функции map(func, sequence)
|
||||
// на func(element) for element in sequence
|
||||
new MapDesugarVisitor().ProcessNode(root);
|
||||
|
||||
// замена генерации последовательностей на Select.Where
|
||||
// (не работает из-за лямбд (скорее всего), если переместить в ApplyConversionsAfterUsedModulesCompilation)
|
||||
new GeneratorObjectDesugarVisitor(root, generatedNamesManager).ProcessNode(root);
|
||||
|
||||
// Выносим выражения с лямбдами из заголовка foreach + считаем максимум 10 вложенных лямбд
|
||||
// украл из паскаля
|
||||
new TryCatchDecorator(StandOutExprWithLambdaInForeachSequenceAndNestedLambdasVisitor.Create(generatedNamesManager), forIntellisense).ProcessNode(root);
|
||||
new VarNamesInMethodsWithSameNameAsClassGenericParamsReplacer(root as compilation_unit).ProcessNode(root);
|
||||
FindOnExceptVarsAndApplyRenameVisitor.Create(generatedNamesManager).ProcessNode(root);
|
||||
|
||||
// дешугаризация составных сравнительных операций (e.g. a == b == c)
|
||||
new CompoundComparisonDesugarVisitor(generatedNamesManager).ProcessNode(root);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
protected override syntax_tree_node ApplyConversionsAfterUsedModulesCompilation(syntax_tree_node root, bool forIntellisense, in CompilationArtifactsUsedBySyntaxConverters compilationArtifacts)
|
||||
{
|
||||
var generatedNamesManager = new GeneratedNamesManager();
|
||||
|
||||
// украл из паскаля, нужны для работы 'for i1, i2 in expr' (работает с кортежными присваиваниями)
|
||||
var binder = new BindCollectLightSymInfo(root as compilation_unit);
|
||||
binder.ProcessNode(root);
|
||||
new TryCatchDecorator(new NewAssignTuplesDesugarVisitor(binder, generatedNamesManager), forIntellisense).ProcessNode(root);
|
||||
|
||||
// Заменяет
|
||||
// variable_name = single_length_string
|
||||
// на
|
||||
// variable_name = str(single_length_string)
|
||||
// чтобы при выведении типа правильно вывел str, а не char
|
||||
new AssignmentCharAsStringVisitor().ProcessNode(root);
|
||||
|
||||
// Сохраняет множество имён функций, которые объявлены в программе для NameCorrectVisitor
|
||||
var ffv = new FindFunctionsNamesVisitor();
|
||||
|
||||
ffv.ProcessNode(root);
|
||||
|
||||
// проверка корректности имён, разрешение неоднозначности
|
||||
// сохранение множества переменных, использующихся как глобальные в ncv.variablesUsedAsGlobal
|
||||
var ncv = new NameCorrectVisitor(System.IO.Path.GetFileNameWithoutExtension(((compilation_unit)root).file_name), forIntellisense,
|
||||
compilationArtifacts.NamesFromUsedUnits, ffv.definedFunctionsNames);
|
||||
|
||||
ncv.ProcessNode(root);
|
||||
|
||||
// замена типов из SPython на типы из PascalABC.NET
|
||||
if (!forIntellisense)
|
||||
new TypeCorrectVisitor().ProcessNode(root);
|
||||
|
||||
// вынос forward объявлений для всех функций в начало
|
||||
new AddForwardDeclarationsVisitor().ProcessNode(root);
|
||||
|
||||
// выполняет генерацию кода для функций с kwarg-аргументами
|
||||
new TryCatchDecorator(new KwargsFunctionDesugarVisitor(), forIntellisense).ProcessNode(root);
|
||||
|
||||
// замена вызова функций с kwarg-аргументами на вызов метода класса
|
||||
new TryCatchDecorator(new FunctionsWithNamedParametersDesugarVisitor(), forIntellisense).ProcessNode(root);
|
||||
|
||||
// выносит объявлений переменных из ncv.variablesUsedAsGlobal на глобальный уровень
|
||||
// (в модулях все переменные, объявленные на глобальном уровне являются глобальными)
|
||||
new RetainUsedGlobalVariablesVisitor(ncv.variablesUsedAsGlobal).ProcessNode(root);
|
||||
|
||||
// удаление специфичных синтаксических узлов Spython'a перед конвертацией в семантическое дерево
|
||||
if (!forIntellisense)
|
||||
new EraseSpythonOnlyNodesVisitor().ProcessNode(root);
|
||||
|
||||
// перестроение структуры дерева, для последующих этапов компиляции
|
||||
// итоговое представление:
|
||||
// 1) forward объявления функций
|
||||
// 2) объявления глобальных переменных (без присваиваний)
|
||||
// 3) объявление функции %%MAIN%%, содержащей компилируемую программу
|
||||
// 4) объявления функций, объявленных в программе
|
||||
// 5) begin %%MAIN%%() end.
|
||||
new TreeNodesRearrangementVisitor().ProcessNode(root);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
private class TryCatchDecorator
|
||||
{
|
||||
private readonly WalkingVisitorNew internalVisitor;
|
||||
private readonly bool forIntellisense;
|
||||
|
||||
public TryCatchDecorator(WalkingVisitorNew internalVisitor, bool forIntellisense)
|
||||
{
|
||||
this.internalVisitor = internalVisitor;
|
||||
this.forIntellisense = forIntellisense;
|
||||
}
|
||||
|
||||
public bool ProcessNode(syntax_tree_node root)
|
||||
{
|
||||
if (forIntellisense)
|
||||
{
|
||||
try
|
||||
{
|
||||
internalVisitor.ProcessNode(root);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
internalVisitor.ProcessNode(root);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
using PascalABCCompiler.Errors;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Languages.SPython.Frontend.Converters
|
||||
{
|
||||
public static class SPythonStringResources
|
||||
{
|
||||
public static string Get(string key)
|
||||
{
|
||||
return PascalABCCompiler.StringResources.Get("SPYTHONSYNTAXTREEVISITORSERROR_" + key);
|
||||
}
|
||||
|
||||
public static string Get(string key, params object[] values)
|
||||
{
|
||||
return (string.Format(Get(key), values));
|
||||
}
|
||||
}
|
||||
|
||||
public class SPythonSyntaxVisitorError : SyntaxError
|
||||
{
|
||||
public SPythonSyntaxVisitorError(string resourcestring, SourceContext sc, params object[] values) : base(SPythonStringResources.Get(resourcestring, values), "", sc, null)
|
||||
{
|
||||
|
||||
}
|
||||
public SPythonSyntaxVisitorError(string resourcestring, PascalABCCompiler.SyntaxTree.syntax_tree_node bad_node)
|
||||
: base(SPythonStringResources.Get(resourcestring), "", bad_node.source_context, bad_node)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,491 +0,0 @@
|
|||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.Parsers;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Languages.SPython.Frontend.Converters
|
||||
{
|
||||
// заполняет таблицу символов динамически, при проходе по дереву сверху вниз
|
||||
public class SymbolTableFillingVisitor : BaseChangeVisitor
|
||||
{
|
||||
protected SymbolTable symbolTable;
|
||||
|
||||
private readonly ILanguageInformation languageInformation = Facade.LanguageProvider.Instance.SelectLanguageByName("SPython").LanguageInformation;
|
||||
|
||||
private readonly bool forIntellisense;
|
||||
|
||||
public SymbolTableFillingVisitor(string unitName, bool forIntellisense, Dictionary<string, Dictionary<string, bool>> par) {
|
||||
symbolTable = new SymbolTable(unitName, par);
|
||||
this.forIntellisense = forIntellisense;
|
||||
}
|
||||
|
||||
// нужны методы из BaseChangeVisitor, но порядок обхода из WalkingVisitorNew
|
||||
public override void DefaultVisit(syntax_tree_node n)
|
||||
{
|
||||
if (n == null) return;
|
||||
for (var i = 0; i < n.subnodes_count; i++)
|
||||
ProcessNode(n[i]);
|
||||
}
|
||||
|
||||
public override void Enter(syntax_tree_node stn)
|
||||
{
|
||||
if (stn is statement_list)
|
||||
{
|
||||
symbolTable.OpenLocalScope();
|
||||
}
|
||||
if (stn is procedure_definition || stn is function_lambda_definition)
|
||||
{
|
||||
symbolTable.OpenLocalScope();
|
||||
symbolTable.IsInFunctionBody = true;
|
||||
}
|
||||
|
||||
base.Enter(stn);
|
||||
}
|
||||
|
||||
public override void Exit(syntax_tree_node stn)
|
||||
{
|
||||
if (stn is procedure_definition || stn is function_lambda_definition)
|
||||
{
|
||||
symbolTable.IsInFunctionBody = false;
|
||||
symbolTable.CloseLocalScope();
|
||||
}
|
||||
if (stn is statement_list)
|
||||
{
|
||||
symbolTable.CloseLocalScope();
|
||||
}
|
||||
|
||||
base.Exit(stn);
|
||||
}
|
||||
|
||||
public override void visit(semantic_check_sugared_statement_node _)
|
||||
{
|
||||
// Скипаем. Узел нужен на семантике, здесь порождает лишние ошибки.
|
||||
}
|
||||
|
||||
private bool IsForwardDeclaration(procedure_header _procedure_header)
|
||||
{
|
||||
foreach (procedure_attribute attr in _procedure_header.proc_attributes.proc_attributes)
|
||||
if (attr.attribute_type is proc_attribute.attr_forward)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void visit(procedure_header _procedure_header)
|
||||
{
|
||||
string procedure_name = _procedure_header.name.meth_name.name;
|
||||
// Сейчас здесь не могут быть встречены forward-объявления функций
|
||||
// но на будущее...
|
||||
if (IsForwardDeclaration(_procedure_header))
|
||||
{
|
||||
symbolTable.Add(procedure_name, NameKind.ForwardDeclaredFunction);
|
||||
}
|
||||
else
|
||||
{
|
||||
symbolTable.AddToParentScope(procedure_name, NameKind.GlobalFunction);
|
||||
}
|
||||
base.visit(_procedure_header);
|
||||
}
|
||||
|
||||
public override void visit(function_header _function_header)
|
||||
{
|
||||
visit(_function_header as procedure_header);
|
||||
}
|
||||
|
||||
public override void visit(function_lambda_definition _function_lambda_definition)
|
||||
{
|
||||
foreach (ident id in _function_lambda_definition.ident_list.list)
|
||||
symbolTable.Add(id.name, NameKind.LocalVariable);
|
||||
|
||||
base.visit(_function_lambda_definition);
|
||||
}
|
||||
|
||||
public override void visit(foreach_stmt _foreach_stmt)
|
||||
{
|
||||
symbolTable.OpenLocalScope();
|
||||
symbolTable.Add(_foreach_stmt.identifier.name, NameKind.LocalVariable);
|
||||
|
||||
if (_foreach_stmt.ext is ident_list _ident_list)
|
||||
{
|
||||
foreach (ident _ident in _ident_list.idents)
|
||||
{
|
||||
symbolTable.Add(_ident.name, NameKind.LocalVariable);
|
||||
}
|
||||
}
|
||||
|
||||
base.visit(_foreach_stmt);
|
||||
symbolTable.CloseLocalScope();
|
||||
}
|
||||
|
||||
public override void visit(interface_node _interface_node)
|
||||
{
|
||||
ProcessNode(_interface_node.uses_modules);
|
||||
ProcessNode(_interface_node.using_namespaces);
|
||||
ProcessNode(_interface_node.interface_definitions);
|
||||
}
|
||||
|
||||
public override void visit(global_statement _global_statement)
|
||||
{
|
||||
foreach (ident _ident in _global_statement.idents.idents)
|
||||
{
|
||||
symbolTable.MakeVisibleForAssignment(_ident.name);
|
||||
}
|
||||
}
|
||||
|
||||
public override void visit(typed_parameters _typed_parameters)
|
||||
{
|
||||
foreach (ident id in _typed_parameters.idents.idents)
|
||||
symbolTable.Add(id.name, NameKind.LocalVariable);
|
||||
|
||||
base.visit(_typed_parameters);
|
||||
}
|
||||
|
||||
public override void visit(var_statement _var_statement)
|
||||
{
|
||||
foreach (ident id in _var_statement.var_def.vars.idents)
|
||||
symbolTable.Add(id.name, NameKind.LocalVariable);
|
||||
|
||||
base.visit(_var_statement);
|
||||
}
|
||||
|
||||
public override void visit(import_statement _import_statement)
|
||||
{
|
||||
if (forIntellisense)
|
||||
return;
|
||||
|
||||
foreach (as_statement as_Statement in _import_statement.modules_names.as_statements)
|
||||
{
|
||||
string real_name = as_Statement.real_name.name;
|
||||
string alias = as_Statement.alias.name;
|
||||
if (languageInformation.SpecialModulesAliases.ContainsKey(real_name))
|
||||
real_name = languageInformation.SpecialModulesAliases[real_name];
|
||||
symbolTable.AddModuleAlias(real_name, alias);
|
||||
}
|
||||
}
|
||||
|
||||
public override void visit(from_import_statement _from_import_statement)
|
||||
{
|
||||
if (forIntellisense)
|
||||
return;
|
||||
|
||||
string module_real_name = _from_import_statement.module_name.name;
|
||||
string module_name = module_real_name;
|
||||
if (languageInformation.SpecialModulesAliases.ContainsKey(module_name))
|
||||
module_name = languageInformation.SpecialModulesAliases[module_name];
|
||||
|
||||
if (_from_import_statement.is_star)
|
||||
{
|
||||
foreach (var kv in symbolTable.ModuleNameToSymbols[module_name])
|
||||
symbolTable.AddAlias(kv.Key, kv.Value, kv.Key, module_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (as_statement as_Statement in _from_import_statement.imported_names.as_statements)
|
||||
{
|
||||
var namesDict = symbolTable.ModuleNameToSymbols[module_name];
|
||||
|
||||
// Учитываем, что в именах может быть обозначение шаблонности
|
||||
var foundName = namesDict.FirstOrDefault(kv => !kv.Key.Contains('`') && kv.Key == as_Statement.real_name.name
|
||||
|| kv.Key.Contains('`') && kv.Key.Substring(0, kv.Key.IndexOf('`')) == as_Statement.real_name.name).Key;
|
||||
|
||||
if (foundName == null)
|
||||
throw new SPythonSyntaxVisitorError("MODULE_{0}_HAS_NO_NAME_{1}",
|
||||
_from_import_statement.source_context, module_real_name, as_Statement.real_name.name);
|
||||
|
||||
symbolTable.AddAlias(as_Statement.real_name.name, namesDict[foundName], as_Statement.alias.name, module_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Возможно рудимент (Выпилить, если не понадобится) 13.12.2025 EVA
|
||||
/* public override void visit(variable_definitions _variable_definitions)
|
||||
{
|
||||
foreach (var_def_statement vds in _variable_definitions.var_definitions)
|
||||
{
|
||||
foreach (ident id in vds.vars.idents)
|
||||
{
|
||||
symbolTable.Add(id.name, NameKind.GlobalVariable);
|
||||
}
|
||||
}
|
||||
base.visit(_variable_definitions);
|
||||
}*/
|
||||
|
||||
[Flags]
|
||||
protected enum NameKind
|
||||
{
|
||||
// Имя отсутствует в текущем контексте
|
||||
Unknown = 0b_0000_0000,
|
||||
// Ключевые слова языка
|
||||
Keyword = 0b_0000_0001,
|
||||
// Имя глобальной переменной
|
||||
GlobalVariable = 0b_0000_0010,
|
||||
// Имя глобальной функции
|
||||
GlobalFunction = 0b_0000_0100,
|
||||
// Имя подключённого модуля или его псевдоним
|
||||
ModuleAlias = 0b_0000_1000,
|
||||
// Имя, подключённое из модуля (не переменная или константа), или его псевдоним
|
||||
ImportedNotVariableAlias = 0b_0001_0000,
|
||||
// Подключенная из модуля константа или переменная
|
||||
ImportedVariableAlias = 0b_0010_0000,
|
||||
// Локальня переменная
|
||||
LocalVariable = 0b_0100_0000,
|
||||
// Имя глобальной forward-объявленной функции
|
||||
ForwardDeclaredFunction = 0b_1000_0000,
|
||||
}
|
||||
|
||||
protected class SymbolTable
|
||||
{
|
||||
private readonly HashSet<string> forwardDeclaredFunctions = new HashSet<string>();
|
||||
|
||||
private readonly string[] Keywords = {
|
||||
"int", "float", "str", "bool", "bigint", // standard types
|
||||
"break", "continue", "exit", "halt", // standard ops
|
||||
"true", "false", // constants
|
||||
};
|
||||
|
||||
private void FillKeywords()
|
||||
{
|
||||
foreach (var keyword in Keywords)
|
||||
currentScope.Add(keyword, NameKind.Keyword);
|
||||
}
|
||||
|
||||
public SymbolTable(string unitName, Dictionary<string, Dictionary<string, bool>> par)
|
||||
{
|
||||
ModuleNameToSymbols = par;
|
||||
entryScope = new LocalScope();
|
||||
currentScope = entryScope;
|
||||
FillKeywords();
|
||||
|
||||
if (!StandardLibraries.Contains(unitName))
|
||||
AddAliasesFromStandartLibraries();
|
||||
}
|
||||
|
||||
// names added to current function with global statements
|
||||
private readonly HashSet<string> NamesAddedByGlobal = new HashSet<string>();
|
||||
|
||||
private bool isInFunctionBody = false;
|
||||
|
||||
public bool IsInFunctionBody {
|
||||
get { return isInFunctionBody; }
|
||||
set
|
||||
{
|
||||
isInFunctionBody = value;
|
||||
if (isInFunctionBody)
|
||||
{
|
||||
Add(StringConstants.result_var_name, NameKind.LocalVariable);
|
||||
}
|
||||
else
|
||||
{
|
||||
NamesAddedByGlobal.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private readonly string[] StandardLibraries = Facade.LanguageProvider.Instance.SelectLanguageByName("SPython").SystemUnitNames;
|
||||
|
||||
private LocalScope currentScope;
|
||||
|
||||
private readonly LocalScope entryScope;
|
||||
|
||||
// moduleRealName -> functions and global variables in this module real names
|
||||
public Dictionary<string, Dictionary<string, bool>> ModuleNameToSymbols { get; set; }
|
||||
|
||||
private void AddAliasesFromStandartLibraries()
|
||||
{
|
||||
foreach (string standardLibrary in StandardLibraries)
|
||||
{
|
||||
if (ModuleNameToSymbols.ContainsKey(standardLibrary))
|
||||
foreach (var kv in ModuleNameToSymbols[standardLibrary])
|
||||
AddAlias(kv.Key, kv.Value, kv.Key, standardLibrary);
|
||||
}
|
||||
}
|
||||
|
||||
public string AliasToRealName(string alias)
|
||||
{
|
||||
return entryScope.GetRealName(alias);
|
||||
}
|
||||
|
||||
public string AliasToModuleName(string alias)
|
||||
{
|
||||
return entryScope.GetDeclaredModuleName(alias);
|
||||
}
|
||||
|
||||
public void MakeVisibleForAssignment(string name)
|
||||
{
|
||||
NamesAddedByGlobal.Add(name);
|
||||
}
|
||||
|
||||
public bool IsVisibleToAssign(string name)
|
||||
{
|
||||
NameKind kind = this[name];
|
||||
if (kind == NameKind.Unknown || kind == NameKind.ImportedNotVariableAlias) return false;
|
||||
|
||||
if (!isInFunctionBody) return true;
|
||||
return (kind != NameKind.GlobalVariable &&
|
||||
kind != NameKind.ImportedVariableAlias) ||
|
||||
NamesAddedByGlobal.Contains(name);
|
||||
}
|
||||
|
||||
public NameKind this[string name]
|
||||
{
|
||||
get {
|
||||
if (currentScope.Contains(name))
|
||||
return currentScope.GetNameKind(name);
|
||||
if (forwardDeclaredFunctions.Contains(name))
|
||||
return NameKind.ForwardDeclaredFunction;
|
||||
return NameKind.Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(string name, NameKind nameType)
|
||||
{
|
||||
switch (nameType)
|
||||
{
|
||||
case NameKind.LocalVariable:
|
||||
case NameKind.GlobalVariable:
|
||||
case NameKind.GlobalFunction:
|
||||
currentScope.Add(name, nameType);
|
||||
break;
|
||||
case NameKind.ForwardDeclaredFunction:
|
||||
forwardDeclaredFunctions.Add(name);
|
||||
break;
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public void AddToParentScope(string name, NameKind nameType)
|
||||
{
|
||||
currentScope.OuterScope.Add(name, nameType);
|
||||
}
|
||||
|
||||
public void AddAlias(string realName, bool isVariable, string alias, string moduleName)
|
||||
{
|
||||
// оставляем только обозначение шаблонности
|
||||
if (alias.Contains("`"))
|
||||
{
|
||||
alias = alias.Substring(0, alias.IndexOf('`') + 1);
|
||||
}
|
||||
// в realName не должно быть обозначения шаблонности, потому что оно пойдет в синтаксический узел
|
||||
if (realName.Contains("`"))
|
||||
{
|
||||
realName = realName.Substring(0, realName.IndexOf('`'));
|
||||
}
|
||||
|
||||
entryScope.Add(alias, realName, isVariable ? NameKind.ImportedVariableAlias : NameKind.ImportedNotVariableAlias, moduleName);
|
||||
}
|
||||
|
||||
public void AddModuleAlias(string realName, string alias)
|
||||
{
|
||||
entryScope.Add(alias, realName, NameKind.ModuleAlias);
|
||||
}
|
||||
|
||||
// Возможно рудимент (Выпилить, если не понадобится) 13.12.2025 EVA
|
||||
/*private void EraseNameAsLocal(string name)
|
||||
{
|
||||
localVariables.EraseName(name);
|
||||
}*/
|
||||
|
||||
public void OpenLocalScope()
|
||||
{
|
||||
currentScope = new LocalScope(currentScope);
|
||||
}
|
||||
|
||||
public void CloseLocalScope()
|
||||
{
|
||||
currentScope.ClearScope();
|
||||
}
|
||||
|
||||
public bool IsOutermostScope()
|
||||
{
|
||||
return currentScope.IsOutermostScope();
|
||||
}
|
||||
|
||||
private class LocalScope
|
||||
{
|
||||
private class SymbolInfo
|
||||
{
|
||||
internal string realName;
|
||||
internal NameKind kind;
|
||||
internal string declaredModuleName;
|
||||
|
||||
internal SymbolInfo(string realName, NameKind kind, string declaredModuleName)
|
||||
{
|
||||
this.realName = realName;
|
||||
this.kind = kind;
|
||||
this.declaredModuleName = declaredModuleName;
|
||||
}
|
||||
}
|
||||
|
||||
public LocalScope OuterScope { get; private set; }
|
||||
private Dictionary<string, SymbolInfo> symbolsInfos = new Dictionary<string, SymbolInfo>();
|
||||
|
||||
public LocalScope(LocalScope outerScope = null)
|
||||
{
|
||||
this.OuterScope = outerScope;
|
||||
}
|
||||
|
||||
public bool Contains(string name) => FindNameRecursive(name) != null;
|
||||
|
||||
// Возможно рудимент (Выпилить, если не понадобится) 13.12.2025 EVA
|
||||
/*public void EraseName(string name)
|
||||
{
|
||||
LocalScope curr = this;
|
||||
|
||||
while (curr != null)
|
||||
{
|
||||
//if (curr.symbols.Contains(name))
|
||||
curr.symbols.Remove(name);
|
||||
curr = curr.outerScope;
|
||||
}
|
||||
}*/
|
||||
|
||||
public void Add(string ident, string realName, NameKind kind, string declaredModuleName = null)
|
||||
{
|
||||
symbolsInfos[ident] = new SymbolInfo(realName, kind, declaredModuleName);
|
||||
}
|
||||
|
||||
public void Add(string ident, NameKind kind)
|
||||
{
|
||||
Add(ident, ident, kind);
|
||||
}
|
||||
|
||||
private SymbolInfo FindNameRecursive(string name)
|
||||
{
|
||||
LocalScope curr = this;
|
||||
|
||||
while (curr != null)
|
||||
{
|
||||
if (curr.symbolsInfos.ContainsKey(name))
|
||||
return curr.symbolsInfos[name];
|
||||
curr = curr.OuterScope;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public string GetRealName(string ident) => FindNameRecursive(ident).realName;
|
||||
|
||||
public NameKind GetNameKind(string ident) => FindNameRecursive(ident).kind;
|
||||
|
||||
public string GetDeclaredModuleName(string ident) => FindNameRecursive(ident).declaredModuleName;
|
||||
|
||||
public void ClearScope()
|
||||
{
|
||||
if (OuterScope != null)
|
||||
{
|
||||
symbolsInfos = OuterScope.symbolsInfos;
|
||||
OuterScope = OuterScope.OuterScope;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsOutermostScope()
|
||||
{
|
||||
return OuterScope.OuterScope == null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
using PascalABCCompiler.SyntaxTree;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Languages.SPython.Frontend.Converters
|
||||
{
|
||||
internal class TreeNodesRearrangementVisitor : BaseChangeVisitor
|
||||
{
|
||||
private procedure_definition mainFunction;
|
||||
|
||||
// declaration после объявления мейна (объявления функций с определениями)
|
||||
private List<declaration> suffix = new List<declaration>();
|
||||
|
||||
private declarations decls;
|
||||
|
||||
private const string mainFunctionName = "%%MAIN%%";
|
||||
|
||||
private bool isInFunction = false;
|
||||
private int scopeCounter = 0;
|
||||
|
||||
public TreeNodesRearrangementVisitor() { }
|
||||
|
||||
// нужны методы из BaseChangeVisitor, но порядок обхода из WalkingVisitorNew
|
||||
public override void DefaultVisit(syntax_tree_node n)
|
||||
{
|
||||
if (n == null) return;
|
||||
for (var i = 0; i < n.subnodes_count; i++)
|
||||
ProcessNode(n[i]);
|
||||
}
|
||||
|
||||
public override void Enter(syntax_tree_node stn)
|
||||
{
|
||||
if (stn is procedure_definition)
|
||||
{
|
||||
isInFunction = true;
|
||||
scopeCounter++;
|
||||
}
|
||||
if (stn is statement_list)
|
||||
{
|
||||
scopeCounter++;
|
||||
}
|
||||
if (stn is program_module pm)
|
||||
{
|
||||
decls = pm.program_block.defs;
|
||||
}
|
||||
if (stn is interface_node intn)
|
||||
{
|
||||
decls = intn.interface_definitions;
|
||||
}
|
||||
|
||||
base.Enter(stn);
|
||||
}
|
||||
|
||||
private void BuildMainFunction(statement_list _statement_list)
|
||||
{
|
||||
statement_list mainBody = _statement_list.TypedClone();
|
||||
mainBody.source_context = mainBody.Parent.source_context; // source context для MAIN охватывает весь файл
|
||||
procedure_header _procedure_header = new procedure_header(mainFunctionName);
|
||||
block _block = new block(null, mainBody, mainBody.source_context);
|
||||
//block _block = new block(null, new statement_list(), _statement_list.source_context);
|
||||
mainFunction = new procedure_definition(_procedure_header, _block, false, _block.source_context);
|
||||
}
|
||||
|
||||
public override void Exit(syntax_tree_node stn)
|
||||
{
|
||||
if (stn is procedure_definition)
|
||||
{
|
||||
isInFunction = false;
|
||||
scopeCounter--;
|
||||
}
|
||||
if (stn is statement_list sl)
|
||||
{
|
||||
scopeCounter--;
|
||||
// вышли из внешнего statement_list внутри begin end.
|
||||
if (!isInFunction && scopeCounter == 0)
|
||||
{
|
||||
BuildMainFunction(sl);
|
||||
decls.list.Add(mainFunction);
|
||||
foreach (declaration decl in suffix)
|
||||
decls.list.Add(decl);
|
||||
sl.list.Clear();
|
||||
sl.Add(new procedure_call(new method_call(new ident(mainFunctionName), null), true));
|
||||
}
|
||||
}
|
||||
|
||||
base.Exit(stn);
|
||||
}
|
||||
|
||||
public override void visit(declarations_as_statement _declarations_as_statement)
|
||||
{
|
||||
foreach (declaration decl in _declarations_as_statement.defs.defs)
|
||||
{
|
||||
suffix.Add(decl);
|
||||
}
|
||||
ReplaceStatement(_declarations_as_statement, new empty_statement());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace Languages.SPython.Frontend.Converters
|
||||
{
|
||||
public class TypeCorrectVisitor : BaseChangeVisitor
|
||||
{
|
||||
|
||||
public override void visit(template_type_reference ttr)
|
||||
{
|
||||
int index = ttr.name.names.Count - 1;
|
||||
if (ttr.name.names[index].name == "tuple")
|
||||
{
|
||||
int cnt = ttr.params_list.Count;
|
||||
if (cnt > 7)
|
||||
{
|
||||
throw new SPythonSyntaxVisitorError("LONG_TUPLE_TYPENAME",
|
||||
ttr.source_context, cnt);
|
||||
}
|
||||
if (cnt > 1)
|
||||
ttr.name.names[index].name = "!tuple" + cnt;
|
||||
}
|
||||
|
||||
base.visit(ttr);
|
||||
}
|
||||
|
||||
public override void visit(named_type_reference _named_type_reference)
|
||||
{
|
||||
ident id = _named_type_reference.names[_named_type_reference.names.Count - 1];
|
||||
|
||||
switch (id.name)
|
||||
{
|
||||
case "int":
|
||||
id.name = "integer";
|
||||
break;
|
||||
case "float":
|
||||
id.name = "real";
|
||||
break;
|
||||
case "str":
|
||||
id.name = "string";
|
||||
break;
|
||||
case "bool":
|
||||
id.name = "boolean";
|
||||
break;
|
||||
case "bigint":
|
||||
id.name = "biginteger";
|
||||
break;
|
||||
|
||||
case "integer":
|
||||
throw new SPythonSyntaxVisitorError("PASCALABCNET_TYPE_{0}_INSTEAD_OF_SPYTHON_TYPE_{1}",
|
||||
id.source_context, id.name, "int");
|
||||
case "real":
|
||||
throw new SPythonSyntaxVisitorError("PASCALABCNET_TYPE_{0}_INSTEAD_OF_SPYTHON_TYPE_{1}",
|
||||
id.source_context, id.name, "float");
|
||||
case "string":
|
||||
throw new SPythonSyntaxVisitorError("PASCALABCNET_TYPE_{0}_INSTEAD_OF_SPYTHON_TYPE_{1}",
|
||||
id.source_context, id.name, "str");
|
||||
case "boolean":
|
||||
throw new SPythonSyntaxVisitorError("PASCALABCNET_TYPE_{0}_INSTEAD_OF_SPYTHON_TYPE_{1}",
|
||||
id.source_context, id.name, "bool");
|
||||
case "biginteger":
|
||||
throw new SPythonSyntaxVisitorError("PASCALABCNET_TYPE_{0}_INSTEAD_OF_SPYTHON_TYPE_{1}",
|
||||
id.source_context, id.name, "bigint");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,137 +0,0 @@
|
|||
using Languages.SPython.Frontend.Converters;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace Languages.Pascal.Frontend.Converters
|
||||
{
|
||||
public class UnsupportedConstructsVisitor : BaseEnterExitVisitor
|
||||
{
|
||||
private int blockLevel = 0;
|
||||
// function returns a value
|
||||
private bool isInFunction = false;
|
||||
// procedure doesn't return value
|
||||
private bool isInProcedure = false;
|
||||
|
||||
public UnsupportedConstructsVisitor() { }
|
||||
|
||||
public override void Enter(syntax_tree_node st)
|
||||
{
|
||||
if (st is statement_list)
|
||||
{
|
||||
++blockLevel;
|
||||
}
|
||||
if (st is procedure_definition pd)
|
||||
{
|
||||
if (pd.proc_header is function_header)
|
||||
isInFunction = true;
|
||||
else
|
||||
isInProcedure = true;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Exit(syntax_tree_node st)
|
||||
{
|
||||
if (st is statement_list)
|
||||
{
|
||||
--blockLevel;
|
||||
}
|
||||
if (st is procedure_definition)
|
||||
{
|
||||
isInProcedure = isInFunction = false;
|
||||
}
|
||||
}
|
||||
|
||||
public override void visit(return_statement _return_statement)
|
||||
{
|
||||
// 'return' или 'return expr' вне функции
|
||||
if (!isInFunction && !isInProcedure)
|
||||
{
|
||||
throw new SPythonSyntaxVisitorError("RETURN_NOT_IN_FUNCTION",
|
||||
_return_statement.source_context);
|
||||
}
|
||||
// 'return' внутри функции, которая должна возвращать значение
|
||||
if (isInFunction && _return_statement.expr == null)
|
||||
{
|
||||
throw new SPythonSyntaxVisitorError("RETURN_NOT_RETURN_VALUE",
|
||||
_return_statement.source_context);
|
||||
}
|
||||
// 'return expr' внутри функции, которая не возвращает значение
|
||||
if (isInProcedure && _return_statement.expr != null)
|
||||
{
|
||||
throw new SPythonSyntaxVisitorError("RETURN_HAS_RETURN_VALUE",
|
||||
_return_statement.expr.source_context);
|
||||
}
|
||||
|
||||
base.visit(_return_statement);
|
||||
}
|
||||
|
||||
public override void visit(global_statement _global_statement)
|
||||
{
|
||||
// конструкция 'global ...' используется вне функции
|
||||
if (!isInProcedure && !isInFunction)
|
||||
{
|
||||
throw new SPythonSyntaxVisitorError("GLOBAL_NOT_IN_FUNCTION",
|
||||
_global_statement.source_context);
|
||||
}
|
||||
// конструкция 'global ...' используется
|
||||
// не на самом внешнем блоке внутри функции
|
||||
if (blockLevel != 2)
|
||||
{
|
||||
throw new SPythonSyntaxVisitorError("GLOBAL_IN_NOT_OUTERMOST_BLOCK",
|
||||
_global_statement.source_context);
|
||||
}
|
||||
|
||||
base.visit(_global_statement);
|
||||
}
|
||||
|
||||
public override void visit(import_statement _import_statement)
|
||||
{
|
||||
// конструкция 'import ...'
|
||||
// используется не на глобальном уровне
|
||||
if (blockLevel > 1)
|
||||
{
|
||||
throw new SPythonSyntaxVisitorError("LOCAL_IMPORT_USE",
|
||||
_import_statement.source_context);
|
||||
}
|
||||
|
||||
base.visit(_import_statement);
|
||||
}
|
||||
|
||||
public override void visit(from_import_statement _from_import_statement)
|
||||
{
|
||||
// конструкция 'from ... import ...'
|
||||
// используется не на глобальном уровне
|
||||
if (blockLevel > 1)
|
||||
{
|
||||
throw new SPythonSyntaxVisitorError("LOCAL_FROM_IMPORT_USE",
|
||||
_from_import_statement.source_context);
|
||||
}
|
||||
|
||||
base.visit(_from_import_statement);
|
||||
}
|
||||
|
||||
public override void visit(procedure_definition _procedure_definition)
|
||||
{
|
||||
// объявление функции не на глобальном уровне
|
||||
if (blockLevel > 1)
|
||||
{
|
||||
throw new SPythonSyntaxVisitorError("LOCAL_FUNCTION_DECLARATION",
|
||||
_procedure_definition.source_context);
|
||||
}
|
||||
|
||||
base.visit(_procedure_definition);
|
||||
}
|
||||
|
||||
public override void visit(assign_tuple _assign_tuple)
|
||||
{
|
||||
// выявление ошибок типа
|
||||
// a, b = 1, 2, 3
|
||||
if (_assign_tuple.expr is tuple_node right_part
|
||||
&& _assign_tuple.vars.Count < right_part.el.Count
|
||||
)
|
||||
{
|
||||
throw new SPythonSyntaxVisitorError("LEFT_SIZE_TUPLE_ASSIGNMENT_LESS_THAN_RIGHT",
|
||||
_assign_tuple.source_context);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
|
||||
// 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 System;
|
||||
using System.Collections;
|
||||
|
|
@ -8,18 +8,19 @@ using PascalABCCompiler.SyntaxTree;
|
|||
using PascalABCCompiler.Parsers;
|
||||
using PascalABCCompiler.Errors;
|
||||
using System.IO;
|
||||
using Languages.Facade;
|
||||
using System.Linq;
|
||||
//using ICSharpCode.SharpDevelop.Dom;
|
||||
|
||||
namespace CodeCompletion
|
||||
{
|
||||
public class CodeCompletionController
|
||||
{
|
||||
private static readonly LanguageProvider LanguageProvider = LanguageProvider.Instance;
|
||||
|
||||
public Dictionary<syntax_tree_node, string> docs = new Dictionary<syntax_tree_node, string>();
|
||||
// static bool parsers_loaded=false;
|
||||
|
||||
public static Controller ParsersController = new Controller();
|
||||
string FileName;
|
||||
string Text;
|
||||
public Dictionary<PascalABCCompiler.SyntaxTree.syntax_tree_node, string> docs = new Dictionary<PascalABCCompiler.SyntaxTree.syntax_tree_node, string>();
|
||||
static bool parsers_loaded=false;
|
||||
public IParser Parser;
|
||||
|
||||
static CodeCompletionController()
|
||||
{
|
||||
//ParsersController.Reload();
|
||||
|
|
@ -28,73 +29,90 @@ namespace CodeCompletion
|
|||
|
||||
public CodeCompletionController()
|
||||
{
|
||||
/*if (!parsers_loaded)
|
||||
if (!parsers_loaded)
|
||||
{
|
||||
//ParsersController.Reload();
|
||||
parsers_loaded = true;
|
||||
}*/
|
||||
}
|
||||
//dconv = new DomConverter(this);
|
||||
}
|
||||
|
||||
public static PascalABCCompiler.Compiler comp;// = new PascalABCCompiler.Compiler();
|
||||
public static Dictionary<string, string> StandartDirectories = new Dictionary<string, string>();
|
||||
public static Hashtable StandartDirectories = new Hashtable();
|
||||
public static Hashtable comp_modules = new Hashtable(StringComparer.OrdinalIgnoreCase);
|
||||
// public static Hashtable parsers = new Hashtable(StringComparer.OrdinalIgnoreCase);
|
||||
public static Hashtable parsers = new Hashtable(StringComparer.OrdinalIgnoreCase);
|
||||
public static Dictionary<string, InterfaceUnitScope> pabcNamespaces = new Dictionary<string, InterfaceUnitScope>();
|
||||
|
||||
public static string currentLanguageISO;
|
||||
// public static PascalABCCompiler.Parsers.IParser currentParser;
|
||||
// static string cur_ext = ".pas";
|
||||
private static ILanguage currentLanguage;
|
||||
static string doctagsParserExtension = ".pasdt" + PascalABCCompiler.Parsers.Controller.HideParserExtensionPostfixChar;
|
||||
//public static PascalABCCompiler.Parsers.IParser currentParser;
|
||||
static string cur_ext = ".pas";
|
||||
private static IParser currentParser;
|
||||
|
||||
/// <summary>
|
||||
/// Запоминает язык текущего открытого файла.
|
||||
/// Если язык файла не поддерживается в системе, то ошибка не выбрасывается,
|
||||
/// текущему языку присваивается null.
|
||||
/// </summary>
|
||||
public static void SetLanguage(string fileName)
|
||||
public static void SetParser(string ext)
|
||||
{
|
||||
currentLanguage = LanguageProvider.SelectLanguageByExtensionSafe(fileName);
|
||||
cur_ext = ext;
|
||||
currentParser = null;
|
||||
}
|
||||
|
||||
public void ResetNamespaces()
|
||||
{
|
||||
pabcNamespaces.Clear();
|
||||
}
|
||||
|
||||
private static string get_doctagsParserExtension(string ext)
|
||||
{
|
||||
return ext + "dt" + PascalABCCompiler.Parsers.Controller.HideParserExtensionPostfixChar;
|
||||
}
|
||||
|
||||
public static ILanguage CurrentLanguage
|
||||
public static IParser CurrentParser
|
||||
{
|
||||
get
|
||||
{
|
||||
return currentLanguage;
|
||||
if (currentParser == null)
|
||||
currentParser = parsers[cur_ext] as IParser;
|
||||
return currentParser;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Поддерживается ли Intellisense для текущего языка
|
||||
/// </summary>
|
||||
public static bool IntellisenseAvailable()
|
||||
internal compilation_unit ParsersControllerGetCompilationUnit(string FileName, string Text, List<Error> ErrorsList, List<CompilerWarning> Warnings)
|
||||
{
|
||||
return CurrentLanguage != null && CurrentLanguage.LanguageIntellisenseSupport != null;
|
||||
string ext = Path.GetExtension(FileName);
|
||||
Parser = ParsersController.selectParser(ext.ToLower());
|
||||
parsers[ext] = Parser;
|
||||
compilation_unit cu = null;
|
||||
cu = ParsersController.GetCompilationUnit(FileName, Text, ErrorsList, Warnings);
|
||||
//ParsersController.GetExpression("test.pas", "a+b", new List<PascalABCCompiler.Errors.Error>());
|
||||
return cu;
|
||||
}
|
||||
|
||||
internal compilation_unit ParsersControllerGetCompilationUnitSpecial(string FileName, string Text, List<Error> ErrorsList, List<CompilerWarning> Warnings)
|
||||
{
|
||||
string ext = Path.GetExtension(FileName);
|
||||
Parser = ParsersController.selectParser(ext.ToLower());
|
||||
parsers[ext] = Parser;
|
||||
compilation_unit cu = null;
|
||||
cu = ParsersController.GetCompilationUnitSpecial(FileName, Text, ErrorsList, Warnings);
|
||||
//ParsersController.GetExpression("test.pas","a+b",new List<PascalABCCompiler.Errors.Error>());
|
||||
return cu;
|
||||
}
|
||||
|
||||
public DomConverter Compile(string FileName, string Text)
|
||||
{
|
||||
List<Error> ErrorsList = new List<Error>();
|
||||
this.Text = Text;
|
||||
this.FileName = FileName;
|
||||
List<PascalABCCompiler.Errors.Error> ErrorsList = new List<PascalABCCompiler.Errors.Error>();
|
||||
List<CompilerWarning> Warnings = new List<CompilerWarning>();
|
||||
compilation_unit cu = null;
|
||||
|
||||
ILanguage currentLanguage = LanguageProvider.SelectLanguageByExtension(FileName);
|
||||
|
||||
PascalABCCompiler.SyntaxTree.compilation_unit cu = null;
|
||||
string ext = Path.GetExtension(FileName);
|
||||
try
|
||||
{
|
||||
cu = currentLanguage.Parser.GetCompilationUnit(FileName, Text, ErrorsList, Warnings, ParseMode.Normal, false);
|
||||
|
||||
cu = ParsersControllerGetCompilationUnit(FileName, Text, ErrorsList, Warnings);
|
||||
ErrorsList.Clear();
|
||||
|
||||
if (currentLanguage.DocParser != null)
|
||||
BuildDocs(Text, cu, currentLanguage.DocParser);
|
||||
|
||||
PascalABCCompiler.SyntaxTree.documentation_comment_list dt = ParsersController.Compile(System.IO.Path.ChangeExtension(FileName, get_doctagsParserExtension(ext)), Text/*+")))));end."*/, ErrorsList, Warnings, PascalABCCompiler.Parsers.ParseMode.Normal) as PascalABCCompiler.SyntaxTree.documentation_comment_list;
|
||||
PascalABCCompiler.DocumentationConstructor docconst = new PascalABCCompiler.DocumentationConstructor();
|
||||
if (cu != null)
|
||||
docs = docconst.Construct(cu, dt);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
@ -102,12 +120,6 @@ namespace CodeCompletion
|
|||
File.AppendAllText("log.txt", e.Message + Environment.NewLine + e.StackTrace + Environment.NewLine);
|
||||
#endif
|
||||
}
|
||||
|
||||
TypeScope.instance_cache.Clear();
|
||||
|
||||
// очистка кэша и данных от старых компиляций, чтобы при новой компиляции не появились ссылки на старые данные
|
||||
TypeTable.Clear();
|
||||
|
||||
DomConverter dconv = new DomConverter(this);
|
||||
if (cu != null)
|
||||
{
|
||||
|
|
@ -115,26 +127,29 @@ namespace CodeCompletion
|
|||
|
||||
dconv.ConvertToDom(cu);
|
||||
}
|
||||
// Попытка поменять текст программы ниже сработает только для PascalABC.NET
|
||||
else if (currentLanguage == LanguageProvider.MainLanguage)
|
||||
else
|
||||
{
|
||||
|
||||
ErrorsList.Clear();
|
||||
Warnings.Clear();
|
||||
try
|
||||
{
|
||||
//cu = ParsersController.GetComilationUnit(FileName, Text+")))));end.",comp.CompilerOptions.ParserSearchPatchs,ErrorsList);
|
||||
//cu = ParsersControllerGetComilationUnit(FileName, get_temp_text(Text), ErrorsList, true);
|
||||
string tmp = ParsersHelper.GetModifiedProgramm(Text);
|
||||
if (tmp != null)
|
||||
{
|
||||
cu = currentLanguage.Parser.GetCompilationUnit(FileName, Text, ErrorsList, Warnings, ParseMode.Special, false);
|
||||
cu = ParsersControllerGetCompilationUnitSpecial(FileName, tmp, ErrorsList, Warnings);
|
||||
}
|
||||
if (comp_modules[FileName] == null)
|
||||
{
|
||||
if (cu == null)
|
||||
cu = get_fictive_unit(Text, FileName);
|
||||
}
|
||||
|
||||
ErrorsList.Clear();
|
||||
Warnings.Clear();
|
||||
|
||||
if (currentLanguage.DocParser != null)
|
||||
BuildDocs(Text, cu, currentLanguage.DocParser);
|
||||
|
||||
PascalABCCompiler.SyntaxTree.documentation_comment_list dt = ParsersController.Compile(System.IO.Path.ChangeExtension(FileName, get_doctagsParserExtension(ext)), Text + ")))));end.", ErrorsList, Warnings, PascalABCCompiler.Parsers.ParseMode.Normal) as PascalABCCompiler.SyntaxTree.documentation_comment_list;
|
||||
PascalABCCompiler.DocumentationConstructor docconst = new PascalABCCompiler.DocumentationConstructor();
|
||||
if (cu != null)
|
||||
docs = docconst.Construct(cu, dt);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
@ -149,91 +164,162 @@ namespace CodeCompletion
|
|||
}
|
||||
}
|
||||
if (docs != null) docs.Clear();
|
||||
//if (dconv.is_compiled) comp_modules[file_name]=dconv;
|
||||
//if (dconv.is_compiled) comp_modules[FileName]=dconv;
|
||||
return dconv;
|
||||
//ConvertToDom(cu);
|
||||
}
|
||||
|
||||
private void BuildDocs(string Text, compilation_unit cu, IDocParser docParser)
|
||||
//vremenno, potom ubrat
|
||||
private compilation_unit get_fictive_unit(string s, string FileName)
|
||||
{
|
||||
documentation_comment_list dt = docParser.BuildTree(Text);
|
||||
PascalABCCompiler.DocumentationConstructor docconst = new PascalABCCompiler.DocumentationConstructor();
|
||||
if (cu != null)
|
||||
docs = docconst.Construct(cu, dt);
|
||||
program_module prog = new program_module();
|
||||
int line = 1;
|
||||
int col = 1;
|
||||
for (int i = 0; i < s.Length; i++)
|
||||
if (s[i] == '\n')
|
||||
{
|
||||
line++;
|
||||
col = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
col++;
|
||||
}
|
||||
prog.source_context = new SourceContext(1, 1, line + 3, 3);
|
||||
prog.program_block = new block();
|
||||
prog.file_name = FileName;
|
||||
statement_list sl = new statement_list();
|
||||
prog.program_block.program_code = sl;
|
||||
prog.program_block.program_code.left_logical_bracket = new token_info("begin");
|
||||
prog.program_block.program_code.left_logical_bracket.source_context = new SourceContext(1, 1, 1, 5);
|
||||
prog.program_block.program_code.right_logical_bracket = new token_info("end");
|
||||
prog.program_block.program_code.right_logical_bracket.source_context = new SourceContext(line + 3, 1, line + 3, 3);
|
||||
sl.subnodes.Add(new empty_statement());
|
||||
return prog;
|
||||
}
|
||||
|
||||
public compilation_unit ParseOnlySyntaxTree(string FileName, string Text)
|
||||
public PascalABCCompiler.SyntaxTree.compilation_unit ParseOnlySyntaxTree(string FileName, string Text)
|
||||
{
|
||||
var currentLanguage = LanguageProvider.SelectLanguageByExtensionSafe(FileName);
|
||||
|
||||
if (currentLanguage == null)
|
||||
return null;
|
||||
|
||||
var cu = currentLanguage.Parser.GetCompilationUnit(FileName, Text, new List<Error>(), new List<CompilerWarning>(), ParseMode.Normal, false);
|
||||
|
||||
List<PascalABCCompiler.Errors.Error> ErrorsList = new List<PascalABCCompiler.Errors.Error>();
|
||||
List<CompilerWarning> Warnings = new List<CompilerWarning>();
|
||||
PascalABCCompiler.SyntaxTree.compilation_unit cu = ParsersControllerGetCompilationUnit(FileName, Text, ErrorsList, Warnings);
|
||||
return cu;
|
||||
}
|
||||
|
||||
public DomConverter CompileAllIfNeed(string FileName, bool parse_only_interface=false)
|
||||
public DomConverter CompileAllIfNeed(string FileName, string Text)
|
||||
{
|
||||
string Text = comp.GetSourceFileText(FileName);
|
||||
List<Error> ErrorsList = new List<Error>();
|
||||
DomConverter dconv = (DomConverter)comp_modules[FileName];
|
||||
if (dconv != null) return dconv;
|
||||
this.Text = Text;
|
||||
this.FileName = FileName;
|
||||
string ext = Path.GetExtension(FileName);
|
||||
List<PascalABCCompiler.Errors.Error> ErrorsList = new List<PascalABCCompiler.Errors.Error>();
|
||||
List<CompilerWarning> Warnings = new List<CompilerWarning>();
|
||||
compilation_unit cu = null;
|
||||
|
||||
DomConverter dconv = new DomConverter(this);
|
||||
|
||||
ILanguage currentLanguage = LanguageProvider.SelectLanguageByExtensionSafe(FileName);
|
||||
|
||||
if (currentLanguage == null)
|
||||
return dconv;
|
||||
|
||||
if (Text != null)
|
||||
{
|
||||
cu = currentLanguage.Parser.GetCompilationUnit(FileName, Text, ErrorsList, Warnings, ParseMode.Normal, true);
|
||||
}
|
||||
PascalABCCompiler.SyntaxTree.compilation_unit cu = ParsersController.GetCompilationUnit(FileName, Text, ErrorsList, Warnings);
|
||||
Parser = ParsersController.selectParser(Path.GetExtension(FileName).ToLower());
|
||||
ErrorsList.Clear();
|
||||
Warnings.Clear();
|
||||
|
||||
if (currentLanguage.DocParser != null)
|
||||
BuildDocs(Text, cu, currentLanguage.DocParser);
|
||||
|
||||
dconv.visitor.parse_only_interface = parse_only_interface;
|
||||
PascalABCCompiler.SyntaxTree.documentation_comment_list dt = ParsersController.Compile(System.IO.Path.ChangeExtension(FileName, get_doctagsParserExtension(ext)), Text, ErrorsList, Warnings, PascalABCCompiler.Parsers.ParseMode.Normal) as PascalABCCompiler.SyntaxTree.documentation_comment_list;
|
||||
PascalABCCompiler.DocumentationConstructor docconst = new PascalABCCompiler.DocumentationConstructor();
|
||||
if (cu != null)
|
||||
docs = docconst.Construct(cu, dt);
|
||||
dconv = new DomConverter(this);
|
||||
if (CodeCompletionTools.XmlDoc.LookupLocalizedXmlDocForUnitWithSources(FileName, CodeCompletionController.currentLanguageISO) != null)
|
||||
{
|
||||
dconv.visitor.add_doc_from_text = false;
|
||||
}
|
||||
|
||||
if (cu != null)
|
||||
{
|
||||
dconv.ConvertToDom(cu);
|
||||
}
|
||||
// Попытка поменять текст программы ниже сработает только для PascalABC.NET
|
||||
else if (currentLanguage == LanguageProvider.MainLanguage)
|
||||
else
|
||||
{
|
||||
ErrorsList.Clear();
|
||||
Warnings.Clear();
|
||||
|
||||
//cu = ParsersControllerGetComilationUnit(FileName, Text, ErrorsList, true);
|
||||
if (comp_modules[FileName] == null)
|
||||
{
|
||||
string tmp = ParsersHelper.GetModifiedProgramm(Text);
|
||||
if (tmp != null)
|
||||
{
|
||||
cu = currentLanguage.Parser.GetCompilationUnit(FileName, Text, ErrorsList, Warnings, ParseMode.Special, true);
|
||||
cu = ParsersControllerGetCompilationUnitSpecial(FileName, tmp, ErrorsList, Warnings);
|
||||
ErrorsList.Clear();
|
||||
}
|
||||
|
||||
ErrorsList.Clear();
|
||||
Warnings.Clear();
|
||||
if (cu == null)
|
||||
cu = get_fictive_unit(Text, FileName);
|
||||
}
|
||||
|
||||
if (currentLanguage.DocParser != null)
|
||||
BuildDocs(Text, cu, currentLanguage.DocParser);
|
||||
|
||||
ErrorsList.Clear();
|
||||
Warnings.Clear();
|
||||
dt = ParsersController.Compile(System.IO.Path.ChangeExtension(FileName, get_doctagsParserExtension(ext)), Text + ")))));end.", ErrorsList, Warnings, PascalABCCompiler.Parsers.ParseMode.Normal) as PascalABCCompiler.SyntaxTree.documentation_comment_list;
|
||||
//PascalABCCompiler.DocumentationConstructor docconst = new PascalABCCompiler.DocumentationConstructor();
|
||||
if (cu != null)
|
||||
docs = docconst.Construct(cu, dt);
|
||||
if (CodeCompletionTools.XmlDoc.LookupLocalizedXmlDocForUnitWithSources(FileName, CodeCompletionController.currentLanguageISO) != null)
|
||||
{
|
||||
dconv.visitor.add_doc_from_text = false;
|
||||
dconv.visitor.add_doc_from_text = false;
|
||||
}
|
||||
if (cu != null)
|
||||
{
|
||||
dconv.ConvertToDom(cu);
|
||||
}
|
||||
}
|
||||
//comp_modules[FileName] = dconv;
|
||||
if (dconv.is_compiled) comp_modules[FileName] = dconv;
|
||||
|
||||
if (docs != null) docs.Clear();
|
||||
//GC.Collect();
|
||||
return dconv;
|
||||
}
|
||||
|
||||
public DomConverter CompileAllIfNeed(string FileName, bool parse_only_interface=false)
|
||||
{
|
||||
this.FileName = FileName;
|
||||
this.Text = comp.GetSourceFileText(FileName);
|
||||
string ext = Path.GetExtension(FileName);
|
||||
List<PascalABCCompiler.Errors.Error> ErrorsList = new List<PascalABCCompiler.Errors.Error>();
|
||||
List<CompilerWarning> Warnings = new List<CompilerWarning>();
|
||||
PascalABCCompiler.SyntaxTree.compilation_unit cu = null;
|
||||
if (Text != null)
|
||||
{
|
||||
cu = ParsersController.GetCompilationUnit(FileName, Text, ErrorsList, Warnings);
|
||||
}
|
||||
Parser = ParsersController.selectParser(Path.GetExtension(FileName).ToLower());
|
||||
ErrorsList.Clear();
|
||||
Warnings.Clear();
|
||||
PascalABCCompiler.SyntaxTree.documentation_comment_list dt = ParsersController.Compile(System.IO.Path.ChangeExtension(FileName, get_doctagsParserExtension(ext)), Text, ErrorsList, Warnings, PascalABCCompiler.Parsers.ParseMode.Normal) as PascalABCCompiler.SyntaxTree.documentation_comment_list;
|
||||
PascalABCCompiler.DocumentationConstructor docconst = new PascalABCCompiler.DocumentationConstructor();
|
||||
if (cu != null)
|
||||
docs = docconst.Construct(cu, dt);
|
||||
DomConverter dconv = new DomConverter(this);
|
||||
dconv.visitor.parse_only_interface = parse_only_interface;
|
||||
if (CodeCompletionTools.XmlDoc.LookupLocalizedXmlDocForUnitWithSources(FileName, CodeCompletionController.currentLanguageISO) != null)
|
||||
{
|
||||
dconv.visitor.add_doc_from_text = false;
|
||||
}
|
||||
if (cu != null)
|
||||
dconv.ConvertToDom(cu);
|
||||
else
|
||||
{
|
||||
ErrorsList.Clear();
|
||||
Warnings.Clear();
|
||||
//cu = ParsersControllerGetComilationUnit(FileName, Text, ErrorsList, true);
|
||||
if (comp_modules[FileName] == null)
|
||||
{
|
||||
string tmp = ParsersHelper.GetModifiedProgramm(Text);
|
||||
if (tmp != null)
|
||||
{
|
||||
cu = ParsersControllerGetCompilationUnitSpecial(FileName, tmp, ErrorsList, Warnings);
|
||||
ErrorsList.Clear();
|
||||
}
|
||||
if (cu == null)
|
||||
cu = get_fictive_unit(Text, FileName);
|
||||
}
|
||||
ErrorsList.Clear();
|
||||
Warnings.Clear();
|
||||
dt = ParsersController.Compile(System.IO.Path.ChangeExtension(FileName, get_doctagsParserExtension(ext)), Text, ErrorsList, Warnings, PascalABCCompiler.Parsers.ParseMode.Normal) as PascalABCCompiler.SyntaxTree.documentation_comment_list;
|
||||
if (cu != null)
|
||||
docs = docconst.Construct(cu, dt);
|
||||
if (CodeCompletionTools.XmlDoc.LookupLocalizedXmlDocForUnitWithSources(FileName, CodeCompletionController.currentLanguageISO) != null)
|
||||
{
|
||||
dconv.visitor.add_doc_from_text = false;
|
||||
}
|
||||
if (cu != null)
|
||||
{
|
||||
dconv.ConvertToDom(cu);
|
||||
|
|
@ -241,7 +327,7 @@ namespace CodeCompletion
|
|||
}
|
||||
if (dconv.is_compiled) comp_modules[FileName] = dconv;
|
||||
if (docs != null) docs.Clear();
|
||||
//comp_modules[file_name] = dconv;
|
||||
//comp_modules[FileName] = dconv;
|
||||
// GC.Collect();
|
||||
return dconv;
|
||||
}
|
||||
|
|
@ -249,7 +335,7 @@ namespace CodeCompletion
|
|||
|
||||
public class CodeCompletionNameHelper
|
||||
{
|
||||
public static readonly string system_unit_file_name = PascalABCCompiler.StringConstants.pascalSystemUnitName;
|
||||
public static readonly string system_unit_file_name = PascalABCCompiler.TreeConverter.compiler_string_consts.system_unit_file_name;
|
||||
public static string system_unit_file_full_name;
|
||||
private static CodeCompletionNameHelper helper;
|
||||
|
||||
|
|
@ -259,63 +345,34 @@ namespace CodeCompletion
|
|||
|
||||
public PascalABCCompiler.Parsers.KeywordKind GetKeywordKind(string name)
|
||||
{
|
||||
if (CodeCompletionController.IntellisenseAvailable())
|
||||
return CodeCompletionController.CurrentLanguage.LanguageIntellisenseSupport.GetKeywordKind(name);
|
||||
if (CodeCompletionController.CurrentParser != null)
|
||||
return CodeCompletionController.CurrentParser.LanguageInformation.GetKeywordKind(name);
|
||||
return PascalABCCompiler.Parsers.KeywordKind.None;
|
||||
}
|
||||
|
||||
public bool IsKeyword(string name)
|
||||
public string[] GetKeywords()
|
||||
{
|
||||
if (CodeCompletionController.IntellisenseAvailable())
|
||||
{
|
||||
return CodeCompletionController.CurrentLanguage.LanguageIntellisenseSupport.IsKeyword(name);
|
||||
}
|
||||
return false;
|
||||
if (CodeCompletionController.CurrentParser != null)
|
||||
return CodeCompletionController.CurrentParser.LanguageInformation.Keywords;
|
||||
return new string[0];
|
||||
}
|
||||
|
||||
public List<string> GetKeywords()
|
||||
public string[] GetTypeKeywords()
|
||||
{
|
||||
if (CodeCompletionController.IntellisenseAvailable())
|
||||
return CodeCompletionController.CurrentLanguage.LanguageInformation.KeywordsStorage.KeywordsForIntellisenseList;
|
||||
return new List<string>();
|
||||
}
|
||||
|
||||
public List<string> GetTypeKeywords()
|
||||
{
|
||||
if (CodeCompletionController.IntellisenseAvailable())
|
||||
return CodeCompletionController.CurrentLanguage.LanguageInformation.KeywordsStorage.TypeKeywords;
|
||||
return new List<string>();
|
||||
if (CodeCompletionController.CurrentParser != null)
|
||||
return CodeCompletionController.CurrentParser.LanguageInformation.TypeKeywords;
|
||||
return new string[0];
|
||||
}
|
||||
|
||||
const string LibSourceDirectoryIdent = "%LIBSOURCEDIRECTORY%";
|
||||
public static string FindSourceFileName(string unit_name, out int found_dir_ind, ILanguage currentUnitLanguage, params string[] ddirs)
|
||||
public static string FindSourceFileName(string unit_name, 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.GetCurrentSearchDirectories(currentUnitLanguage));
|
||||
// Надо как-то проверять, что мы не в инсталированной версии EVA
|
||||
if (MainLibSourceDirectoryExists())
|
||||
Dirs.AddRange(GetLibSourceDirectories(currentUnitLanguage));
|
||||
return CodeCompletionController.comp.FindSourceFileNameInDirs(unit_name, out found_dir_ind, currentUnitLanguage, Dirs.ToArray());
|
||||
}
|
||||
|
||||
public static bool MainLibSourceDirectoryExists()
|
||||
{
|
||||
return CodeCompletionController.StandartDirectories.ContainsKey(LibSourceDirectoryIdent)
|
||||
&& Directory.Exists(CodeCompletionController.StandartDirectories[LibSourceDirectoryIdent]);
|
||||
}
|
||||
|
||||
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();
|
||||
Dirs.Add(CodeCompletionController.comp.CompilerOptions.SearchDirectory);
|
||||
if (CodeCompletionController.StandartDirectories.ContainsKey(LibSourceDirectoryIdent))
|
||||
Dirs.Add((string)CodeCompletionController.StandartDirectories[LibSourceDirectoryIdent]);
|
||||
return CodeCompletionController.comp.FindSourceFileName(unit_name, Dirs.ToArray());
|
||||
}
|
||||
|
||||
public static CodeCompletionNameHelper Helper
|
||||
|
|
@ -336,7 +393,7 @@ namespace CodeCompletion
|
|||
public static string GetModifiedProgramm(string src)
|
||||
{
|
||||
sb.Remove(0,sb.Length);
|
||||
if (!src.TrimEnd().EndsWith("end."))
|
||||
if (!src.EndsWith("end."))
|
||||
{
|
||||
sb.AppendLine(src);
|
||||
sb.AppendLine();
|
||||
|
|
|
|||
|
|
@ -1,22 +1,131 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net40</TargetFramework>
|
||||
|
||||
<OutputPath>..\bin\</OutputPath>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>9.0.30729</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{1AB15F6E-C22E-499A-A7ED-54BA7DE5CFA6}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>CodeCompletion</RootNamespace>
|
||||
<AssemblyName>CodeCompletion</AssemblyName>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<OldToolsVersion>4.0</OldToolsVersion>
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile />
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\bin\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\bin\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Compiler\Compiler.csproj" />
|
||||
<ProjectReference Include="..\Errors\Errors.csproj" />
|
||||
<ProjectReference Include="..\LanguageIntegrator\LanguageIntegrator.csproj" />
|
||||
<ProjectReference Include="..\ParserTools\ParserTools.csproj" />
|
||||
<ProjectReference Include="..\SemanticTree\SemanticTree.csproj" />
|
||||
<ProjectReference Include="..\StringConstants\StringConstants.csproj" />
|
||||
<ProjectReference Include="..\SyntaxTree\SyntaxTree.csproj" />
|
||||
<ProjectReference Include="..\TreeConverter\TreeConverter.csproj" />
|
||||
<Reference Include="Microsoft.VisualBasic" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CodeCompletion.cs" />
|
||||
<Compile Include="CodeCompletionPCUReader.cs" />
|
||||
<Compile Include="CodeFormatter.cs" />
|
||||
<Compile Include="DomConverter.cs" />
|
||||
<Compile Include="DomSyntaxTreeVisitor.cs" />
|
||||
<Compile Include="ExpressionEvaluator.cs" />
|
||||
<Compile Include="ExpressionVisitor.cs" />
|
||||
<Compile Include="FindReferences.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SemanticTreeWalker.cs" />
|
||||
<Compile Include="SymTable.cs" />
|
||||
<Compile Include="Testing.cs" />
|
||||
<Compile Include="TypeTable.cs" />
|
||||
<Compile Include="UnitXmlDocs.cs" />
|
||||
<Compile Include="XmlDocs.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Compiler\Compiler.csproj">
|
||||
<Project>{1E42361A-EDA3-4872-88AF-A3AAF600D36D}</Project>
|
||||
<Name>Compiler</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Errors\Errors.csproj">
|
||||
<Project>{44A01F9E-DCE7-470C-AAE5-C3DE0CCBEE3B}</Project>
|
||||
<Name>Errors</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\ParserTools\ParserTools.csproj">
|
||||
<Project>{AF2EFD7B-69DD-4B43-AF65-B59B29349C23}</Project>
|
||||
<Name>ParserTools</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SemanticTree\SemanticTree.csproj">
|
||||
<Project>{613E0DDA-AA8A-437C-AC45-507B47429FF9}</Project>
|
||||
<Name>SemanticTree</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SyntaxTree\SyntaxTree.csproj">
|
||||
<Project>{C2CAC65A-B2AE-4CCC-B067-E6B8E75DF73A}</Project>
|
||||
<Name>SyntaxTree</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\TreeConverter\TreeConverter.csproj">
|
||||
<Project>{1C9C945A-586D-42A2-A06B-65D84FA7FF78}</Project>
|
||||
<Name>TreeConverter</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Клиентский профиль .NET Framework 3.5 SP1</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Установщик Windows 3.1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
|
|
@ -77,9 +77,7 @@ namespace CodeCompletion
|
|||
if (Header[i] != PCUFile.Header[i])
|
||||
return false;
|
||||
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;
|
||||
}
|
||||
|
|
@ -98,7 +96,7 @@ namespace CodeCompletion
|
|||
{
|
||||
//(ssyy) DarkStar - Ïî÷åìó áû â ýòîì ñëó÷àå ïðîñòî íå ïåðåêîìïèëèðîâàòü ìîäóëü?
|
||||
CloseUnit();
|
||||
throw new InvalidPCUFile(unit_name);
|
||||
throw new InvalidPCUFule(unit_name);
|
||||
}
|
||||
|
||||
private void ReadPCUHeader()
|
||||
|
|
@ -109,10 +107,7 @@ namespace CodeCompletion
|
|||
pcu_file.SourceFileName = br.ReadString();
|
||||
else
|
||||
pcu_file.SourceFileName = Path.GetFileNameWithoutExtension(FileName);
|
||||
|
||||
pcu_file.languageName = br.ReadString();
|
||||
|
||||
int num_names = br.ReadInt32();
|
||||
int num_names = br.ReadInt32();
|
||||
pcu_file.names = new NameRef[num_names];
|
||||
for (int i=0; i<num_names; i++)
|
||||
{
|
||||
|
|
@ -120,7 +115,6 @@ 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();
|
||||
|
|
@ -131,7 +125,6 @@ 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();
|
||||
|
|
|
|||
|
|
@ -416,13 +416,7 @@ namespace CodeFormatters
|
|||
lines[i] = new string(' ', addit_pos_for_multiline) + lines[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
lines[i] = new string(' ', off) + lines[i].Trim();
|
||||
if (lines[i].EndsWith(" else"))
|
||||
lines[i] += " ";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -490,7 +484,7 @@ namespace CodeFormatters
|
|||
if (s.Length > 0 && !char.IsWhiteSpace(s[0]) && s[0] != '{' && !s.StartsWith("//") && !s.StartsWith("(*") && s[0] != ';' && !char.IsWhiteSpace(s[0]) && (sb.Length == 0 || !char.IsWhiteSpace(sb[sb.Length-1])))
|
||||
sb.Append(' ');
|
||||
}
|
||||
else if (s.IndexOf("//") == -1)
|
||||
else
|
||||
s = s.TrimStart(' ', '\t');
|
||||
sb.Append(s);
|
||||
if (add_space_after)
|
||||
|
|
@ -579,24 +573,16 @@ namespace CodeFormatters
|
|||
comm = "() ->";
|
||||
comm += " ";
|
||||
}
|
||||
else if (comm.EndsWith("procedure->("))
|
||||
{
|
||||
comm = comm.Replace("procedure->(", "procedure -> (");
|
||||
}
|
||||
else if (comm.EndsWith("procedure->"))
|
||||
{
|
||||
comm = comm.Replace("procedure->", "procedure -> ");
|
||||
}
|
||||
else if (comm.StartsWith(":") && comm.EndsWith(":") && comm.Replace(" ", "") == "::")
|
||||
comm = "::";
|
||||
else if (comm.StartsWith("[") && comm.EndsWith(":"))
|
||||
comm = comm.Replace(" ", "");
|
||||
else if (comm.StartsWith("( ") && comm.TrimEnd().EndsWith("var"))
|
||||
comm = comm.Replace(" ", "") + " ";
|
||||
comm = comm.Replace(" ", "")+" ";
|
||||
else if (trimed_comm.StartsWith(", ") && comm.TrimEnd().EndsWith("var"))
|
||||
comm = RemoveOverSpaces(comm);
|
||||
else if (trimed_comm.StartsWith(",var"))
|
||||
comm = ", var" + trimed_comm.Replace(",var", "");
|
||||
comm = ", var"+ trimed_comm.Replace(",var", "");
|
||||
else if (comm.StartsWith("array") || comm.StartsWith("set") || comm.StartsWith("sequence"))
|
||||
comm = RemoveOverSpaces(comm);
|
||||
else if ((comm.StartsWith("class") || comm.StartsWith("interface")) && comm.EndsWith("("))
|
||||
|
|
@ -692,11 +678,6 @@ namespace CodeFormatters
|
|||
sb.Append("()");
|
||||
cur_src_off = pos;
|
||||
}
|
||||
else if (sn is program_module && (sn as program_module).program_block.program_code.right_logical_bracket.source_context == null)
|
||||
{
|
||||
string comm = Text.Substring(prev_pos).Trim();
|
||||
sb.Append(comm);
|
||||
}
|
||||
}
|
||||
|
||||
private void IncOffset()
|
||||
|
|
@ -894,7 +875,6 @@ namespace CodeFormatters
|
|||
WritePossibleCommentAfter(sn);
|
||||
if (sn.source_context != null /*&& !(sn is exception_handler)*/)
|
||||
prev_sn = sn;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -922,14 +902,9 @@ namespace CodeFormatters
|
|||
add_newline_before = true;
|
||||
}*/
|
||||
visit_node(_statement_list.left_logical_bracket);
|
||||
//add_space_before = true;
|
||||
}
|
||||
|
||||
if (!in_one_row(_statement_list) && _statement_list.left_logical_bracket != null && _statement_list.subnodes.Count > 0
|
||||
&& _statement_list.subnodes[0].source_context != null
|
||||
&& _statement_list.left_logical_bracket.source_context != null
|
||||
&& _statement_list.left_logical_bracket.source_context.end_position.line_num == _statement_list.subnodes[0].source_context.begin_position.line_num
|
||||
&& !_statement_list.left_logical_bracket.text.StartsWith("##"))
|
||||
if (!in_one_row(_statement_list) && _statement_list.left_logical_bracket != null && _statement_list.subnodes.Count > 0 && _statement_list.subnodes[0].source_context != null && _statement_list.left_logical_bracket.source_context.end_position.line_num == _statement_list.subnodes[0].source_context.begin_position.line_num)
|
||||
add_newline_after = true;
|
||||
else
|
||||
add_space_after = true;
|
||||
|
|
@ -1135,18 +1110,9 @@ namespace CodeFormatters
|
|||
int pos = GetPosition(_string_const.source_context.begin_position.line_num, _string_const.source_context.begin_position.column_num);
|
||||
if (Text[pos] == '$')
|
||||
sb.Append('$');
|
||||
if (_string_const.IsMultiline)
|
||||
{
|
||||
//sb.Append("'''");
|
||||
sb.Append(_string_const.Value);
|
||||
//sb.Append("'''");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append("'");
|
||||
sb.Append(_string_const.Value.Replace("'", "''"));
|
||||
sb.Append("'");
|
||||
}
|
||||
sb.Append("'");
|
||||
sb.Append(_string_const.Value.Replace("'","''"));
|
||||
sb.Append("'");
|
||||
}
|
||||
|
||||
public override void visit(expression_list _expression_list)
|
||||
|
|
@ -1665,8 +1631,7 @@ namespace CodeFormatters
|
|||
{
|
||||
if (i > 0)
|
||||
add_space_after = true;
|
||||
if (_uses_list.units[i].source_context != null)
|
||||
visit_node(_uses_list.units[i]);
|
||||
visit_node(_uses_list.units[i]);
|
||||
}
|
||||
insert_newline_after_prev = true;
|
||||
DecOffset(tab);
|
||||
|
|
@ -1706,19 +1671,10 @@ namespace CodeFormatters
|
|||
|
||||
public override void visit(program_module _program_module)
|
||||
{
|
||||
// Хак
|
||||
var s = sb.ToString();
|
||||
if (s.Equals("###") || s.Equals("##"))
|
||||
sb.Append(" ");
|
||||
|
||||
if (_program_module.program_name != null)
|
||||
visit_node(_program_module.program_name);
|
||||
if (_program_module.used_units != null && _program_module.used_units.source_context != null)
|
||||
{
|
||||
/*if (_program_module.program_block != null && _program_module.program_block.program_code.left_logical_bracket.text.StartsWith("##"))
|
||||
;
|
||||
else*/ visit_node(_program_module.used_units);
|
||||
}
|
||||
if (_program_module.used_units != null)
|
||||
visit_node(_program_module.used_units);
|
||||
if (_program_module.program_block != null)
|
||||
visit_node(_program_module.program_block);
|
||||
//sb.Append(".");
|
||||
|
|
@ -2429,14 +2385,6 @@ namespace CodeFormatters
|
|||
WriteKeyword("begin");
|
||||
IncOffset();
|
||||
}
|
||||
else if (string.Compare(_token_info.text, "##", true) == 0)
|
||||
{
|
||||
WriteKeyword("##\n");
|
||||
}
|
||||
else if (string.Compare(_token_info.text, "###", true) == 0)
|
||||
{
|
||||
WriteKeyword("###\n");
|
||||
}
|
||||
else if (string.Compare(_token_info.text, "initialization", true) == 0)
|
||||
{
|
||||
WriteKeyword("initialization");
|
||||
|
|
@ -3106,8 +3054,8 @@ namespace CodeFormatters
|
|||
add_space_after = true;
|
||||
|
||||
visit_node(_short_func_definition.procdef.proc_body);
|
||||
//if (!(_short_func_definition.procdef.proc_header is constructor))
|
||||
IncOffset();
|
||||
if (!(_short_func_definition.procdef.proc_header is constructor))
|
||||
IncOffset();
|
||||
in_procedure = tmp_in_procedure;
|
||||
multiline_stack_pop(_short_func_definition);
|
||||
}
|
||||
|
|
@ -3463,73 +3411,6 @@ namespace CodeFormatters
|
|||
visit_node(_if_expr_new.if_false);
|
||||
}
|
||||
}
|
||||
|
||||
public override void visit(array_const_new acn)
|
||||
{
|
||||
sb.Append(acn.braces_type);
|
||||
visit_node(acn.elements);
|
||||
//sb.Append("|");
|
||||
}
|
||||
|
||||
public override void visit(double_question_node dn)
|
||||
{
|
||||
visit_node(dn.left);
|
||||
visit_node(dn.right);
|
||||
}
|
||||
public override void visit(bigint_const bi)
|
||||
{
|
||||
visit(new uint64_const(bi.val, bi.source_context));
|
||||
//sb.Append("bi");
|
||||
}
|
||||
|
||||
public override void visit(property_ident _property_ident)
|
||||
{
|
||||
if (_property_ident.ln != null)
|
||||
{
|
||||
foreach (ident id in _property_ident.ln)
|
||||
visit_node(id);
|
||||
return;
|
||||
}
|
||||
WriteAmpersandIfNeed(_property_ident);
|
||||
sb.Append(prepare_ident(_property_ident.name));
|
||||
}
|
||||
|
||||
public override void visit(foreach_stmt_formatting fe)
|
||||
{
|
||||
WriteKeyword("foreach");
|
||||
SetKeywordOffset("foreach");
|
||||
sb.Append(" var (");
|
||||
visit_node(fe.il);
|
||||
add_space_after = true;
|
||||
add_space_before = true;
|
||||
visit_node(fe.in_what);
|
||||
if (!in_one_row(fe.stmt))
|
||||
add_newline_after = true;
|
||||
add_space_before = true;
|
||||
bool need_off = !(fe.stmt is statement_list);
|
||||
if (need_off)
|
||||
IncOffset();
|
||||
visit_node(fe.stmt);
|
||||
if (need_off)
|
||||
DecOffset();
|
||||
}
|
||||
public override void visit(let_var_expr lvex)
|
||||
{
|
||||
sb.Append("(var ");
|
||||
|
||||
visit_node(lvex.id);
|
||||
add_space_after = true;
|
||||
add_space_before = true;
|
||||
visit_node(lvex.ex);
|
||||
}
|
||||
public override void visit(to_expr to_ex)
|
||||
{
|
||||
visit_node(to_ex.key);
|
||||
sb.Append(" ");
|
||||
visit_node(to_ex.value);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,7 +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 System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
|
@ -30,7 +29,6 @@ namespace CodeCompletion
|
|||
internal bool mouse_hover = false;
|
||||
private DomSyntaxTreeVisitor stv = null;
|
||||
private SymScope[] selected_methods = null;
|
||||
private Dictionary<method_call, SymScope> method_call_cache = new Dictionary<method_call, SymScope>();
|
||||
|
||||
public ExpressionVisitor(SymScope entry_scope, DomSyntaxTreeVisitor stv)
|
||||
{
|
||||
|
|
@ -182,7 +180,7 @@ namespace CodeCompletion
|
|||
{
|
||||
TypeSynonim ts = (returned_scopes[i] as ElementScope).sc as TypeSynonim;
|
||||
TypeScope act_ts = ts.GetLeafActType();
|
||||
ProcType procType = act_ts as ProcType;
|
||||
ProcType procType =act_ts as ProcType;
|
||||
if (procType != null)
|
||||
{
|
||||
ProcScope tmp = procType.target;
|
||||
|
|
@ -200,11 +198,6 @@ namespace CodeCompletion
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (returned_scopes[i] is TypeScope)
|
||||
{
|
||||
// операция преобразования типа не поддерживается здесь EVA
|
||||
continue;
|
||||
}
|
||||
else if (i == 0)
|
||||
return proces;
|
||||
}
|
||||
|
|
@ -353,7 +346,7 @@ namespace CodeCompletion
|
|||
{
|
||||
returned_scope = entry_scope;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (returned_scope is ProcScope && (returned_scope as ProcScope).parameters.Count != 0)
|
||||
{
|
||||
returned_scopes = entry_scope.FindOverloadNames(_ident.name);
|
||||
|
|
@ -476,7 +469,7 @@ namespace CodeCompletion
|
|||
|
||||
public override void visit(string_const _string_const)
|
||||
{
|
||||
returned_scope = new ElementScope(entry_scope.FindName(StringConstants.string_type_name));
|
||||
returned_scope = new ElementScope(entry_scope.FindName(PascalABCCompiler.TreeConverter.compiler_string_consts.string_type_name));
|
||||
}
|
||||
|
||||
public override void visit(expression_list _expression_list)
|
||||
|
|
@ -580,8 +573,7 @@ namespace CodeCompletion
|
|||
|
||||
public override void visit(if_node _if_node)
|
||||
{
|
||||
_if_node.then_body.visit(this);
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void visit(ref_type _ref_type)
|
||||
|
|
@ -799,13 +791,6 @@ namespace CodeCompletion
|
|||
return null;
|
||||
}
|
||||
|
||||
public SymScope CheckForAccess(ElementScope ss, ProcScope es)
|
||||
{
|
||||
if (es.acc_mod == access_modifer.protected_modifer)
|
||||
if (es.topScope is TypeScope && CheckForBaseAccess(entry_scope, es.topScope)) return es;
|
||||
return null;
|
||||
}
|
||||
|
||||
public SymScope CheckForAccess(TypeScope ss, ElementScope es)
|
||||
{
|
||||
if (es.acc_mod == access_modifer.none || es.acc_mod == access_modifer.public_modifer || es.acc_mod == access_modifer.published_modifer || es.acc_mod == access_modifer.internal_modifer)
|
||||
|
|
@ -842,7 +827,7 @@ namespace CodeCompletion
|
|||
_dot_node.left.visit(this);
|
||||
search_all = tmp2;
|
||||
by_dot = tmp;
|
||||
|
||||
|
||||
if (returned_scope != null && returned_scope is ElementScope && (returned_scope as ElementScope).sc is ProcScope)
|
||||
{
|
||||
if (((returned_scope as ElementScope).sc as ProcScope).return_type != null)
|
||||
|
|
@ -852,7 +837,7 @@ namespace CodeCompletion
|
|||
}
|
||||
else if (returned_scope != null && returned_scope is ProcScope)
|
||||
{
|
||||
|
||||
|
||||
ProcScope ps = returned_scope as ProcScope;
|
||||
if (ps.return_type == null)
|
||||
{
|
||||
|
|
@ -869,7 +854,7 @@ namespace CodeCompletion
|
|||
TypeScope ts = ((returned_scope as ElementScope).sc as ProcType).target.return_type;
|
||||
if (ts != null)
|
||||
returned_scope = new ElementScope(ts);
|
||||
|
||||
|
||||
}
|
||||
else if ((returned_scope != null && returned_scope is ElementScope && (returned_scope as ElementScope).sc is CompiledScope && ((returned_scope as ElementScope).sc as CompiledScope).IsDelegate) && _dot_node.left is method_call)
|
||||
{
|
||||
|
|
@ -917,12 +902,6 @@ namespace CodeCompletion
|
|||
return;
|
||||
}
|
||||
}
|
||||
else if (ps != null)
|
||||
{
|
||||
method_call mc = new method_call(_dot_node, new expression_list());
|
||||
mc.visit(this);
|
||||
return;
|
||||
}
|
||||
if (tmp_tn is ElementScope && stv != null)
|
||||
{
|
||||
List<ProcScope> procs = stv.entry_scope.GetExtensionMethods((_dot_node.right as ident).name, (tmp_tn as ElementScope).sc as TypeScope);
|
||||
|
|
@ -956,17 +935,11 @@ namespace CodeCompletion
|
|||
//if (ret_names[i] != null)
|
||||
//ret_names[i] = ((ret_names[i] as ElementScope).sc as ProcType).target;
|
||||
}
|
||||
else if (returned_scopes[i] is ProcScope && (returned_scopes[i] as ProcScope).acc_mod == access_modifer.protected_modifer)
|
||||
{
|
||||
returned_scopes[i] = CheckForAccess(left_scope as ElementScope, returned_scopes[i] as ProcScope);
|
||||
//if (ret_names[i] != null)
|
||||
//ret_names[i] = ((ret_names[i] as ElementScope).sc as ProcType).target;
|
||||
}
|
||||
else if (left_scope is ElementScope && returned_scopes[i] is ProcScope && (returned_scopes[i] as ProcScope).IsStatic)
|
||||
{
|
||||
returned_scopes[i] = null;
|
||||
}
|
||||
else if (left_scope is TypeScope && returned_scopes[i] is ProcScope && !(returned_scopes[i] as ProcScope).IsStatic && !(returned_scopes[i] as ProcScope).IsConstructor() && !(returned_scope is TypeScope && (returned_scopes[i] as ProcScope).is_extension))
|
||||
else if (left_scope is TypeScope && returned_scopes[i] is ProcScope && !(returned_scopes[i] as ProcScope).IsStatic && !(returned_scopes[i] as ProcScope).IsConstructor())
|
||||
{
|
||||
returned_scopes[i] = null;
|
||||
}
|
||||
|
|
@ -1045,13 +1018,13 @@ namespace CodeCompletion
|
|||
if (meths[i] is ProcScope)
|
||||
{
|
||||
if (DomSyntaxTreeVisitor.is_good_overload(meths[i] as ProcScope, arg_types))
|
||||
if (!meths[i].si.not_include || by_dot || mouse_hover && meths[i].loc == null)
|
||||
if (!meths[i].si.not_include || by_dot)
|
||||
good_procs.Add(meths[i] as ProcScope);
|
||||
}
|
||||
else if (meths[i] is ProcType)
|
||||
{
|
||||
if (DomSyntaxTreeVisitor.is_good_overload((meths[i] as ProcType).target, arg_types))
|
||||
if (!meths[i].si.not_include || by_dot || mouse_hover && meths[i].loc == null)
|
||||
if (!meths[i].si.not_include || by_dot)
|
||||
good_procs.Add((meths[i] as ProcType).target);
|
||||
}
|
||||
}
|
||||
|
|
@ -1151,35 +1124,18 @@ namespace CodeCompletion
|
|||
public override void visit(method_call _method_call)
|
||||
{
|
||||
returned_scopes.Clear();
|
||||
if (method_call_cache.ContainsKey(_method_call))
|
||||
{
|
||||
returned_scope = method_call_cache[_method_call];
|
||||
return;
|
||||
}
|
||||
search_all = true;
|
||||
_method_call.dereferencing_value.visit(this);
|
||||
search_all = false;
|
||||
SymScope[] names = returned_scopes.ToArray();
|
||||
|
||||
// Не нашли кандидатов - возврат
|
||||
if (names.Length == 0)
|
||||
{
|
||||
returned_scope = null;
|
||||
method_call_cache[_method_call] = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (names[0] is ElementScope && (names[0] as ElementScope).sc is TypeScope && ((names[0] as ElementScope).sc as TypeScope).IsDelegate)
|
||||
if (names.Length > 0 && names[0] is ElementScope && (names[0] as ElementScope).sc is TypeScope && ((names[0] as ElementScope).sc as TypeScope).IsDelegate)
|
||||
{
|
||||
returned_scope = names[0];
|
||||
method_call_cache[_method_call] = returned_scope;
|
||||
return;
|
||||
}
|
||||
// Срабатывает на операции преобразования типа
|
||||
if (names.All(name => name is TypeScope))
|
||||
if (names.Length > 0 && names[0] is TypeScope)
|
||||
{
|
||||
returned_scope = new ElementScope(names[0]);
|
||||
method_call_cache[_method_call] = returned_scope;
|
||||
return;
|
||||
}
|
||||
TypeScope obj = null;
|
||||
|
|
@ -1220,41 +1176,20 @@ namespace CodeCompletion
|
|||
}
|
||||
ProcScope ps = select_method(names, null, null, obj, _method_call.parameters != null ? _method_call.parameters.expressions.ToArray() : null);
|
||||
returned_scope = ps;
|
||||
if (ps == null)
|
||||
if (ps == null && names.Length > 0)
|
||||
{
|
||||
returned_scope = null;
|
||||
|
||||
// Если есть ProcScope, то приоритет отдаем ему.
|
||||
// Неверно в случае, когда есть подходящая операция преобразования типа у TypeScope,
|
||||
// но операция преобразования типа по хорошему должна обрабатываться в select_method EVA
|
||||
if (names[0] is TypeScope && names.Length > 1)
|
||||
{
|
||||
var p = names.FirstOrDefault(s => s is ProcScope);
|
||||
|
||||
if (p != null)
|
||||
returned_scope = p;
|
||||
else
|
||||
foreach (SymScope ss in names)
|
||||
if (ss is ProcScope)
|
||||
{
|
||||
returned_scope = new ElementScope(names[0]);
|
||||
returned_scope = ss;
|
||||
break;
|
||||
}
|
||||
else if (ss is TypeScope)
|
||||
{
|
||||
returned_scope = new ElementScope(ss);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (SymScope ss in names)
|
||||
{
|
||||
if (ss is ProcScope)
|
||||
{
|
||||
returned_scope = ss;
|
||||
break;
|
||||
}
|
||||
else if (ss is TypeScope)
|
||||
{
|
||||
returned_scope = new ElementScope(ss);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (returned_scope != null)
|
||||
{
|
||||
|
|
@ -1273,8 +1208,7 @@ namespace CodeCompletion
|
|||
else
|
||||
returned_scope = new ElementScope(ps);
|
||||
}
|
||||
// ниже мертый код, поскольку эти типы наследники ProcScope EVA
|
||||
/*else if (returned_scope is ProcRealization)
|
||||
else if (returned_scope is ProcRealization)
|
||||
{
|
||||
if ((returned_scope as ProcRealization).def_proc != null && (returned_scope as ProcRealization).def_proc.return_type != null)
|
||||
returned_scope = new ElementScope((returned_scope as ProcRealization).def_proc.return_type);
|
||||
|
|
@ -1285,7 +1219,7 @@ namespace CodeCompletion
|
|||
if ((returned_scope as CompiledMethodScope).return_type != null)
|
||||
returned_scope = new ElementScope((returned_scope as CompiledMethodScope).return_type);
|
||||
else returned_scope = null;
|
||||
}*/
|
||||
}
|
||||
/*else if (ret_tn is ElementScope && (ret_tn as ElementScope).sc is ProcScope)
|
||||
{
|
||||
ret_tn = new ElementScope(((ret_tn as ElementScope).sc as ProcScope).return_type);
|
||||
|
|
@ -1298,21 +1232,12 @@ namespace CodeCompletion
|
|||
}
|
||||
else ret_tn = null;*/
|
||||
}
|
||||
method_call_cache[_method_call] = returned_scope;
|
||||
}
|
||||
|
||||
public override void visit(pascal_set_constant psc)
|
||||
public override void visit(pascal_set_constant _pascal_set_constant)
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
// returned_scope = null;
|
||||
|
||||
var dn = new dot_node(new ident(StringConstants.pascalSystemUnitName), new ident("Arr"), psc.source_context);
|
||||
var el = new expression_list(psc.values.expressions[0], psc.source_context);
|
||||
var nn = new method_call(dn, el, psc.source_context);
|
||||
var dn1 = new dot_node(new ident(StringConstants.pascalSystemUnitName), new ident("__NewSetCreatorInternal"), psc.source_context);
|
||||
var el1 = new expression_list(nn, psc.source_context);
|
||||
var nn1 = new method_call(dn1, el1, psc.source_context);
|
||||
visit(nn1);
|
||||
returned_scope = null;
|
||||
}
|
||||
|
||||
public override void visit(array_const _array_const)
|
||||
|
|
@ -1495,7 +1420,7 @@ namespace CodeCompletion
|
|||
if (returned_scope != null) returned_scope = new ElementScope(returned_scope);
|
||||
}
|
||||
else if (_typecast_node.cast_op == op_typecast.is_op)
|
||||
returned_scope = new ElementScope(entry_scope.FindName(StringConstants.bool_type_name));
|
||||
returned_scope = new ElementScope(entry_scope.FindName(PascalABCCompiler.TreeConverter.compiler_string_consts.bool_type_name));
|
||||
}
|
||||
|
||||
public override void visit(interface_node _interface_node)
|
||||
|
|
@ -1591,7 +1516,7 @@ namespace CodeCompletion
|
|||
|
||||
public override void visit(format_expr _format_expr)
|
||||
{
|
||||
returned_scope = entry_scope.FindName(StringConstants.string_type_name);
|
||||
returned_scope = entry_scope.FindName(PascalABCCompiler.TreeConverter.compiler_string_consts.string_type_name);
|
||||
}
|
||||
|
||||
public override void visit(initfinal_part _initfinal_part)
|
||||
|
|
@ -1734,14 +1659,14 @@ namespace CodeCompletion
|
|||
returned_scope = returned_scope.FindNameOnlyInType(_template_type_reference.name.names[i].name + suffix);
|
||||
if (returned_scope == null)
|
||||
returned_scope = entry_scope.FindNameOnlyInType(_template_type_reference.name.names[i].name + suffix);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
returned_scope = returned_scope.FindName(_template_type_reference.name.names[i].name + suffix);
|
||||
if (returned_scope == null)
|
||||
returned_scope = entry_scope.FindName(_template_type_reference.name.names[i].name);
|
||||
}
|
||||
|
||||
|
||||
if (returned_scope == null)
|
||||
return;
|
||||
}
|
||||
|
|
@ -1821,7 +1746,7 @@ namespace CodeCompletion
|
|||
|
||||
public override void visit(sizeof_operator _sizeof_operator)
|
||||
{
|
||||
returned_scope = new ElementScope(entry_scope.FindName(StringConstants.integer_type_name));
|
||||
returned_scope = new ElementScope(entry_scope.FindName(PascalABCCompiler.TreeConverter.compiler_string_consts.integer_type_name));
|
||||
}
|
||||
|
||||
public override void visit(typeof_operator _typeof_operator)
|
||||
|
|
@ -1841,7 +1766,7 @@ namespace CodeCompletion
|
|||
|
||||
public override void visit(var_statement _var_statement)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override void visit(question_colon_expression _question_colon_expression)
|
||||
|
|
@ -2027,7 +1952,7 @@ namespace CodeCompletion
|
|||
_function_lambda_definition.proc_body.visit(this);
|
||||
if (returned_scope is ElementScope)
|
||||
returned_scope = (returned_scope as ElementScope).sc;
|
||||
ps.return_type = new UnknownScope(new SymInfo("", SymbolKind.Class, ""));// returned_scope as TypeScope;
|
||||
ps.return_type = new UnknownScope(new SymInfo("",SymbolKind.Class,""));// returned_scope as TypeScope;
|
||||
returned_scope = new ProcType(ps);
|
||||
}
|
||||
public override void visit(function_lambda_call _function_lambda_call)
|
||||
|
|
@ -2055,11 +1980,11 @@ namespace CodeCompletion
|
|||
public override void visit(semantic_type_node stn) // SSM
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public override void visit(slice_expr _slice_expr)
|
||||
{
|
||||
_slice_expr.v.visit(this);
|
||||
}
|
||||
{
|
||||
_slice_expr.v.visit(this);
|
||||
}
|
||||
|
||||
public override void visit(slice_expr_question _slice_expr_question)
|
||||
{
|
||||
|
|
@ -2069,7 +1994,7 @@ namespace CodeCompletion
|
|||
{
|
||||
method_call mc = new method_call();
|
||||
mc.parameters = _tuple_node.el;
|
||||
mc.dereferencing_value = new dot_node(new ident("Tuple"), new ident(StringConstants.default_constructor_name));
|
||||
mc.dereferencing_value = new dot_node(new ident("Tuple"), new ident("Create"));
|
||||
mc.visit(this);
|
||||
}
|
||||
|
||||
|
|
@ -2085,21 +2010,9 @@ namespace CodeCompletion
|
|||
returned_scope = new ElementScope(ts);*/
|
||||
|
||||
method_call mc = new method_call();
|
||||
mc.parameters = new expression_list(new List<expression> { _diapason_expr_new.left, _diapason_expr_new.right });
|
||||
mc.dereferencing_value = new dot_node(new ident(StringConstants.pascalSystemUnitName), new ident("InternalRange"));
|
||||
mc.parameters = new expression_list(new List<expression> { _diapason_expr_new.left, _diapason_expr_new.right});
|
||||
mc.dereferencing_value = new dot_node(new ident("PABCSystem"), new ident("InternalRange"));
|
||||
mc.visit(this);
|
||||
}
|
||||
|
||||
public override void visit(array_const_new acn)
|
||||
{
|
||||
acn.elements.expressions[0].visit(this);
|
||||
//var rr = this.returned_scope;
|
||||
//var nn = new new_expr((syntax_type, plist, true, new SyntaxTree.array_const(acn.elements, acn.elements.source_context), acn.source_context);
|
||||
//var nn = new new_expr($2, el, true, $6 as array_const, @$);
|
||||
var dn = new dot_node(new ident(StringConstants.pascalSystemUnitName), new ident("Arr"), acn.source_context);
|
||||
var el = new expression_list(acn.elements.expressions[0], acn.source_context);
|
||||
var nn = new method_call(dn, el, acn.source_context);
|
||||
visit(nn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ namespace CodeCompletion
|
|||
ret_tn = ret_tn.FindNameOnlyInType(_named_type_reference.names[i].name);
|
||||
else ret_tn = ret_tn.FindNameInAnyOrder(_named_type_reference.names[i].name);
|
||||
if (ret_tn == null) break;
|
||||
else if (founded_scope.IsEqual(ret_tn) && founded_scope is TypeScope)
|
||||
else if (founded_scope.IsEqual(ret_tn))
|
||||
pos_list.Add(get_position(_named_type_reference.names[i]));
|
||||
}
|
||||
}
|
||||
|
|
@ -244,19 +244,6 @@ namespace CodeCompletion
|
|||
_var_def_statement.inital_value.visit(this);
|
||||
}
|
||||
|
||||
public override void visit(let_var_expr _let_var_expr)
|
||||
{
|
||||
if (for_refactoring)
|
||||
{
|
||||
IBaseScope ss = entry_scope.FindScopeByLocation(_let_var_expr.id.source_context.begin_position.line_num, _let_var_expr.id.source_context.begin_position.column_num);
|
||||
if (ss != null && ss.IsEqual(founded_scope))
|
||||
pos_list.Add(get_position(_let_var_expr.id));
|
||||
}
|
||||
|
||||
if (_let_var_expr.ex != null)
|
||||
_let_var_expr.ex.visit(this);
|
||||
}
|
||||
|
||||
public override void visit(declaration _declaration)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
|
@ -328,10 +315,6 @@ namespace CodeCompletion
|
|||
|
||||
public override void visit(for_node _for_node)
|
||||
{
|
||||
IBaseScope tmp = cur_scope;
|
||||
cur_scope = entry_scope.FindScopeByLocation(_for_node.source_context.begin_position.line_num, _for_node.source_context.begin_position.column_num);
|
||||
if (cur_scope == null)
|
||||
cur_scope = tmp;
|
||||
if (_for_node.loop_variable != null)
|
||||
{
|
||||
ret_tn = cur_scope.FindNameInAnyOrder(_for_node.loop_variable.name);
|
||||
|
|
@ -347,10 +330,7 @@ namespace CodeCompletion
|
|||
if (_for_node.increment_value != null)
|
||||
_for_node.increment_value.visit(this);
|
||||
if (_for_node.statements != null)
|
||||
{
|
||||
_for_node.statements.visit(this);
|
||||
}
|
||||
cur_scope = tmp;
|
||||
}
|
||||
|
||||
public override void visit(repeat_node _repeat_node)
|
||||
|
|
@ -539,15 +519,6 @@ namespace CodeCompletion
|
|||
{
|
||||
//SymScope ss = entry_scope.FindScopeByLocation(_type_declaration.source_context.begin_position.line_num,_type_declaration.source_context.begin_position.column_num);
|
||||
IBaseScope ss = entry_scope.FindNameInAnyOrder(_type_declaration.type_name.name);
|
||||
if (for_refactoring && _type_declaration.type_name is template_type_name)
|
||||
{
|
||||
foreach (ident id in (_type_declaration.type_name as template_type_name).template_args.list)
|
||||
{
|
||||
var targ_ss = entry_scope.FindScopeByLocation(id.source_context.begin_position.line_num, id.source_context.begin_position.column_num);
|
||||
if (targ_ss != null && targ_ss.IsEqual(founded_scope))
|
||||
pos_list.Add(get_position(id));
|
||||
}
|
||||
}
|
||||
if (ss == null && entry_scope is IInterfaceUnitScope && (entry_scope as IInterfaceUnitScope).ImplementationUnitScope != null)
|
||||
ss = (entry_scope as IInterfaceUnitScope).ImplementationUnitScope.FindNameInAnyOrder(_type_declaration.type_name.name);
|
||||
if (for_refactoring && ss != null && ss.IsEqual(founded_scope) && string.Compare(ss.SymbolInfo.name, _type_declaration.type_name.name, true) == 0 && !(ss is ITypeSynonimScope && !(founded_scope is ITypeSynonimScope)))
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ using System.Runtime.InteropServices;
|
|||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("CodeCompletion")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2005-2026 by Ivan Bondarev, Stanislav Mikhalkovich")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2005-2020 by Ivan Bondarev, Stanislav Mikhalkovich")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,10 +0,0 @@
|
|||
from GraphWPF import *
|
||||
|
||||
color = RandomColor()
|
||||
|
||||
def MouseMove(x: float, y: float, mb: int):
|
||||
if mb == 1:
|
||||
FillCircle(x, y, 10, color)
|
||||
|
||||
|
||||
OnMouseMove = MouseMove
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
# индекс минимального элемента
|
||||
def argmin(arr: list[int]) -> int:
|
||||
if len(arr) == 0:
|
||||
return -1
|
||||
res = 0
|
||||
for i in range(1, len(arr)):
|
||||
if arr[i] < arr[res]:
|
||||
res = i
|
||||
return res
|
||||
|
||||
|
||||
|
||||
|
||||
print(argmin([1, 2, 3]))
|
||||
print(argmin([3, 2, 1]))
|
||||
# a = [4,9,16,8,2,15,13,13,15,2,8,16,9,4]
|
||||
a = [i ** 2 % 17 for i in range(2, 16)]
|
||||
print(argmin([i ** 2 % 17 for i in range(2, 16)]))
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
N = 7
|
||||
|
||||
# Выводит первые N чисел,
|
||||
# которые можно тремя различными
|
||||
# способами представить как
|
||||
# сумму двух квадратов целых чисел
|
||||
def print_sequence(N: int):
|
||||
a = 0
|
||||
while True:
|
||||
a += 1
|
||||
for b in range(1, a):
|
||||
for c in range(1, b):
|
||||
for d in range(1, c + 1):
|
||||
for e in range(1, d):
|
||||
for f in range(1, e):
|
||||
if a ** 2 + f ** 2 == b ** 2 + e ** 2 == c ** 2 + d ** 2:
|
||||
print(a ** 2 + f ** 2, '\t= ',
|
||||
a, '^2 + ', f, '^2 \t= ',
|
||||
b, '^2 + ', e, '^2 \t= ',
|
||||
c, '^2 + ', d, '^2', sep='')
|
||||
|
||||
N -= 1
|
||||
if N == 0:
|
||||
return
|
||||
|
||||
|
||||
print_sequence(N)
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
from WPFObjects import RectangleWPF, ObjectUnderPoint
|
||||
from WPFObjects import Colors, Window, OnMouseDown
|
||||
from PABCSystem import Random, Inc, Milliseconds
|
||||
|
||||
CountSquares = 10
|
||||
StatusRect: RectangleWPF
|
||||
CurrentDigit = 1
|
||||
Mistakes = 0
|
||||
|
||||
def DrawStatusText():
|
||||
if CurrentDigit <= CountSquares:
|
||||
StatusRect.Text = ('Удалено квадратов: ' + str(CurrentDigit-1)
|
||||
+ '\tОшибок: ' + str(Mistakes))
|
||||
else:
|
||||
StatusRect.Text = ('Игра окончена. Время: ' + str(Milliseconds() // 1000)
|
||||
+ ' с.\tОшибок: ' + str(Mistakes))
|
||||
|
||||
|
||||
def MyMouseDown(x: float, y: float, mb: int):
|
||||
ob = ObjectUnderPoint(x, y)
|
||||
if ob is RectangleWPF and ob != StatusRect:
|
||||
if ob.Number == CurrentDigit:
|
||||
ob.Destroy()
|
||||
Inc(CurrentDigit)
|
||||
DrawStatusText()
|
||||
else:
|
||||
ob.Color = Colors.Red
|
||||
Inc(Mistakes)
|
||||
DrawStatusText()
|
||||
|
||||
|
||||
Window.Title = 'Игра: удали все квадраты по порядку'
|
||||
for i in range(1, CountSquares + 1):
|
||||
x = Random(Window.Width - 50)
|
||||
y = Random(Window.Height - 100)
|
||||
ob = new RectangleWPF(x, y, 50, 50, Colors.LightGreen, 1)
|
||||
ob.FontSize = 25
|
||||
ob.Number = i
|
||||
StatusRect = new RectangleWPF(0, Window.Height - 40,
|
||||
Window.Width, 40, Colors.LightBlue)
|
||||
DrawStatusText()
|
||||
OnMouseDown = MyMouseDown
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
import random as rnd
|
||||
|
||||
hidden_number = rnd.randint(1, 100)
|
||||
print('Угадай число от 1 до 100')
|
||||
attempts = 0
|
||||
left_border = 1
|
||||
right_border = 100
|
||||
while True:
|
||||
attempts += 1
|
||||
guess = int(input('Попытка ' + str(attempts) + ':'))
|
||||
if guess < left_border or right_border < guess:
|
||||
print('Число', guess, 'не из диапазона',
|
||||
'[' + str(left_border) + ',', str(right_border) + ']')
|
||||
continue
|
||||
if guess < hidden_number:
|
||||
left_border = guess + 1
|
||||
print('Загаданное число больше', guess);
|
||||
elif guess > hidden_number:
|
||||
right_border = guess - 1
|
||||
print('Загаданное число меньше', guess);
|
||||
else:
|
||||
print('Победа!!!')
|
||||
break
|
||||
print('Попробуй число от', left_border,
|
||||
'до', right_border)
|
||||
print('Тебе понадобилось', attempts, 'попыток')
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
a = int(input('Введите первое число:'))
|
||||
b = int(input('Введите второе число:'))
|
||||
|
||||
def print_expressions(a: int, b: int):
|
||||
print(a, ' +', b, '=', a + b, end = '\n')
|
||||
print(a, ' -', b, '=', a - b, end = '\n')
|
||||
print(a, ' *', b, '=', a * b, end = '\n')
|
||||
print(a, ' %', b, '=', a % b, end = '\n')
|
||||
print(a, ' /', b, '=', a / b, end = '\n')
|
||||
print(a, '//', b, '=', a // b, end = '\n')
|
||||
print(a, '**', b, '=', a ** b, end = '\n')
|
||||
|
||||
print_expressions(a, b)
|
||||
|
||||
|
||||
# Введите первое число: 10
|
||||
# Введите второе число: 6
|
||||
# 10 + 6 = 16
|
||||
# 10 - 6 = 4
|
||||
# 10 * 6 = 60
|
||||
# 10 % 6 = 4
|
||||
# 10 / 6 = 1.66666666666667
|
||||
# 10 // 6 = 1
|
||||
# 10 ** 6 = 1000000
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
def print_matr(matr: list[list[int]]):
|
||||
for row in matr:
|
||||
for elem in row:
|
||||
print(elem, '\t', end=' ')
|
||||
print()
|
||||
|
||||
|
||||
matrix_of_integers: list[list[int]]
|
||||
matrix_of_integers = [
|
||||
[j * i for j in range(1, 10)]
|
||||
for i in range(1, 10) if i % 2 == 0
|
||||
]
|
||||
print_matr(matrix_of_integers)
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
a = [1, 2, 3]
|
||||
a.append(4)
|
||||
a.insert(4, 2)
|
||||
b = a.copy()
|
||||
b.reverse()
|
||||
print(b)
|
||||
print(a)
|
||||
print(a.count(2))
|
||||
print(a.pop(1))
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
#unit random
|
||||
import PABCSystem
|
||||
|
||||
def random() -> float:
|
||||
return PABCSystem.Random()
|
||||
|
||||
def randint(a: int, b: int) -> int:
|
||||
return PABCSystem.Random(a, b)
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
from time import time
|
||||
|
||||
s: set[int] = set()
|
||||
t1 = time()
|
||||
|
||||
for i in range(1, 10000):
|
||||
s |= {i}
|
||||
|
||||
t2 = time()
|
||||
print(t2 - t1)
|
||||
print(len(s))
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
unit time1;
|
||||
|
||||
interface
|
||||
|
||||
function time(): real;
|
||||
|
||||
function forty_two(): real;
|
||||
|
||||
implementation
|
||||
|
||||
function time() : real := DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds;
|
||||
|
||||
function forty_two() : real := 42;
|
||||
|
||||
end.
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
begin
|
||||
var n := 60000;
|
||||
var t1 := Milliseconds;
|
||||
var sm := 0.0;
|
||||
var i := 1.0;
|
||||
while i < n do
|
||||
begin
|
||||
var j := 1.0;
|
||||
while j < n do
|
||||
begin
|
||||
sm += 1.0 / i / j;
|
||||
j += 1;
|
||||
end;
|
||||
i += 1;
|
||||
end;
|
||||
var t2 := Milliseconds;
|
||||
print(t2 - t1);
|
||||
end.
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
import time
|
||||
|
||||
n = 60000
|
||||
start = time.time()
|
||||
sm: float = 0
|
||||
|
||||
i = 1.0
|
||||
while i < n:
|
||||
j = 1.0
|
||||
while j < n:
|
||||
sm += 1.0 / i / j
|
||||
j += 1
|
||||
i += 1
|
||||
|
||||
end = time.time();
|
||||
print(end - start)
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
# Рекурсивная функция вычисления факториала
|
||||
def factorial(n: int)-> bigint:
|
||||
if n == 0:
|
||||
return 1
|
||||
return n * factorial(n - 1)
|
||||
|
||||
|
||||
# Не рекурсивная функция вычисления числа Фибоначчи
|
||||
def fibonacci(n: int)-> bigint:
|
||||
if n <= 1:
|
||||
return n
|
||||
f1: bigint = 0
|
||||
f2: bigint = 1
|
||||
for i in range(n - 1):
|
||||
t = f1 + f2
|
||||
f1 = f2
|
||||
f2 = t
|
||||
return f2
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
Uses unit_example;
|
||||
|
||||
const N: integer = 10;
|
||||
|
||||
begin
|
||||
println('Последовательность чисел Фибоначчи:');
|
||||
for var i := 1 to N do
|
||||
println('F(' + i + ')=', fibonacci(i));
|
||||
println();
|
||||
|
||||
println('Последовательность факториалов:');
|
||||
for var i := 1 to N do
|
||||
println(i + '!=', factorial(i));
|
||||
println();
|
||||
end.
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
from unit_example import fibonacci as F, factorial as fact
|
||||
|
||||
N = 10
|
||||
|
||||
fibs = [F(i) for i in range(1, N + 1)]
|
||||
print("Последовательность чисел Фибоначчи:")
|
||||
i = 0
|
||||
for fib_num in fibs:
|
||||
i += 1
|
||||
print('F(' + str(i) + ')\t=', fib_num)
|
||||
print()
|
||||
|
||||
facts = [fact(i) for i in range(1, N + 1)]
|
||||
print("Последовательность факториалов:")
|
||||
i = 0
|
||||
for fact_num in facts:
|
||||
i += 1
|
||||
print(str(i) + '!\t=', fact_num)
|
||||
print()
|
||||
5326
Compiler/Compiler.cs
5326
Compiler/Compiler.cs
File diff suppressed because it is too large
Load diff
|
|
@ -1,32 +1,206 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net40</TargetFramework>
|
||||
|
||||
<OutputPath>..\bin\</OutputPath>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<ProjectType>Local</ProjectType>
|
||||
<ProductVersion>8.0.50727</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{1E42361A-EDA3-4872-88AF-A3AAF600D36D}</ProjectGuid>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ApplicationIcon>
|
||||
</ApplicationIcon>
|
||||
<AssemblyKeyContainerName>
|
||||
</AssemblyKeyContainerName>
|
||||
<AssemblyName>Compiler</AssemblyName>
|
||||
<AssemblyOriginatorKeyFile>
|
||||
</AssemblyOriginatorKeyFile>
|
||||
<DefaultClientScript>JScript</DefaultClientScript>
|
||||
<DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
|
||||
<DefaultTargetSchema>IE50</DefaultTargetSchema>
|
||||
<DelaySign>false</DelaySign>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>Compiler</RootNamespace>
|
||||
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
|
||||
<StartupObject>
|
||||
</StartupObject>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
<OldToolsVersion>4.0</OldToolsVersion>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile />
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<OutputPath>..\bin\</OutputPath>
|
||||
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
|
||||
<BaseAddress>285212672</BaseAddress>
|
||||
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
|
||||
<ConfigurationOverrideFile>
|
||||
</ConfigurationOverrideFile>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DocumentationFile>
|
||||
</DocumentationFile>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<FileAlignment>4096</FileAlignment>
|
||||
<NoStdLib>false</NoStdLib>
|
||||
<NoWarn>
|
||||
</NoWarn>
|
||||
<Optimize>false</Optimize>
|
||||
<RegisterForComInterop>false</RegisterForComInterop>
|
||||
<RemoveIntegerChecks>false</RemoveIntegerChecks>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DebugType>full</DebugType>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<OutputPath>..\bin\</OutputPath>
|
||||
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
|
||||
<BaseAddress>285212672</BaseAddress>
|
||||
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
|
||||
<ConfigurationOverrideFile>
|
||||
</ConfigurationOverrideFile>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<DocumentationFile>
|
||||
</DocumentationFile>
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
<FileAlignment>4096</FileAlignment>
|
||||
<NoStdLib>false</NoStdLib>
|
||||
<NoWarn>
|
||||
</NoWarn>
|
||||
<Optimize>true</Optimize>
|
||||
<RegisterForComInterop>false</RegisterForComInterop>
|
||||
<RemoveIntegerChecks>false</RemoveIntegerChecks>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DebugType>none</DebugType>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="ICSharpCode.NRefactory">
|
||||
<HintPath>..\Libraries\ICSharpCode.NRefactory.dll</HintPath>
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Scripting, Version=1.1.0.20, Culture=neutral, PublicKeyToken=7f709c5b713576e1, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\Libraries\Microsoft.Scripting.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System">
|
||||
<Name>System</Name>
|
||||
</Reference>
|
||||
<Reference Include="System.Data">
|
||||
<Name>System.Data</Name>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml">
|
||||
<Name>System.XML</Name>
|
||||
</Reference>
|
||||
<ProjectReference Include="..\Errors\Errors.csproj">
|
||||
<Project>{44A01F9E-DCE7-470C-AAE5-C3DE0CCBEE3B}</Project>
|
||||
<Name>Errors</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Localization\Localization.csproj">
|
||||
<Project>{2DE2842F-0912-4251-BC0F-480854C44A13}</Project>
|
||||
<Name>Localization</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\NETGenerator\NETGenerator.csproj">
|
||||
<Name>NETGenerator</Name>
|
||||
<Project>{7FE7173B-22EB-46E5-897B-02F422662E51}</Project>
|
||||
<Package>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Package>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\CompilerTools\CompilerTools.csproj">
|
||||
<Project>{A25D26FB-3043-4BCF-833E-E3F4C3BE795E}</Project>
|
||||
<Name>CompilerTools</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\ParserTools\ParserTools.csproj">
|
||||
<Project>{AF2EFD7B-69DD-4B43-AF65-B59B29349C23}</Project>
|
||||
<Name>ParserTools</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SemanticTree\SemanticTree.csproj">
|
||||
<Name>SemanticTree</Name>
|
||||
<Project>{613E0DDA-AA8A-437C-AC45-507B47429FF9}</Project>
|
||||
<Package>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Package>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SyntaxTreeConverters\SyntaxTreeConverters.csproj">
|
||||
<Project>{f10a5330-dcf4-4533-877c-7b1b1be23884}</Project>
|
||||
<Name>SyntaxTreeConverters</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SyntaxTree\SyntaxTree.csproj">
|
||||
<Name>SyntaxTree</Name>
|
||||
<Project>{C2CAC65A-B2AE-4CCC-B067-E6B8E75DF73A}</Project>
|
||||
<Package>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Package>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\TreeConverter\TreeConverter.csproj">
|
||||
<Name>TreeConverter</Name>
|
||||
<Project>{1C9C945A-586D-42A2-A06B-65D84FA7FF78}</Project>
|
||||
<Package>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Package>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Compiler.cs" />
|
||||
<Compile Include="Config\AssemblyInfo.cs" />
|
||||
<Compile Include="ConsoleCompilerCommands.cs" />
|
||||
<Compile Include="DocXml.cs" />
|
||||
<Compile Include="ICompiler.cs" />
|
||||
<Compile Include="IProjectInfo.cs" />
|
||||
<Compile Include="ProjectInfo.cs" />
|
||||
<Compile Include="RemoteCompiler.cs" />
|
||||
<Compile Include="SemanticTreeConverters\ISemanticTreeConverter.cs" />
|
||||
<Compile Include="SemanticTreeConverters\SemanticTreeConvertersController.cs" />
|
||||
<Compile Include="Errors.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="PCU\PCUFileFormatVersion.cs" />
|
||||
<Compile Include="PCU\PCUWriter.cs" />
|
||||
<Compile Include="PCU\PCUReader.cs" />
|
||||
<Compile Include="PCU\PCUWrappers.cs" />
|
||||
<Compile Include="..\Configuration\GlobalAssemblyInfo.cs">
|
||||
<Link>Config\GlobalAssemblyInfo.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="string_constants.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="SyntaxTreeConvertersController\SyntaxTreeConvertersController.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\CoreUtils\PABCCoreUtils.csproj" />
|
||||
<ProjectReference Include="..\Errors\Errors.csproj" />
|
||||
<ProjectReference Include="..\LanguageIntegrator\LanguageIntegrator.csproj" />
|
||||
<ProjectReference Include="..\Localization\Localization.csproj" />
|
||||
<ProjectReference Include="..\NETGenerator\NETGenerator.csproj" />
|
||||
<ProjectReference Include="..\CompilerTools\CompilerTools.csproj" />
|
||||
<ProjectReference Include="..\ParserTools\ParserTools.csproj" />
|
||||
<ProjectReference Include="..\SemanticTree\SemanticTree.csproj" />
|
||||
<ProjectReference Include="..\StringConstants\StringConstants.csproj" />
|
||||
<ProjectReference Include="..\SyntaxTree\SyntaxTree.csproj" />
|
||||
<ProjectReference Include="..\SyntaxVisitors\SyntaxVisitors.csproj" />
|
||||
<ProjectReference Include="..\TreeConverter\TreeConverter.csproj" />
|
||||
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Клиентский профиль .NET Framework 3.5 SP1</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Установщик Windows 3.1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>
|
||||
</PreBuildEvent>
|
||||
<PostBuildEvent>
|
||||
</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
67
Compiler/Compiler.csproj.user
Normal file
67
Compiler/Compiler.csproj.user
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<LastOpenVersion>7.10.3077</LastOpenVersion>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ReferencePath>
|
||||
</ReferencePath>
|
||||
<CopyProjectDestinationFolder>
|
||||
</CopyProjectDestinationFolder>
|
||||
<CopyProjectUncPath>
|
||||
</CopyProjectUncPath>
|
||||
<CopyProjectOption>0</CopyProjectOption>
|
||||
<ProjectView>ProjectFiles</ProjectView>
|
||||
<ProjectTrust>0</ProjectTrust>
|
||||
<PublishUrlHistory />
|
||||
<InstallUrlHistory />
|
||||
<SupportUrlHistory />
|
||||
<UpdateUrlHistory />
|
||||
<BootstrapperUrlHistory />
|
||||
<ErrorReportUrlHistory />
|
||||
<FallbackCulture>ru-RU</FallbackCulture>
|
||||
<VerifyUploadedFiles>false</VerifyUploadedFiles>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<EnableASPDebugging>false</EnableASPDebugging>
|
||||
<EnableASPXDebugging>false</EnableASPXDebugging>
|
||||
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
|
||||
<EnableSQLServerDebugging>false</EnableSQLServerDebugging>
|
||||
<RemoteDebugEnabled>false</RemoteDebugEnabled>
|
||||
<RemoteDebugMachine>
|
||||
</RemoteDebugMachine>
|
||||
<StartAction>Project</StartAction>
|
||||
<StartArguments>
|
||||
</StartArguments>
|
||||
<StartPage>
|
||||
</StartPage>
|
||||
<StartProgram>
|
||||
</StartProgram>
|
||||
<StartURL>
|
||||
</StartURL>
|
||||
<StartWorkingDirectory>
|
||||
</StartWorkingDirectory>
|
||||
<StartWithIE>true</StartWithIE>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<EnableASPDebugging>false</EnableASPDebugging>
|
||||
<EnableASPXDebugging>false</EnableASPXDebugging>
|
||||
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
|
||||
<EnableSQLServerDebugging>false</EnableSQLServerDebugging>
|
||||
<RemoteDebugEnabled>false</RemoteDebugEnabled>
|
||||
<RemoteDebugMachine>
|
||||
</RemoteDebugMachine>
|
||||
<StartAction>Project</StartAction>
|
||||
<StartArguments>
|
||||
</StartArguments>
|
||||
<StartPage>
|
||||
</StartPage>
|
||||
<StartProgram>
|
||||
</StartProgram>
|
||||
<StartURL>
|
||||
</StartURL>
|
||||
<StartWorkingDirectory>
|
||||
</StartWorkingDirectory>
|
||||
<StartWithIE>true</StartWithIE>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
@ -8,10 +8,11 @@ namespace PascalABCCompiler
|
|||
{
|
||||
public class ConsoleCompilerConstants
|
||||
{
|
||||
public const int MaxProcessMemoryMB = 500;
|
||||
public const int MaxProcessMemoryMB = 150;
|
||||
|
||||
public const string DataSeparator = "]\r\n[";
|
||||
public static readonly string MessageSeparator = "\002\002\002";
|
||||
//public const string MessageSeparator = "***";
|
||||
public const string MessageSeparator = "\002\002\002";
|
||||
|
||||
//1xx to remoteCompiler
|
||||
public const int CommandStartNumber = 100;
|
||||
|
|
@ -25,7 +26,6 @@ namespace PascalABCCompiler
|
|||
public const int GetLastWriteTime = 186;
|
||||
public const int VarBeginOffest = 187;
|
||||
public const int InternalError = 188;
|
||||
public const int PABCHealth = 189;
|
||||
|
||||
|
||||
//2xx to pabcnetc.exe
|
||||
|
|
@ -48,12 +48,5 @@ namespace PascalABCCompiler
|
|||
public const int CompilerOptionsProjectCompiled = 225;
|
||||
public const int UseDllForSystemUnits = 226;
|
||||
public const int IDELocale = 227;
|
||||
public const int CompilerLocale = 228;
|
||||
|
||||
static ConsoleCompilerConstants()
|
||||
{
|
||||
if (System.Environment.OSVersion.Platform == System.PlatformID.Unix || System.Environment.OSVersion.Platform == System.PlatformID.MacOSX)
|
||||
MessageSeparator = "*\002\002\002*";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,19 +24,19 @@ namespace PascalABCCompiler
|
|||
try
|
||||
{
|
||||
this.cu = cu;
|
||||
is_assembly = cu.SyntaxTree is SyntaxTree.program_module || Compiler.IsDll(cu.SyntaxTree);
|
||||
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.UnitFileName, ".xml"), settings);
|
||||
unit_name = Path.GetFileNameWithoutExtension(cu.UnitFileName);
|
||||
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.UnitFileName));
|
||||
xtw.WriteString(Path.GetFileNameWithoutExtension(cu.UnitName));
|
||||
xtw.WriteEndElement();
|
||||
xtw.WriteEndElement();
|
||||
}
|
||||
|
|
@ -45,7 +45,7 @@ namespace PascalABCCompiler
|
|||
xtw.WriteStartElement("unit");
|
||||
xtw.WriteStartAttribute("name");
|
||||
//xtw.WriteString((cu.SemanticTree as common_unit_node).unit_name);
|
||||
xtw.WriteString(Path.GetFileNameWithoutExtension(cu.UnitFileName));
|
||||
xtw.WriteString(Path.GetFileNameWithoutExtension(cu.UnitName));
|
||||
xtw.WriteEndAttribute();
|
||||
xtw.WriteString(cu.SemanticTree.documentation);
|
||||
xtw.WriteEndElement();
|
||||
|
|
@ -364,7 +364,7 @@ namespace PascalABCCompiler
|
|||
|
||||
private string get_delegate_name(common_type_node ctn)
|
||||
{
|
||||
common_method_node cmn = ctn.find_first_in_type(StringConstants.invoke_method_name).sym_info as common_method_node;
|
||||
common_method_node cmn = ctn.find_first_in_type(compiler_string_consts.invoke_method_name).sym_info as common_method_node;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (cmn.return_value_type != null)
|
||||
sb.Append("@function");
|
||||
|
|
|
|||
|
|
@ -1,441 +1,107 @@
|
|||
// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
|
||||
// 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 System;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace PascalABCCompiler.Errors
|
||||
namespace PascalABCCompiler
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Базовый класс для ошибок, бросаемых компилятором
|
||||
/// </summary>
|
||||
public class CompilerThrownError : LocatedError
|
||||
{
|
||||
public CompilerThrownError(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
public CompilerThrownError(string message, string FileName)
|
||||
: base(message, FileName)
|
||||
{
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
return Message;
|
||||
}
|
||||
}
|
||||
public class FileNotFound : TreeConverter.CompilationErrorWithLocation
|
||||
{
|
||||
private string _file_name;
|
||||
|
||||
/// <summary>
|
||||
/// Бросается в случае невозможности чтения pcu
|
||||
/// </summary>
|
||||
public class ReadPCUError : CompilerThrownError
|
||||
{
|
||||
public ReadPCUError(string FileName)
|
||||
: base(string.Format(StringResources.Get("COMPILATIONERROR_READ_PCU{0}_ERROR"), FileName))
|
||||
{
|
||||
}
|
||||
}
|
||||
public FileNotFound(string file_name, TreeRealization.location loc):base(loc)
|
||||
{
|
||||
_file_name=file_name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Бросается в случае использования uses in в пространстве имен
|
||||
/// </summary>
|
||||
public class NamespaceCannotHaveInSection : CompilerThrownError
|
||||
{
|
||||
public NamespaceCannotHaveInSection(SyntaxTree.SourceContext sc)
|
||||
: base(string.Format(StringResources.Get("COMPILATIONERROR_NAMESPACE_CANNOT_HAVE_IN_SECTION")))
|
||||
{
|
||||
this.source_context = sc;
|
||||
}
|
||||
}
|
||||
public string file_name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _file_name;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Бросается, если встречена не основная программа (там где она должна быть)
|
||||
/// </summary>
|
||||
public class ProgramModuleExpected : CompilerThrownError
|
||||
{
|
||||
public ProgramModuleExpected(string FileName, SyntaxTree.SourceContext sc)
|
||||
: base(StringResources.Get("COMPILATIONERROR_PROGRAM_MODULE_EXPECTED"), FileName)
|
||||
{
|
||||
this.source_context = sc;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Бросается, если встречен не модуль (там где он должна быть)
|
||||
/// </summary>
|
||||
public class UnitModuleExpected : CompilerThrownError
|
||||
{
|
||||
public UnitModuleExpected(string FileName, SyntaxTree.SourceContext sc)
|
||||
: base(StringResources.Get("COMPILATIONERROR_UNIT_MODULE_EXPECTED"), FileName)
|
||||
{
|
||||
this.source_context = sc;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Бросается при обнаружении директивы {$apptype dll} не в библиотеке
|
||||
/// </summary>
|
||||
public class AppTypeDllIsAllowedOnlyForLibraries : CompilerThrownError
|
||||
{
|
||||
public AppTypeDllIsAllowedOnlyForLibraries(string FileName, SyntaxTree.SourceContext sc)
|
||||
: base(StringResources.Get("COMPILATIONERROR_APPTYPE_DLL_IS_ALLOWED_ONLY_FOR_LIBRARIES"), FileName)
|
||||
{
|
||||
this.source_context = sc;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Бросается при обраружении директивы {$DisableStandardUnits} в подключенном модуле
|
||||
/// </summary>
|
||||
public class DisableStandardUnitsDirectiveDisallowedInUsedUnits : CompilerThrownError
|
||||
{
|
||||
public DisableStandardUnitsDirectiveDisallowedInUsedUnits(string FileName, SyntaxTree.SourceContext sc)
|
||||
: base(StringResources.Get("COMPILATIONERROR_DISABLE_STANDARD_UNITS_DIRECTIVE_DISALLOWED_IN_USED_UNITS"), FileName)
|
||||
{
|
||||
this.source_context = sc;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Бросается при компиляции библиотеки не первой
|
||||
/// </summary>
|
||||
public class UnitModuleExpectedLibraryFound : CompilerThrownError
|
||||
{
|
||||
public UnitModuleExpectedLibraryFound(string FileName, SyntaxTree.SourceContext sc)
|
||||
: base(StringResources.Get("COMPILATIONERROR_UNIT_MODULE_EXPECTED_LIBRARY_FOUND"), FileName)
|
||||
{
|
||||
this.source_context = sc;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Бросается, если файл сборки не найден
|
||||
/// </summary>
|
||||
public class AssemblyNotFound : CompilerThrownError
|
||||
{
|
||||
public string AssemblyFileName;
|
||||
public AssemblyNotFound(string FileName, string AssemblyFileName, SyntaxTree.SourceContext sc)
|
||||
: base(string.Format(StringResources.Get("COMPILATIONERROR_ASSEMBLY_{0}_NOT_FOUND"), AssemblyFileName), FileName)
|
||||
{
|
||||
this.AssemblyFileName = AssemblyFileName;
|
||||
this.source_context = sc;
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(StringResources.Get("COMPILATIONERROR_FILE_{0}_NOT_FOUND"), _file_name);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Бросается при невозможности чтения сборки
|
||||
/// </summary>
|
||||
public class AssemblyReadingError : CompilerThrownError
|
||||
{
|
||||
public string AssemblyFileName;
|
||||
public AssemblyReadingError(string FileName, string AssemblyFileName, SyntaxTree.SourceContext sc)
|
||||
: base(string.Format(StringResources.Get("COMPILATIONERROR_ASSEMBLY_{0}_READING_ERROR"), AssemblyFileName), FileName)
|
||||
{
|
||||
this.AssemblyFileName = AssemblyFileName;
|
||||
this.source_context = sc;
|
||||
}
|
||||
}
|
||||
public class DLLReadingError : TreeConverter.CompilationError
|
||||
{
|
||||
private string _dll_name;
|
||||
|
||||
/// <summary>
|
||||
/// Бросается при попытке обработки неправильного пути к сборке
|
||||
/// </summary>
|
||||
public class InvalidAssemblyPathError : CompilerThrownError
|
||||
{
|
||||
public InvalidAssemblyPathError(string FileName, SyntaxTree.SourceContext sc)
|
||||
: base(string.Format(StringResources.Get("COMPILATIONERROR_INVALID_ASSEMBLY_PATH")), FileName)
|
||||
{
|
||||
this.source_context = sc;
|
||||
}
|
||||
}
|
||||
public DLLReadingError(string dll_name)
|
||||
{
|
||||
_dll_name=dll_name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Бросается при попытке обработки неправильного пути к файлу
|
||||
/// </summary>
|
||||
public class InvalidPathError : CompilerThrownError
|
||||
{
|
||||
public InvalidPathError(SyntaxTree.SourceContext sc)
|
||||
: base(string.Format(StringResources.Get("COMPILATIONERROR_INVALID_PATH")))
|
||||
{
|
||||
this.source_context = sc;
|
||||
this.fileName = sc.FileName;
|
||||
}
|
||||
}
|
||||
public string dll_name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _dll_name;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Бросается при неудаче в нахождении файла ресурсов
|
||||
/// </summary>
|
||||
public class ResourceFileNotFound : CompilerThrownError
|
||||
{
|
||||
public ResourceFileNotFound(string fileName, string ResFileName, SourceContext sc)
|
||||
: base(string.Format(StringResources.Get("COMPILATIONERROR_RESOURCEFILE_{0}_NOT_FOUND"), ResFileName), fileName)
|
||||
{
|
||||
source_context = sc;
|
||||
}
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
//return ("Dll: "+dll_name+" not found");
|
||||
return string.Format(StringResources.Get("COMPILATIONERROR_ASSEMBLY_{0}_READING_ERROR"), dll_name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Бросается при подключении явного пространства имен в модуле
|
||||
/// </summary>
|
||||
public class IncludeNamespaceInUnitError : CompilerThrownError
|
||||
{
|
||||
public IncludeNamespaceInUnitError(string FileName, SourceContext sc)
|
||||
: base(string.Format(StringResources.Get("COMPILATIONERROR_INCLUDE_NAMESPACE_IN_UNIT")), FileName)
|
||||
{
|
||||
this.source_context = sc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Бросается, если встречено не явное пространство имен
|
||||
/// </summary>
|
||||
public class NamespaceModuleExpected : CompilerThrownError
|
||||
{
|
||||
public NamespaceModuleExpected(SourceContext sc)
|
||||
: base(string.Format(StringResources.Get("COMPILATIONERROR_NAMESPACE_MODULE_EXPECTED")))
|
||||
{
|
||||
this.source_context = sc;
|
||||
}
|
||||
}
|
||||
public class InvalidUnit : TreeConverter.CompilationError
|
||||
{
|
||||
private string _unit_name;
|
||||
|
||||
/// <summary>
|
||||
/// Бросается в случае некорректного использования директивы {$mainresource ...}
|
||||
/// </summary>
|
||||
public class MainResourceNotAllowed : CompilerThrownError
|
||||
{
|
||||
public MainResourceNotAllowed(string fileName, SourceContext sc)
|
||||
: base(string.Format(StringResources.Get("COMPILATIONERROR_MAINRESOURCE_NOT_ALLOWED")), fileName)
|
||||
{
|
||||
source_context = sc;
|
||||
}
|
||||
public InvalidUnit(string unit_name)
|
||||
{
|
||||
_unit_name=unit_name;
|
||||
}
|
||||
|
||||
}
|
||||
public string unit_name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _unit_name;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Бросается при нахождении дубликатов в секции uses
|
||||
/// </summary>
|
||||
public class DuplicateUsesUnit : CompilerThrownError
|
||||
{
|
||||
public string UnitName;
|
||||
public DuplicateUsesUnit(string FileName, string UnitName, SyntaxTree.SourceContext sc)
|
||||
: base(string.Format(StringResources.Get("COMPILATIONERROR_DUPLICATE_USES_UNIT{0}"), UnitName), FileName)
|
||||
{
|
||||
this.UnitName = UnitName;
|
||||
this.source_context = sc;
|
||||
}
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
return ("Invalid unit: "+_unit_name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Бросается при нахождении дубликатов директив, не поддерживающих многократное использование в рамках некоторого контекста
|
||||
/// </summary>
|
||||
public class DuplicateDirective : CompilerThrownError
|
||||
{
|
||||
public string DirectiveName;
|
||||
public DuplicateDirective(string FileName, string DirectiveName, SyntaxTree.SourceContext sc)
|
||||
: base(string.Format(StringResources.Get("COMPILATIONERROR_DUPLICATE_DIRECTIVE{0}"), DirectiveName), FileName)
|
||||
{
|
||||
this.DirectiveName = DirectiveName;
|
||||
this.source_context = sc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Legacy, бросается, если unitModule.unitName.HeaderKeyword == SyntaxTree.UnitHeaderKeyword.Namespace
|
||||
/// </summary>
|
||||
public class NamespacesCanBeCompiledOnlyInProjects : CompilerThrownError
|
||||
{
|
||||
public NamespacesCanBeCompiledOnlyInProjects(SyntaxTree.SourceContext sc)
|
||||
: base(StringResources.Get("COMPILATIONERROR_NAMESPACE_CAN_BE_COMPILED_ONLY_IN_PROJECTS"))
|
||||
{
|
||||
this.source_context = sc;
|
||||
}
|
||||
}
|
||||
public class UnitCompilationError : TreeConverter.CompilationError
|
||||
{
|
||||
private SyntaxTree.unit_or_namespace _SyntaxUsesUnit;
|
||||
private string _file_name;
|
||||
|
||||
/// <summary>
|
||||
/// Бросается, если модуль (unit) не найден по некоторому пути
|
||||
/// </summary>
|
||||
public class UnitNotFound : CompilerThrownError
|
||||
{
|
||||
public string UnitName;
|
||||
public UnitNotFound(string FileName, string UnitName, SyntaxTree.SourceContext sc)
|
||||
: base(string.Format(StringResources.Get("COMPILATIONERROR_UNIT_{0}_NOT_FOUND"), UnitName), FileName)
|
||||
{
|
||||
this.UnitName = UnitName;
|
||||
this.source_context = sc;
|
||||
}
|
||||
}
|
||||
public UnitCompilationError(string fileName,SyntaxTree.unit_or_namespace syntaxUsesUnit)
|
||||
{
|
||||
_SyntaxUsesUnit=syntaxUsesUnit;
|
||||
_file_name=fileName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Бросается при некорректном пути в uses in
|
||||
/// </summary>
|
||||
public class UsesInWrongName : CompilerThrownError
|
||||
{
|
||||
public string UnitName1;
|
||||
public string UnitName2;
|
||||
public UsesInWrongName(string FileName, string UnitName1, string UnitName2, SyntaxTree.SourceContext sc)
|
||||
: base(string.Format(StringResources.Get("COMPILATIONERROR_USES_IN_WRONG_NAME"), UnitName1, UnitName2), FileName)
|
||||
{
|
||||
this.UnitName1 = UnitName1;
|
||||
this.UnitName2 = UnitName2;
|
||||
this.source_context = sc;
|
||||
}
|
||||
}
|
||||
public SyntaxTree.unit_or_namespace SyntaxUsesUnit
|
||||
{
|
||||
get
|
||||
{
|
||||
return _SyntaxUsesUnit;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Бросается при невозможности найти исходник по некотрому пути
|
||||
/// </summary>
|
||||
public class SourceFileNotFound : CompilerThrownError
|
||||
{
|
||||
public SourceFileNotFound(string FileName)
|
||||
: base(string.Format(StringResources.Get("COMPILATIONERROR_SOURCE_FILE_{0}_NOT_FOUND"), FileName))
|
||||
{
|
||||
}
|
||||
}
|
||||
public string file_name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _file_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Бросается при попытке файловой операции с недостаточными правами
|
||||
/// </summary>
|
||||
public class UnauthorizedAccessToFile : CompilerThrownError
|
||||
{
|
||||
public UnauthorizedAccessToFile(string FileName)
|
||||
: base(string.Format(StringResources.Get("COMPILATIONERROR_NO_ACCESS_TO_FILE{0}"), FileName))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Бросается в случае обнаружения циклической зависимости модулей
|
||||
/// </summary>
|
||||
public class CycleUnitReference : CompilerThrownError
|
||||
{
|
||||
public CycleUnitReference(string FileName, SyntaxTree.unit_or_namespace SyntaxUsesUnit)
|
||||
: base(string.Format(StringResources.Get("COMPILATIONERROR_CYCLIC_UNIT_REFERENCE_WITH_UNIT_{0}"), SyntaxTree.Utils.IdentListToString(SyntaxUsesUnit.name.idents, ".")), FileName)
|
||||
{
|
||||
this.source_context = SyntaxUsesUnit.source_context;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Бросается, если пользователь указывает неподдерживаемый целевой framework
|
||||
/// </summary>
|
||||
public class UnsupportedTargetFramework : CompilerThrownError
|
||||
{
|
||||
public UnsupportedTargetFramework(string FrameworkName, SourceContext sc)
|
||||
: base(string.Format(StringResources.Get("COMPILATIONERROR_UNSUPPORTED_TARGETFRAMEWORK_{0}"), FrameworkName))
|
||||
{
|
||||
this.source_context = sc;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Бросается, если пользователь указывает неподдерживаемую целевую платформу
|
||||
/// </summary>
|
||||
public class UnsupportedTargetPlatform : CompilerThrownError
|
||||
{
|
||||
public UnsupportedTargetPlatform(string platformName, SourceContext sc)
|
||||
: base(string.Format(StringResources.Get("COMPILATIONERROR_UNSUPPORTED_TARGET_PLATFORM{0}"), platformName))
|
||||
{
|
||||
source_context = sc;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Бросается, если пользователь указывает неподдерживаемый тип выходного файла (например, в директиве {$apptype ...})
|
||||
/// </summary>
|
||||
public class UnsupportedOutputFileType : CompilerThrownError
|
||||
{
|
||||
public UnsupportedOutputFileType(string outputFileType, SourceContext sc)
|
||||
: base(string.Format(StringResources.Get("COMPILATIONERROR_UNSUPPORTED_OUTPUT_FILE_TYPE{0}"), outputFileType))
|
||||
{
|
||||
source_context = sc;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Бросается при отсутствии некоторого файла по некоторому пути
|
||||
/// </summary>
|
||||
public class FileNotFound : CompilerThrownError
|
||||
{
|
||||
public FileNotFound(string fileName, SourceContext sc)
|
||||
: base(string.Format(StringResources.Get("COMPILATIONERROR_FILE_{0}_NOT_FOUND"), fileName))
|
||||
{
|
||||
this.source_context = sc;
|
||||
}
|
||||
}
|
||||
|
||||
/*public class DLLReadingError : TreeConverter.CompilationError
|
||||
{
|
||||
private string _dll_name;
|
||||
|
||||
public DLLReadingError(string dll_name)
|
||||
{
|
||||
_dll_name = dll_name;
|
||||
}
|
||||
|
||||
public string dll_name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _dll_name;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
//return ("Dll: "+dll_name+" not found");
|
||||
return string.Format(StringResources.Get("COMPILATIONERROR_ASSEMBLY_{0}_READING_ERROR"), dll_name);
|
||||
}
|
||||
}
|
||||
|
||||
public class InvalidUnit : TreeConverter.CompilationError
|
||||
{
|
||||
private string _unit_name;
|
||||
|
||||
public InvalidUnit(string unit_name)
|
||||
{
|
||||
_unit_name = unit_name;
|
||||
}
|
||||
|
||||
public string unit_name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _unit_name;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return ("Invalid unit: " + _unit_name);
|
||||
}
|
||||
}
|
||||
|
||||
public class UnitCompilationError : TreeConverter.CompilationError
|
||||
{
|
||||
private SyntaxTree.unit_or_namespace _SyntaxUsesUnit;
|
||||
private string _file_name;
|
||||
|
||||
public UnitCompilationError(string fileName, SyntaxTree.unit_or_namespace syntaxUsesUnit)
|
||||
{
|
||||
_SyntaxUsesUnit = syntaxUsesUnit;
|
||||
_file_name = fileName;
|
||||
}
|
||||
|
||||
public SyntaxTree.unit_or_namespace SyntaxUsesUnit
|
||||
{
|
||||
get
|
||||
{
|
||||
return _SyntaxUsesUnit;
|
||||
}
|
||||
}
|
||||
|
||||
public string file_name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _file_name;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
// 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 System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using PascalABCCompiler.SemanticTreeConverters;
|
||||
using PascalABCCompiler.SyntaxTreeConverters;
|
||||
using PascalABCCompiler.Errors;
|
||||
|
||||
///В разработке DarkStar
|
||||
|
|
@ -11,27 +14,25 @@ namespace PascalABCCompiler
|
|||
public enum CompilerType { Standart, Remote }
|
||||
public interface ICompiler
|
||||
{
|
||||
/// Здоровье кода на всякий случай выносим в интерфейс компилятора
|
||||
/// Реально оно будет использоваться только при запуске из под оболочки (Remote Compiler)
|
||||
int PABCCodeHealth
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/*SyntaxTreeConvertersController SyntaxTreeConvertersController
|
||||
SyntaxTreeConvertersController SyntaxTreeConvertersController
|
||||
{
|
||||
get;
|
||||
}*/
|
||||
}
|
||||
SemanticTreeConvertersController SemanticTreeConvertersController
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/*SemanticTree.IProgramNode SemanticTree
|
||||
|
||||
Parsers.Controller ParsersController
|
||||
{
|
||||
get;
|
||||
}*/
|
||||
}
|
||||
|
||||
SemanticTree.IProgramNode SemanticTree
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
uint LinesCompiled
|
||||
{
|
||||
get;
|
||||
|
|
@ -47,6 +48,16 @@ namespace PascalABCCompiler
|
|||
{
|
||||
get;
|
||||
}
|
||||
|
||||
SupportedSourceFile[] SupportedSourceFiles
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
SupportedSourceFile[] SupportedProjectFiles
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
CompilerOptions CompilerOptions
|
||||
{
|
||||
|
|
@ -79,9 +90,9 @@ namespace PascalABCCompiler
|
|||
get;
|
||||
}
|
||||
|
||||
PascalABCCompiler.CoreUtils.SourceFilesProviderDelegate SourceFilesProvider
|
||||
SourceFilesProviderDelegate SourceFilesProvider
|
||||
{
|
||||
get; set;
|
||||
get;
|
||||
}
|
||||
|
||||
event ChangeCompilerStateEventDelegate OnChangeCompilerState;
|
||||
|
|
@ -96,11 +107,9 @@ namespace PascalABCCompiler
|
|||
|
||||
void AddWarnings(List<CompilerWarning> WarningList);
|
||||
|
||||
// Не нужно это в интерфейсе! Этого нет в RemoteCompiler!
|
||||
// SyntaxTree.compilation_unit ParseText(string FileName, string Text, List<Error> ErrorList, List<CompilerWarning> Warnings);
|
||||
SyntaxTree.compilation_unit ParseText(string FileName, string Text, List<Error> ErrorList, List<CompilerWarning> Warnings);
|
||||
|
||||
// Не нужно это в интерфейсе! Этого нет в RemoteCompiler!
|
||||
// string GetSourceFileText(string FileName);
|
||||
string GetSourceFileText(string FileName);
|
||||
|
||||
CompilerType CompilerType
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
// 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)
|
||||
|
||||
// при внесении изменений в структуру PCU файла версию увеличить на 1
|
||||
//ѕри внесении изменений в структуру PCU файла версию увеличить на 1
|
||||
|
||||
namespace PascalABCCompiler.PCU
|
||||
{
|
||||
public static class PCUFileFormatVersion
|
||||
{
|
||||
public static System.Int16 Version = 123;
|
||||
public static System.Int16 Version = 115;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -189,9 +189,7 @@ namespace PascalABCCompiler.PCU
|
|||
{
|
||||
if (pcu_tsi == null)
|
||||
return true;
|
||||
//if (pcu_tsi.semantic_node_type == semantic_node_type.common_method_node && pcu_tsi.virtual_slot)
|
||||
// return true;
|
||||
if (pcu_tsi.always_restore)
|
||||
if (pcu_tsi.semantic_node_type == semantic_node_type.common_method_node && pcu_tsi.virtual_slot)
|
||||
return true;
|
||||
if (hasNotRestoreAttribute())
|
||||
return false;
|
||||
|
|
@ -349,7 +347,7 @@ namespace PascalABCCompiler.PCU
|
|||
{
|
||||
if (base_type != null && base_type.IsDelegate)
|
||||
return base_type.find_in_type(name, CurrentScope, null, no_search_in_extension_methods);
|
||||
else if (name == StringConstants.deconstruct_method_name)
|
||||
else if (name == compiler_string_consts.deconstruct_method_name)
|
||||
return SystemLibrary.SystemLibrary.object_type.find_in_type(name, CurrentScope, null, no_search_in_extension_methods);
|
||||
|
||||
// SSM перенес из common_type_node (types.cs 2116) - без этого не работали методы расширения последовательностей для типов в pcu, реализующих IEnumerable<T>
|
||||
|
|
@ -385,7 +383,7 @@ namespace PascalABCCompiler.PCU
|
|||
if (this.base_generic_instance != null && sil != null)
|
||||
{
|
||||
var bsil = base_generic_instance.ConvertSymbolInfo(sil);
|
||||
if (orig_generic_or_null == null && name != "op_Implicit")
|
||||
if (orig_generic_or_null == null)
|
||||
return bsil;
|
||||
}
|
||||
foreach (SymbolInfo si in sil)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -8,7 +8,8 @@ using System.IO;
|
|||
using System.Threading;
|
||||
using PascalABCCompiler.Errors;
|
||||
using PascalABCCompiler.TreeRealization;
|
||||
using PascalABCCompiler.CoreUtils;
|
||||
using System.Runtime.Serialization.Formatters;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
|
||||
namespace PascalABCCompiler
|
||||
{
|
||||
|
|
@ -57,7 +58,7 @@ namespace PascalABCCompiler
|
|||
get
|
||||
{
|
||||
if(loc!=null)
|
||||
return new SourceLocation(loc.file_name, loc.begin_line_num, loc.begin_column_num, loc.end_line_num, loc.end_column_num);
|
||||
return new SourceLocation(loc.doc.file_name, loc.begin_line_num, loc.begin_column_num, loc.end_line_num, loc.end_column_num);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
|
@ -84,9 +85,9 @@ namespace PascalABCCompiler
|
|||
string inputId = "pabcnetc_input";
|
||||
string pabcnetcFileName = "pabcnetc.exe";
|
||||
public const int sendCommandStartNumber = 100;
|
||||
public volatile CompilerState compilerState = CompilerState.Reloading; // PVS 01/2022 volatile
|
||||
CompilerState compilerState = CompilerState.Reloading;
|
||||
Encoding inputEncoding = System.Text.Encoding.UTF8;
|
||||
bool compilationStarted = false;
|
||||
bool compilationSatarted = false;
|
||||
|
||||
public int MaxProcessMemoryMB
|
||||
{
|
||||
|
|
@ -111,23 +112,15 @@ namespace PascalABCCompiler
|
|||
Reload();
|
||||
}
|
||||
|
||||
public void stringRecived(string id, string line)
|
||||
void stringRecived(string id, string line)
|
||||
{
|
||||
string arg = null;
|
||||
if (line.Length < 3)
|
||||
return;
|
||||
if ((int)line[0] == 65279 && (int)line[1] == 65279)
|
||||
{
|
||||
line = line.Substring(2);
|
||||
if (line.Length < 3)
|
||||
return;
|
||||
}
|
||||
|
||||
if (line.Length > 3)
|
||||
arg = line.Substring(4);
|
||||
string[] args = Tools.SplitString(arg, ConsoleCompilerConstants.MessageSeparator);
|
||||
int command = Convert.ToInt32(line.Substring(0, 3));
|
||||
|
||||
if (command < sendCommandStartNumber + 50)
|
||||
{
|
||||
ChangeCompilerState((CompilerState)(command - sendCommandStartNumber), arg);
|
||||
|
|
@ -135,9 +128,6 @@ namespace PascalABCCompiler
|
|||
}
|
||||
switch (command)
|
||||
{
|
||||
case ConsoleCompilerConstants.PABCHealth:
|
||||
pABCCodeHealth = Convert.ToInt32(arg);
|
||||
break;
|
||||
case ConsoleCompilerConstants.LinesCompiled:
|
||||
linesCompiled = Convert.ToUInt32(arg);
|
||||
break;
|
||||
|
|
@ -155,9 +145,9 @@ namespace PascalABCCompiler
|
|||
loc = new location(
|
||||
Convert.ToInt32(args[1]), Convert.ToInt32(args[2]),
|
||||
Convert.ToInt32(args[3]), Convert.ToInt32(args[4]),
|
||||
args[5]);
|
||||
new document(args[5]));
|
||||
if (args.Length == 2)
|
||||
loc = new location(0,0,0,0,args[1]);
|
||||
loc = new location(0,0,0,0,new document(args[1]));
|
||||
switch(command)
|
||||
{
|
||||
case ConsoleCompilerConstants.Error:
|
||||
|
|
@ -196,8 +186,6 @@ namespace PascalABCCompiler
|
|||
//Encoding enc = (Encoding)sourceFilesProvider(arg, SourceFileOperation.FileEncoding);
|
||||
//text = Tools.ChangeEncoding(text, enc, Encoding.UTF8);
|
||||
//text = Tools.ChangeEncoding(text, Encoding.GetEncoding(1251), Encoding.UTF8);
|
||||
if (pabcnetcProcess == null)
|
||||
Reload();
|
||||
Process pr = pabcnetcProcess;
|
||||
sendCommand(ConsoleCompilerConstants.SourceFileText, text.Length);
|
||||
byte[] buf = Encoding.UTF8.GetBytes(text);
|
||||
|
|
@ -211,9 +199,9 @@ namespace PascalABCCompiler
|
|||
|
||||
void ChangeCompilerState(CompilerState State, string FileName)
|
||||
{
|
||||
if (State == CompilerState.Ready && compilationStarted)
|
||||
if (State == CompilerState.Ready && compilationSatarted)
|
||||
{
|
||||
compilationStarted = false;
|
||||
compilationSatarted = false;
|
||||
if (CheckProcessMemory())
|
||||
return;
|
||||
}
|
||||
|
|
@ -222,7 +210,7 @@ namespace PascalABCCompiler
|
|||
OnChangeCompilerState(this, State, FileName);
|
||||
}
|
||||
|
||||
/*void stopCompiler()
|
||||
void stopCompiler()
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -241,31 +229,6 @@ namespace PascalABCCompiler
|
|||
pabcnetcProcess = null;
|
||||
remoteCompilerWorkingSet = 0;
|
||||
}
|
||||
}*/
|
||||
|
||||
// SSM 09/01/26 - по совету DeepSeek добавил WaitForExit(10) и Dispose() чтобы освободить ресурсы
|
||||
void stopCompiler()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (pabcnetcProcess != null && !pabcnetcProcess.HasExited)
|
||||
{
|
||||
pabcnetcProcess.EnableRaisingEvents = false;
|
||||
|
||||
if (pabcnetcStreamReader != null)
|
||||
pabcnetcStreamReader.Remove(inputId);
|
||||
|
||||
pabcnetcProcess.Kill();
|
||||
pabcnetcProcess.WaitForExit(10);
|
||||
pabcnetcProcess.Dispose(); // ← ЕДИНСТВЕННОЕ ДОБАВЛЕНИЕ
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
pabcnetcProcess = null;
|
||||
remoteCompilerWorkingSet = 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -278,10 +241,6 @@ namespace PascalABCCompiler
|
|||
}
|
||||
}
|
||||
|
||||
// SSM 18/09/20
|
||||
int pABCCodeHealth = 0;
|
||||
public int PABCCodeHealth { get { return pABCCodeHealth; } }
|
||||
|
||||
CompilerInternalDebug internalDebug=new CompilerInternalDebug();
|
||||
public CompilerInternalDebug InternalDebug
|
||||
{
|
||||
|
|
@ -350,16 +309,12 @@ namespace PascalABCCompiler
|
|||
|
||||
void sendCommand(int command, object arg)
|
||||
{
|
||||
if (pabcnetcProcess == null)
|
||||
Reload();
|
||||
pabcnetcProcess.StandardInput.WriteLine(string.Format("{0} {1}", command, arg));
|
||||
pabcnetcProcess.StandardInput.Flush();
|
||||
}
|
||||
|
||||
void sendObjectAsByteArray(int command, string obj)
|
||||
{
|
||||
if (pabcnetcProcess == null)
|
||||
Reload();
|
||||
pabcnetcProcess.StandardInput.WriteLine(string.Format("{0} {1}", command, obj.Length));
|
||||
pabcnetcProcess.StandardInput.Flush();
|
||||
byte[] buf = Encoding.UTF8.GetBytes(obj);
|
||||
|
|
@ -377,20 +332,16 @@ namespace PascalABCCompiler
|
|||
|
||||
void sendCommand(int command)
|
||||
{
|
||||
if (pabcnetcProcess == null)
|
||||
Reload();
|
||||
pabcnetcProcess.StandardInput.WriteLine(command);
|
||||
}
|
||||
|
||||
/*
|
||||
* Не используется!
|
||||
void sendObject(int id, object o)
|
||||
{
|
||||
sendCommand(id);
|
||||
MemoryStream ms = new MemoryStream();
|
||||
(new BinaryFormatter()).Serialize(ms, o);
|
||||
ms.WriteTo(pabcnetcProcess.StandardInput.BaseStream);
|
||||
}*/
|
||||
}
|
||||
|
||||
void sendCompilerOptions()
|
||||
{
|
||||
|
|
@ -412,34 +363,25 @@ namespace PascalABCCompiler
|
|||
//sendCommand(ConsoleCompilerConstants.CompilerOptionsOutputDirectory, dir_name);
|
||||
sendObjectAsByteArray(ConsoleCompilerConstants.CompilerOptionsOutputDirectory, compilerOptions.OutputDirectory);
|
||||
sendCommand(ConsoleCompilerConstants.CompilerOptionsClearStandartModules);
|
||||
if (compilerOptions.Locale != null)
|
||||
sendCommand(ConsoleCompilerConstants.CompilerLocale, compilerOptions.Locale);
|
||||
|
||||
foreach (var kv in compilerOptions.StandardModules)
|
||||
{
|
||||
foreach (CompilerOptions.StandardModule module in kv.Value)
|
||||
{
|
||||
sendCommand(ConsoleCompilerConstants.CompilerOptionsStandartModule,
|
||||
module.name, (int)module.addMethod, module.languageToAdd);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (PascalABCCompiler.CompilerOptions.StandartModule sm in compilerOptions.StandartModules)
|
||||
sendCommand(
|
||||
ConsoleCompilerConstants.CompilerOptionsStandartModule,
|
||||
sm.Name,(int)sm.AddMethod,(int)sm.AddToLanguages);
|
||||
}
|
||||
|
||||
public delegate void EnvironmentIdleDelegate();
|
||||
public event EnvironmentIdleDelegate EnvironmentIdle;
|
||||
public delegate void EnvorimentIdleDelegate();
|
||||
public event EnvorimentIdleDelegate EnvorimentIdle;
|
||||
|
||||
void waitCompilerReloading()
|
||||
{
|
||||
while (compilerReloading)
|
||||
{
|
||||
Thread.Sleep(5);
|
||||
if (EnvironmentIdle != null)
|
||||
EnvironmentIdle();
|
||||
if (EnvorimentIdle != null)
|
||||
EnvorimentIdle();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public string Compile()
|
||||
{
|
||||
errorsList.Clear();
|
||||
|
|
@ -447,36 +389,14 @@ namespace PascalABCCompiler
|
|||
|
||||
//sendObject(ConsoleCompilerConstants.InternalDebug, internalDebug);
|
||||
//sendObject(ConsoleCompilerConstants.CompilerOptions, compilerOptions);
|
||||
|
||||
waitCompilerReloading();
|
||||
|
||||
sendCompilerOptions();
|
||||
compilerState = CompilerState.CompilationStarting;
|
||||
compilationStarted = true;
|
||||
compilationSatarted = true;
|
||||
sendCommand(ConsoleCompilerConstants.CommandCompile);
|
||||
|
||||
const int timeoutSeconds = 30;
|
||||
DateTime startTime = DateTime.Now;
|
||||
int checkCounter = 0;
|
||||
|
||||
while (compilerState != CompilerState.Ready)
|
||||
{
|
||||
if (checkCounter++ % 50 == 0) // 1000ms / 20ms = 50 - чтобы не вызывать дорогую DateTime.Now
|
||||
{
|
||||
if ((DateTime.Now - startTime).TotalSeconds > timeoutSeconds)
|
||||
{
|
||||
// ТАЙМАУТ! Компилятор не ответил за 30 секунд
|
||||
errorsList.Add(new RemoteCompilerInternalError(
|
||||
$"Таймаут компиляции ({timeoutSeconds} секунд). " +
|
||||
"Компилятор не отвечает."));
|
||||
|
||||
Reload(); // Перезапускаем компилятор (он вероятно завис)
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Thread.Sleep(20); // SSM 09.01.26 - изменил - было 5 мс - большая нагрузка на систему
|
||||
}
|
||||
|
||||
Thread.Sleep(5);
|
||||
if (errorsList.Count > 0)
|
||||
return null;
|
||||
return compilerOptions.OutputFileName;
|
||||
|
|
@ -509,7 +429,7 @@ namespace PascalABCCompiler
|
|||
warnings.Clear();
|
||||
waitCompilerReloading();
|
||||
sendCompilerOptions();
|
||||
compilationStarted = true;
|
||||
compilationSatarted = true;
|
||||
sendCommand(ConsoleCompilerConstants.CommandCompile);
|
||||
}
|
||||
|
||||
|
|
@ -532,8 +452,29 @@ namespace PascalABCCompiler
|
|||
}
|
||||
}
|
||||
|
||||
// SSM 2026 Исключил это из ICompiler
|
||||
/*public PascalABCCompiler.SyntaxTree.compilation_unit ParseText(string FileName, string Text, List<PascalABCCompiler.Errors.Error> ErrorList, List<CompilerWarning> Warnings)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public SupportedSourceFile[] SupportedSourceFiles
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
public SupportedSourceFile[] SupportedProjectFiles
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
public PascalABCCompiler.SyntaxTree.compilation_unit ParseText(string FileName, string Text, List<PascalABCCompiler.Errors.Error> ErrorList, List<CompilerWarning> Warnings)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
|
@ -541,7 +482,15 @@ namespace PascalABCCompiler
|
|||
public string GetSourceFileText(string FileName)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}*/
|
||||
}
|
||||
|
||||
public PascalABCCompiler.SyntaxTreeConverters.SyntaxTreeConvertersController SyntaxTreeConvertersController
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
public PascalABCCompiler.SemanticTreeConverters.SemanticTreeConvertersController SemanticTreeConvertersController
|
||||
{
|
||||
|
|
@ -551,6 +500,14 @@ namespace PascalABCCompiler
|
|||
}
|
||||
}
|
||||
|
||||
public PascalABCCompiler.Parsers.Controller ParsersController
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
public PascalABCCompiler.SemanticTree.IProgramNode SemanticTree
|
||||
{
|
||||
get
|
||||
|
|
@ -570,27 +527,15 @@ namespace PascalABCCompiler
|
|||
bool compilerReloading = true;
|
||||
public void Reload()
|
||||
{
|
||||
pABCCodeHealth = 0;
|
||||
compilerReloading = true;
|
||||
stopCompiler();
|
||||
pabcnetcProcess = new Process();
|
||||
if (!IsUnix())
|
||||
{
|
||||
pabcnetcProcess.StartInfo.FileName = Path.Combine(Tools.GetExecutablePath(), pabcnetcFileName);
|
||||
pabcnetcProcess.StartInfo.Arguments = "commandmode";
|
||||
}
|
||||
else
|
||||
{
|
||||
pabcnetcProcess.StartInfo.FileName = "mono";
|
||||
pabcnetcProcess.StartInfo.Arguments = Path.Combine(Tools.GetExecutablePath(), pabcnetcFileName)+" commandmode";
|
||||
|
||||
}
|
||||
|
||||
pabcnetcProcess.StartInfo.FileName = Path.Combine(Tools.GetExecutablePath(), pabcnetcFileName);
|
||||
pabcnetcProcess.StartInfo.Arguments = "commandmode";
|
||||
pabcnetcProcess.StartInfo.UseShellExecute = false;
|
||||
pabcnetcProcess.StartInfo.CreateNoWindow = true;
|
||||
pabcnetcProcess.StartInfo.RedirectStandardOutput = true;
|
||||
pabcnetcProcess.StartInfo.RedirectStandardInput = true;
|
||||
pabcnetcProcess.StartInfo.RedirectStandardError = true;
|
||||
pabcnetcProcess.EnableRaisingEvents = true;
|
||||
pabcnetcProcess.StartInfo.StandardOutputEncoding = System.Text.Encoding.UTF8;
|
||||
pabcnetcProcess.Exited += pabcnetcProcess_Exited;
|
||||
|
|
@ -601,19 +546,11 @@ namespace PascalABCCompiler
|
|||
compilerReloading = false;
|
||||
}
|
||||
|
||||
public static bool IsUnix()
|
||||
{
|
||||
return System.Environment.OSVersion.Platform == System.PlatformID.Unix || System.Environment.OSVersion.Platform == System.PlatformID.MacOSX;
|
||||
}
|
||||
|
||||
void pabcnetcProcess_Exited(object sender, EventArgs e)
|
||||
{
|
||||
string error = pabcnetcProcess.StandardError.ReadToEnd();
|
||||
|
||||
if (!compilerReloading)
|
||||
{
|
||||
pabcnetcProcess = null;
|
||||
//Reload();
|
||||
Reload();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,110 @@
|
|||
// 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 System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
using PascalABCCompiler.Errors;
|
||||
using PascalABCCompiler.SyntaxTreeConverters;
|
||||
|
||||
namespace PascalABCCompiler.SyntaxTreeConverters
|
||||
{
|
||||
public class SyntaxTreeConvertersController
|
||||
{
|
||||
public enum State
|
||||
{
|
||||
ConnectConverter, Convert
|
||||
}
|
||||
ICompiler Compiler;
|
||||
|
||||
private List<ISyntaxTreeConverter> syntaxTreeConverters = new List<ISyntaxTreeConverter>();
|
||||
public List<ISyntaxTreeConverter> SyntaxTreeConverters
|
||||
{
|
||||
get
|
||||
{
|
||||
return syntaxTreeConverters;
|
||||
}
|
||||
}
|
||||
|
||||
public delegate void ChangeStateDelegate(State State, ISyntaxTreeConverter SyntaxTreeConverter);
|
||||
public event ChangeStateDelegate ChangeState;
|
||||
|
||||
|
||||
public SyntaxTreeConvertersController(ICompiler Compiler)
|
||||
{
|
||||
this.Compiler = Compiler;
|
||||
}
|
||||
|
||||
public void AddStandardConverters()
|
||||
{
|
||||
var st = new StandardSyntaxTreeConverter();
|
||||
syntaxTreeConverters.Add(st);
|
||||
}
|
||||
public void AddConverters()
|
||||
{
|
||||
AddStandardConverters();
|
||||
AddExternalConvertersAsPlugins(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.FullyQualifiedName));
|
||||
}
|
||||
private void AddExternalConvertersAsPlugins(string DirectoryName)
|
||||
{
|
||||
DirectoryInfo di = new DirectoryInfo(DirectoryName);
|
||||
List<FileInfo> dllfiles = di.GetFiles("*ConversionSyntaxExternal.dll").ToList(); // Это только YieldConversionSyntax.dll
|
||||
//List<FileInfo> standartdllfile = di.GetFiles("StandardSyntaxTreeConverter.dll").ToList();
|
||||
//if (standartdllfile.Count>0)
|
||||
// dllfiles.Insert(0, standartdllfile[0]);
|
||||
//dllfiles.Insert(0,new FileInfo("StandardSyntaxTreeConverter.dll"));
|
||||
|
||||
System.Reflection.Assembly assembly = null;
|
||||
ISyntaxTreeConverter Converter;
|
||||
foreach (FileInfo fi in dllfiles)
|
||||
{
|
||||
try
|
||||
{
|
||||
assembly = System.Reflection.Assembly.LoadFile(fi.FullName);
|
||||
try
|
||||
{
|
||||
if (assembly != null)
|
||||
{
|
||||
Type[] types = assembly.GetTypes();
|
||||
foreach (Type type in types)
|
||||
{
|
||||
if (type.Name.IndexOf("SyntaxTreeConverter") >= 0 && type.IsClass)
|
||||
{
|
||||
Object obj = Activator.CreateInstance(type);
|
||||
if (obj is ISyntaxTreeConverter)
|
||||
{
|
||||
Converter = obj as ISyntaxTreeConverter;
|
||||
syntaxTreeConverters.Add(Converter);
|
||||
ChangeState(State.ConnectConverter, Converter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
//ErrorList.Add(new PluginLoadingError(fi.FullName, e));
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//если dll не нетовская
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public syntax_tree_node Convert(syntax_tree_node root)
|
||||
{
|
||||
foreach (ISyntaxTreeConverter SyntaxTreeConverter in syntaxTreeConverters)
|
||||
{
|
||||
ChangeState(State.Convert, SyntaxTreeConverter);
|
||||
root = SyntaxTreeConverter.Convert(root);
|
||||
}
|
||||
return root;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,100 +0,0 @@
|
|||
// 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)
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
*Интерфейс конвертора синтаксического дерева в семантическое для Compiler
|
||||
* Зависит от Errors, SemanticTree, PascalABCCompiler.SyntaxTree
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Languages.Facade;
|
||||
using PascalABCCompiler.TreeConverter.TreeConversion;
|
||||
using System.Linq;
|
||||
|
||||
namespace PascalABCCompiler.TreeConverter
|
||||
{
|
||||
public class SyntaxTreeToSemanticTreeConverter
|
||||
{
|
||||
|
||||
private syntax_tree_visitor syntaxTreeVisitor;
|
||||
|
||||
public SyntaxTreeToSemanticTreeConverter()
|
||||
{
|
||||
|
||||
foreach (var language in LanguageProvider.Instance.Languages)
|
||||
{
|
||||
language.SetSyntaxTreeToSemanticTreeConverter();
|
||||
}
|
||||
|
||||
syntaxTreeVisitor = LanguageProvider.Instance.MainLanguage.SyntaxTreeToSemanticTreeConverter;
|
||||
|
||||
//(ssyy) запоминаем visitor
|
||||
SystemLibrary.SystemLibrary.syn_visitor = syntaxTreeVisitor;
|
||||
}
|
||||
|
||||
//TODO: Разобраться, где использутеся.
|
||||
public SymbolTable.TreeConverterSymbolTable SymbolTable
|
||||
{
|
||||
get
|
||||
{
|
||||
return syntaxTreeVisitor.SymbolTable;
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: Исправить коллекцию модулей.
|
||||
public TreeRealization.common_unit_node CompileInterface(ILanguage language, InitializationDataForCompilingInterface initializationData, List<TreeRealization.var_definition_node> CompiledVariables)
|
||||
{
|
||||
syntaxTreeVisitor = language.SyntaxTreeToSemanticTreeConverter;
|
||||
|
||||
syntaxTreeVisitor.InitializeForCompilingInterface(initializationData);
|
||||
|
||||
language.SetSemanticConstants();
|
||||
|
||||
foreach (SyntaxTree.compiler_directive cd in initializationData.syntaxUnit.compiler_directives)
|
||||
syntaxTreeVisitor.ProcessNode(cd);
|
||||
|
||||
syntaxTreeVisitor.DirectivesToNodesLinks = CompilerDirectivesToSyntaxTreeNodesLinker.BuildLinks(initializationData.syntaxUnit, initializationData.errorsList); //MikhailoMMX добавил передачу списка ошибок (02.10.10)
|
||||
|
||||
syntaxTreeVisitor.BeforeCompilationActions();
|
||||
|
||||
syntaxTreeVisitor.ProcessNode(initializationData.syntaxUnit);
|
||||
|
||||
syntaxTreeVisitor.PostCompilationActions();
|
||||
|
||||
CompiledVariables.AddRange(syntaxTreeVisitor.CompiledVariables);
|
||||
|
||||
return syntaxTreeVisitor.CompiledUnit;
|
||||
}
|
||||
|
||||
public void CompileImplementation(ILanguage language, InitializationDataForCompilingImplementation initializationData, List<TreeRealization.var_definition_node> CompiledVariables)
|
||||
{
|
||||
syntaxTreeVisitor = language.SyntaxTreeToSemanticTreeConverter;
|
||||
|
||||
syntaxTreeVisitor.InitializeForCompilingImplementation(initializationData);
|
||||
|
||||
language.SetSemanticConstants();
|
||||
|
||||
foreach (SyntaxTree.compiler_directive cd in initializationData.syntaxUnit.compiler_directives)
|
||||
cd.visit(syntaxTreeVisitor);
|
||||
|
||||
syntaxTreeVisitor.BeforeCompilationActions();
|
||||
|
||||
syntaxTreeVisitor.visit_implementation(initializationData.syntaxUnit as SyntaxTree.unit_module);
|
||||
|
||||
syntaxTreeVisitor.PostCompilationActions();
|
||||
|
||||
CompiledVariables.AddRange(syntaxTreeVisitor.CompiledVariables);
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
foreach (var syntaxToSemanticTreeConverter in LanguageProvider.Instance.Languages.Select(language => language.SyntaxTreeToSemanticTreeConverter))
|
||||
{
|
||||
syntaxToSemanticTreeConverter.Reset();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Compiler/string_constants.cs
Normal file
11
Compiler/string_constants.cs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
// 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)
|
||||
namespace PascalABCCompiler
|
||||
{
|
||||
public class string_constants
|
||||
{
|
||||
public const string target_exe="exe";
|
||||
public const string target_dll="dll";
|
||||
public const string target_winexe="winexe";
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +1,121 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net40</TargetFramework>
|
||||
|
||||
<RootNamespace>PascalABCCompiler</RootNamespace>
|
||||
|
||||
<OutputPath>..\bin\</OutputPath>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.50727</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{A25D26FB-3043-4BCF-833E-E3F4C3BE795E}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>PAscalABCCompiler</RootNamespace>
|
||||
<AssemblyName>CompilerTools</AssemblyName>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<OldToolsVersion>4.0</OldToolsVersion>
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile />
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\bin\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\bin\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Conf\AssemblyInfo.cs" />
|
||||
<Compile Include="CRC32.cs" />
|
||||
<Compile Include="Errors\Errors.cs" />
|
||||
<Compile Include="Errors\ErrorsStrategy.cs" />
|
||||
<Compile Include="EventedStreamReaderList.cs" />
|
||||
<Compile Include="Tools.cs" />
|
||||
<Compile Include="..\Configuration\GlobalAssemblyInfo.cs">
|
||||
<Link>Conf\GlobalAssemblyInfo.cs</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Errors\Errors.csproj" />
|
||||
<ProjectReference Include="..\Localization\Localization.csproj" />
|
||||
<ProjectReference Include="..\SyntaxTree\SyntaxTree.csproj" />
|
||||
<ProjectReference Include="..\SemanticTree\SemanticTree.csproj" />
|
||||
<ProjectReference Include="..\Errors\Errors.csproj">
|
||||
<Project>{44A01F9E-DCE7-470C-AAE5-C3DE0CCBEE3B}</Project>
|
||||
<Name>Errors</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Localization\Localization.csproj">
|
||||
<Project>{2DE2842F-0912-4251-BC0F-480854C44A13}</Project>
|
||||
<Name>Localization</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\ParserTools\ParserTools.csproj">
|
||||
<Project>{AF2EFD7B-69DD-4B43-AF65-B59B29349C23}</Project>
|
||||
<Name>ParserTools</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SemanticTree\SemanticTree.csproj">
|
||||
<Project>{613E0DDA-AA8A-437C-AC45-507B47429FF9}</Project>
|
||||
<Name>SemanticTree</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SyntaxTree\SyntaxTree.csproj">
|
||||
<Project>{C2CAC65A-B2AE-4CCC-B067-E6B8E75DF73A}</Project>
|
||||
<Name>SyntaxTree</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Properties\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Клиентский профиль .NET Framework 3.5 SP1</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Установщик Windows 3.1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
72
CompilerTools/Errors/Errors.cs
Normal file
72
CompilerTools/Errors/Errors.cs
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
// 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 System;
|
||||
using System.IO;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
|
||||
namespace PascalABCCompiler.Errors
|
||||
{
|
||||
|
||||
public class SemanticError : LocatedError
|
||||
{
|
||||
public SemanticError(string Message, string fileName)
|
||||
: base(Message,fileName)
|
||||
{
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
public virtual SemanticTree.ILocation Location
|
||||
{
|
||||
get
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public SemanticError()
|
||||
{
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format(StringResources.Get("COMPILATIONERROR_UNDEFINED_SEMANTIC_ERROR{0}"), this.GetType().ToString());
|
||||
}
|
||||
public override SourceLocation SourceLocation
|
||||
{
|
||||
get
|
||||
{
|
||||
if (sourceLocation != null)
|
||||
return sourceLocation;
|
||||
if (Location != null)
|
||||
{
|
||||
return new SourceLocation(Location.document.file_name,
|
||||
Location.begin_line_num, Location.begin_column_num, Location.end_line_num, Location.end_column_num);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public override string Message
|
||||
{
|
||||
get
|
||||
{
|
||||
return (this.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class SemanticNonSupportedError : SemanticError
|
||||
{
|
||||
public SemanticNonSupportedError(string fileName)
|
||||
: base("", fileName)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
// 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 System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace PascalABCCompiler.Errors
|
||||
{
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ namespace PascalABCCompiler
|
|||
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch
|
||||
{
|
||||
Remove(so.Ident);
|
||||
}
|
||||
|
|
|
|||
17
CompilerTools/Properties/AssemblyInfo.cs
Normal file
17
CompilerTools/Properties/AssemblyInfo.cs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
// 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 System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[assembly: AssemblyTitle("PascalABCCompiler.CompilerTools")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Localization")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2005-2020 by Ivan Bondarev, Stanislav Mikhalkovich")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
|
|
@ -20,11 +20,11 @@ namespace PascalABCCompiler
|
|||
sc.begin_position.line_num, sc.begin_position.column_num,
|
||||
sc.end_position.line_num, sc.end_position.column_num);
|
||||
}
|
||||
public static string ReplaceAllKeys(string str, Dictionary<string, string> hashtable)
|
||||
public static string ReplaceAllKeys(string str, Hashtable hashtable)
|
||||
{
|
||||
foreach (string key in hashtable.Keys)
|
||||
if (hashtable[key] != null)
|
||||
str = str.Replace(key, hashtable[key]);
|
||||
str = str.Replace(key, hashtable[key].ToString());
|
||||
return str;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ using System.Runtime.CompilerServices;
|
|||
[assembly: AssemblyDelaySign(false)]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("PascalABC.NET Compiler")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2005-2025 by Ivan Bondarev, Stanislav Mihalkovich")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2005-2019 by Ivan Bondarev, Stanislav Mihalkovich")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: AssemblyVersion(RevisionClass.FullVersion)]
|
||||
|
|
@ -13,9 +13,9 @@ using System.Runtime.CompilerServices;
|
|||
internal static class RevisionClass
|
||||
{
|
||||
public const string Major = "3";
|
||||
public const string Minor = "11";
|
||||
public const string Build = "1";
|
||||
public const string Revision = "3835";
|
||||
public const string Minor = "6";
|
||||
public const string Build = "2";
|
||||
public const string Revision = "2440";
|
||||
|
||||
public const string MainVersion = Major + "." + Minor;
|
||||
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ using System.Runtime.CompilerServices;
|
|||
[assembly: AssemblyDelaySign(false)]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("PascalABC.NET Compiler")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2005-2025 by Ivan Bondarev, Stanislav Mihalkovich")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2005-2019 by Ivan Bondarev, Stanislav Mihalkovich")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: AssemblyVersion(RevisionClass.FullVersion)]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
%MINOR%=11
|
||||
%REVISION%=3835
|
||||
%COREVERSION%=1
|
||||
%COREVERSION%=2
|
||||
%REVISION%=2440
|
||||
%MINOR%=6
|
||||
%MAJOR%=3
|
||||
|
|
|
|||
|
|
@ -1,186 +0,0 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace PascalABCCompiler.CoreUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// Class that can open text files with auto-detection of the encoding.
|
||||
/// </summary>
|
||||
public static class FileReader
|
||||
{
|
||||
public static bool IsUnicode(Encoding encoding)
|
||||
{
|
||||
int codepage = encoding.CodePage;
|
||||
// return true if codepage is any UTF codepage
|
||||
return codepage == 65001 || codepage == 65000 || codepage == 1200 || codepage == 1201;
|
||||
}
|
||||
|
||||
public static string ReadFileContent(Stream fs, ref Encoding encoding)
|
||||
{
|
||||
using (StreamReader reader = OpenStream(fs, encoding))
|
||||
{
|
||||
reader.Peek();
|
||||
encoding = reader.CurrentEncoding;
|
||||
return reader.ReadToEnd();
|
||||
}
|
||||
}
|
||||
|
||||
public static string ReadFileContent(string fileName, Encoding encoding)
|
||||
{
|
||||
if (encoding == null)
|
||||
encoding = System.Text.Encoding.GetEncoding(1251);
|
||||
using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||
{
|
||||
return ReadFileContent(fs, ref encoding);
|
||||
}
|
||||
}
|
||||
|
||||
public static StreamReader OpenStream(Stream fs, Encoding defaultEncoding)
|
||||
{
|
||||
if (fs == null)
|
||||
throw new ArgumentNullException("fs");
|
||||
|
||||
if (fs.Length >= 2)
|
||||
{
|
||||
// the autodetection of StreamReader is not capable of detecting the difference
|
||||
// between ISO-8859-1 and UTF-8 without BOM.
|
||||
int firstByte = fs.ReadByte();
|
||||
int secondByte = fs.ReadByte();
|
||||
switch ((firstByte << 8) | secondByte)
|
||||
{
|
||||
case 0x0000: // either UTF-32 Big Endian or a binary file; use StreamReader
|
||||
case 0xfffe: // Unicode BOM (UTF-16 LE or UTF-32 LE)
|
||||
case 0xfeff: // UTF-16 BE BOM
|
||||
case 0xefbb: // start of UTF-8 BOM
|
||||
// StreamReader autodetection works
|
||||
fs.Position = 0;
|
||||
return new StreamReader(fs);
|
||||
default:
|
||||
return AutoDetect(fs, (byte)firstByte, (byte)secondByte, defaultEncoding);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (defaultEncoding != null)
|
||||
{
|
||||
return new StreamReader(fs, defaultEncoding);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new StreamReader(fs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static StreamReader AutoDetect(Stream fs, byte firstByte, byte secondByte, Encoding defaultEncoding)
|
||||
{
|
||||
int max = (int)Math.Min(fs.Length, 500000); // look at max. 500 KB
|
||||
const int ASCII = 0;
|
||||
const int Error = 1;
|
||||
const int UTF8 = 2;
|
||||
const int UTF8Sequence = 3;
|
||||
int state = ASCII;
|
||||
int sequenceLength = 0;
|
||||
byte b;
|
||||
for (int i = 0; i < max; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
b = firstByte;
|
||||
}
|
||||
else if (i == 1)
|
||||
{
|
||||
b = secondByte;
|
||||
}
|
||||
else
|
||||
{
|
||||
b = (byte)fs.ReadByte();
|
||||
}
|
||||
if (b < 0x80)
|
||||
{
|
||||
// normal ASCII character
|
||||
if (state == UTF8Sequence)
|
||||
{
|
||||
state = Error;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (b < 0xc0)
|
||||
{
|
||||
// 10xxxxxx : continues UTF8 byte sequence
|
||||
if (state == UTF8Sequence)
|
||||
{
|
||||
--sequenceLength;
|
||||
if (sequenceLength < 0)
|
||||
{
|
||||
state = Error;
|
||||
break;
|
||||
}
|
||||
else if (sequenceLength == 0)
|
||||
{
|
||||
state = UTF8;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
state = Error;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (b >= 0xc2 && b < 0xf5)
|
||||
{
|
||||
// beginning of byte sequence
|
||||
if (state == UTF8 || state == ASCII)
|
||||
{
|
||||
state = UTF8Sequence;
|
||||
if (b < 0xe0)
|
||||
{
|
||||
sequenceLength = 1; // one more byte following
|
||||
}
|
||||
else if (b < 0xf0)
|
||||
{
|
||||
sequenceLength = 2; // two more bytes following
|
||||
}
|
||||
else
|
||||
{
|
||||
sequenceLength = 3; // three more bytes following
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
state = Error;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 0xc0, 0xc1, 0xf5 to 0xff are invalid in UTF-8 (see RFC 3629)
|
||||
state = Error;
|
||||
break;
|
||||
}
|
||||
}
|
||||
fs.Position = 0;
|
||||
switch (state)
|
||||
{
|
||||
case ASCII:
|
||||
case Error:
|
||||
// when the file seems to be ASCII or non-UTF8,
|
||||
// we read it using the user-specified encoding so it is saved again
|
||||
// using that encoding.
|
||||
if (IsUnicode(defaultEncoding))
|
||||
{
|
||||
// the file is not Unicode, so don't read it using Unicode even if the
|
||||
// user has choosen Unicode as the default encoding.
|
||||
|
||||
// If we don't do this, SD will end up always adding a Byte Order Mark
|
||||
// to ASCII files.
|
||||
defaultEncoding = Encoding.Default; // use system encoding instead
|
||||
}
|
||||
return new StreamReader(fs, defaultEncoding);
|
||||
default:
|
||||
return new StreamReader(fs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue