3.10.3
faststrings EmptyCollection и преобразование ее в List, Dictionary t: (real,real) := (1,2)
This commit is contained in:
parent
bba132bd5d
commit
8fbd7fdfc3
|
|
@ -14,8 +14,8 @@ internal static class RevisionClass
|
||||||
{
|
{
|
||||||
public const string Major = "3";
|
public const string Major = "3";
|
||||||
public const string Minor = "10";
|
public const string Minor = "10";
|
||||||
public const string Build = "2";
|
public const string Build = "3";
|
||||||
public const string Revision = "3597";
|
public const string Revision = "3602";
|
||||||
|
|
||||||
public const string MainVersion = Major + "." + Minor;
|
public const string MainVersion = Major + "." + Minor;
|
||||||
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;
|
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
|
%COREVERSION%=3
|
||||||
|
%REVISION%=3602
|
||||||
%MINOR%=10
|
%MINOR%=10
|
||||||
%REVISION%=3597
|
|
||||||
%COREVERSION%=2
|
|
||||||
%MAJOR%=3
|
%MAJOR%=3
|
||||||
|
|
|
||||||
14
InstallerSamples/WhatsNew/3_10_3/faststring1.pas
Normal file
14
InstallerSamples/WhatsNew/3_10_3/faststring1.pas
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
// 6.0 sec PascalABC.NET vs 11.4 sec Python
|
||||||
|
begin
|
||||||
|
var mx := 0;
|
||||||
|
for var n := 4 to 9999 do
|
||||||
|
begin
|
||||||
|
var s: faststring := '4' + '1' * n;
|
||||||
|
|
||||||
|
while ('411' in s) or ('1111' in s) do
|
||||||
|
s.Replace('411', '14', 1).Replace('1111', '1', 1);
|
||||||
|
|
||||||
|
mx := max(mx, s.ToString.Sum(d -> d.todigit));
|
||||||
|
end;
|
||||||
|
print(mx, Milliseconds / 1000);
|
||||||
|
end.
|
||||||
|
|
@ -1 +1 @@
|
||||||
3.10.2.3597
|
3.10.3.3602
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
!define VERSION '3.10.2.3597'
|
!define VERSION '3.10.3.3602'
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@ using System.Text;
|
||||||
|
|
||||||
namespace PascalABCCompiler.SyntaxTree
|
namespace PascalABCCompiler.SyntaxTree
|
||||||
{
|
{
|
||||||
|
// По идее из разных мест сюда всё собрано в три разных хаотичных класса
|
||||||
|
|
||||||
#region Генерация новых узлов синтаксического дерева
|
#region Генерация новых узлов синтаксического дерева
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Класс для генерации новых узлов синтаксического дерева
|
/// Класс для генерации новых узлов синтаксического дерева
|
||||||
|
|
@ -295,11 +297,11 @@ namespace PascalABCCompiler.SyntaxTree
|
||||||
private static procedure_definition InternalCreateProcedureDefinitionNode(string methName, formal_parameters formalPars, bool classKeyword, statement procBody, SourceContext sc)
|
private static procedure_definition InternalCreateProcedureDefinitionNode(string methName, formal_parameters formalPars, bool classKeyword, statement procBody, SourceContext sc)
|
||||||
{
|
{
|
||||||
return SyntaxTreeNodesConstructor.CreateProcedureDefinitionNode(new method_name(methName),
|
return SyntaxTreeNodesConstructor.CreateProcedureDefinitionNode(new method_name(methName),
|
||||||
formalPars,
|
formalPars,
|
||||||
false,
|
false,
|
||||||
classKeyword,
|
classKeyword,
|
||||||
procBody,
|
procBody,
|
||||||
sc);
|
sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static procedure_definition CreateProcedureDefinitionNode(string methName, formal_parameters formalPars, bool classKeyword, statement procBody, SourceContext sc)
|
public static procedure_definition CreateProcedureDefinitionNode(string methName, formal_parameters formalPars, bool classKeyword, statement procBody, SourceContext sc)
|
||||||
|
|
@ -315,12 +317,12 @@ namespace PascalABCCompiler.SyntaxTree
|
||||||
private static procedure_definition InternalCreateFunctionDefinitionNode(string methName, formal_parameters formalPars, bool classKeyword, statement procBody, type_definition returnType, SourceContext sc)
|
private static procedure_definition InternalCreateFunctionDefinitionNode(string methName, formal_parameters formalPars, bool classKeyword, statement procBody, type_definition returnType, SourceContext sc)
|
||||||
{
|
{
|
||||||
return SyntaxTreeNodesConstructor.CreateFunctionDefinitionNode(new method_name(methName),
|
return SyntaxTreeNodesConstructor.CreateFunctionDefinitionNode(new method_name(methName),
|
||||||
formalPars,
|
formalPars,
|
||||||
false,
|
false,
|
||||||
classKeyword,
|
classKeyword,
|
||||||
procBody,
|
procBody,
|
||||||
returnType,
|
returnType,
|
||||||
sc);
|
sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static procedure_definition CreateFunctionDefinitionNode(string methName, formal_parameters formalPars, bool classKeyword, statement procBody, type_definition returnType, SourceContext sc)
|
public static procedure_definition CreateFunctionDefinitionNode(string methName, formal_parameters formalPars, bool classKeyword, statement procBody, type_definition returnType, SourceContext sc)
|
||||||
|
|
@ -355,10 +357,14 @@ namespace PascalABCCompiler.SyntaxTree
|
||||||
public static SourceContext BuildGenSC = new SourceContext(0, 777777, 0, 0, 0, 0);
|
public static SourceContext BuildGenSC = new SourceContext(0, 777777, 0, 0, 0, 0);
|
||||||
|
|
||||||
private static int GenIdNum = 0;
|
private static int GenIdNum = 0;
|
||||||
public static ident GenIdentName()
|
public static string UniqueString()
|
||||||
{
|
{
|
||||||
GenIdNum++;
|
GenIdNum++;
|
||||||
return new ident("$GenId" + GenIdNum.ToString());
|
return GenIdNum.ToString();
|
||||||
|
}
|
||||||
|
public static ident GenIdentName()
|
||||||
|
{
|
||||||
|
return new ident("$GenId" + UniqueString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static type_definition BuildSimpleType(string name)
|
public static type_definition BuildSimpleType(string name)
|
||||||
|
|
@ -420,6 +426,23 @@ namespace PascalABCCompiler.SyntaxTree
|
||||||
return sl;
|
return sl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SSM 25.01.25
|
||||||
|
public static procedure_definition BuildSimpleFunction(string name, List<ident> paramNames, List<type_definition> paramTypes, type_definition returnType, statement procBody, SourceContext sc = null)
|
||||||
|
{
|
||||||
|
var fp = SyntaxTreeBuilder.BuildFormalParameters(paramNames, paramTypes);
|
||||||
|
var fdn = SyntaxTreeNodesConstructor.CreateFunctionDefinitionNode(new method_name(name), fp, false, false, procBody, returnType, sc);
|
||||||
|
return fdn;
|
||||||
|
}
|
||||||
|
public static procedure_definition BuildSimpleFunctionOneParameter(string name, string paramName, type_definition paramType, type_definition returnType, statement procBody, SourceContext sc = null)
|
||||||
|
{
|
||||||
|
var lstNames = new List<ident>();
|
||||||
|
lstNames.Add(new ident(paramName));
|
||||||
|
var lstTypes = new List<type_definition>();
|
||||||
|
lstTypes.Add(paramType);
|
||||||
|
var fp = SyntaxTreeBuilder.BuildFormalParameters(lstNames, lstTypes);
|
||||||
|
var fdn = SyntaxTreeNodesConstructor.CreateFunctionDefinitionNode(new method_name(name), fp, false, false, procBody, returnType, sc);
|
||||||
|
return fdn;
|
||||||
|
}
|
||||||
public static procedure_definition BuildSimpleConstructor(List<ident> fields, List<ident> formal_names, List<type_definition> types)
|
public static procedure_definition BuildSimpleConstructor(List<ident> fields, List<ident> formal_names, List<type_definition> types)
|
||||||
{
|
{
|
||||||
var fp = SyntaxTreeBuilder.BuildFormalParameters(formal_names, types);
|
var fp = SyntaxTreeBuilder.BuildFormalParameters(formal_names, types);
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ type
|
||||||
|
|
||||||
/// Представляет произвольно большое целое число
|
/// Представляет произвольно большое целое число
|
||||||
BigInteger = System.Numerics.BigInteger;
|
BigInteger = System.Numerics.BigInteger;
|
||||||
|
|
||||||
/// Представляет дату и время
|
/// Представляет дату и время
|
||||||
DateTime = System.DateTime;
|
DateTime = System.DateTime;
|
||||||
|
|
||||||
|
|
@ -181,6 +181,9 @@ type
|
||||||
/// Представляет изменяемую строку символов
|
/// Представляет изменяемую строку символов
|
||||||
StringBuilder = System.Text.StringBuilder;
|
StringBuilder = System.Text.StringBuilder;
|
||||||
|
|
||||||
|
/// Представляет строку с эффективным изменением
|
||||||
|
faststring = StringBuilder;
|
||||||
|
|
||||||
/// Тип кодировки символов
|
/// Тип кодировки символов
|
||||||
Encoding = System.Text.Encoding;
|
Encoding = System.Text.Encoding;
|
||||||
|
|
||||||
|
|
@ -483,7 +486,7 @@ type
|
||||||
end;}
|
end;}
|
||||||
|
|
||||||
type
|
type
|
||||||
NewSetEmpty = class;
|
EmptyCollection = class;
|
||||||
|
|
||||||
/// Тип встроенного множества
|
/// Тип встроенного множества
|
||||||
NewSet<T> = record(IEnumerable<T>)
|
NewSet<T> = record(IEnumerable<T>)
|
||||||
|
|
@ -558,66 +561,77 @@ type
|
||||||
begin
|
begin
|
||||||
Result._hs := new HashSet<T>(a);
|
Result._hs := new HashSet<T>(a);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
static function operator implicit(ns: NewSetEmpty): NewSet<T>; begin end;
|
|
||||||
static function operator:=(var s: NewSet<T>; st: NewSet<T>): NewSet<T>; // Эту функцию обязательно здесь определять
|
static function operator:=(var s: NewSet<T>; st: NewSet<T>): NewSet<T>; // Эту функцию обязательно здесь определять
|
||||||
begin
|
begin
|
||||||
s._hs := new HashSet<T>(st.hs);
|
s._hs := new HashSet<T>(st.hs);
|
||||||
end;
|
end;
|
||||||
|
static function operator implicit(ns: EmptyCollection): NewSet<T>; begin end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
NewSetEmpty = class
|
EmptyCollection = class
|
||||||
public
|
public
|
||||||
static function operator=<T>(s1: NewSet<T>; s2: NewSetEmpty): boolean := s1.Count = 0;
|
static function operator=<T>(s1: NewSet<T>; s2: EmptyCollection): boolean := s1.Count = 0;
|
||||||
static function operator=<T>(s2: NewSetEmpty; s1: NewSet<T>): boolean := s1.Count = 0;
|
static function operator=<T>(s2: EmptyCollection; s1: NewSet<T>): boolean := s1.Count = 0;
|
||||||
static function operator<><T>(s1: NewSet<T>; s2: NewSetEmpty): boolean := not (s1 = s2);
|
static function operator<><T>(s1: NewSet<T>; s2: EmptyCollection): boolean := not (s1 = s2);
|
||||||
static function operator<><T>(s2: NewSetEmpty; s1: NewSet<T>): boolean := not (s1 = s2);
|
static function operator<><T>(s2: EmptyCollection; s1: NewSet<T>): boolean := not (s1 = s2);
|
||||||
static function operator><T>(s1: NewSet<T>; s2: NewSetEmpty): boolean := s1.Count > 0;
|
static function operator><T>(s1: NewSet<T>; s2: EmptyCollection): boolean := s1.Count > 0;
|
||||||
static function operator><T>(s2: NewSetEmpty; s1: NewSet<T>): boolean := False;
|
static function operator><T>(s2: EmptyCollection; s1: NewSet<T>): boolean := False;
|
||||||
static function operator<<T>(s1: NewSet<T>; s2: NewSetEmpty): boolean := False;
|
static function operator<<T>(s1: NewSet<T>; s2: EmptyCollection): boolean := False;
|
||||||
static function operator<<T>(s2: NewSetEmpty; s1: NewSet<T>): boolean := s1.Count > 0;
|
static function operator<<T>(s2: EmptyCollection; s1: NewSet<T>): boolean := s1.Count > 0;
|
||||||
static function operator>=<T>(s1: NewSet<T>; s2: NewSetEmpty): boolean := s1.Count >= 0;
|
static function operator>=<T>(s1: NewSet<T>; s2: EmptyCollection): boolean := s1.Count >= 0;
|
||||||
static function operator>=<T>(s2: NewSetEmpty; s1: NewSet<T>): boolean := False;
|
static function operator>=<T>(s2: EmptyCollection; s1: NewSet<T>): boolean := False;
|
||||||
static function operator<=<T>(s1: NewSet<T>; s2: NewSetEmpty): boolean := False;
|
static function operator<=<T>(s1: NewSet<T>; s2: EmptyCollection): boolean := False;
|
||||||
static function operator<=<T>(s2: NewSetEmpty; s1: NewSet<T>): boolean := s1.Count >= 0;
|
static function operator<=<T>(s2: EmptyCollection; s1: NewSet<T>): boolean := s1.Count >= 0;
|
||||||
// ToDo: определить то же для массивов на будущее
|
// ToDo: определить то же для массивов на будущее
|
||||||
|
|
||||||
static function operator+(first, second: NewSetEmpty): NewSetEmpty := new NewSetEmpty;
|
static function operator+(first, second: EmptyCollection): EmptyCollection := new EmptyCollection;
|
||||||
static function operator-(first, second: NewSetEmpty): NewSetEmpty := new NewSetEmpty;
|
static function operator-(first, second: EmptyCollection): EmptyCollection := new EmptyCollection;
|
||||||
static function operator*(first, second: NewSetEmpty): NewSetEmpty := new NewSetEmpty;
|
static function operator*(first, second: EmptyCollection): EmptyCollection := new EmptyCollection;
|
||||||
static function operator+<T>(first: NewSetEmpty; second: array of T): NewSet<T>;
|
static function operator+<T>(first: EmptyCollection; second: array of T): NewSet<T>;
|
||||||
begin
|
begin
|
||||||
Result.hs.UnionWith(second);
|
Result.hs.UnionWith(second);
|
||||||
end;
|
end;
|
||||||
static function operator+<T>(first: array of T; second: NewSetEmpty): NewSet<T>;
|
static function operator+<T>(first: array of T; second: EmptyCollection): NewSet<T>;
|
||||||
begin
|
begin
|
||||||
Result.hs.UnionWith(first);
|
Result.hs.UnionWith(first);
|
||||||
end;
|
end;
|
||||||
static function operator+<T>(first: NewSet<T>; second: NewSetEmpty): NewSet<T> := first;
|
static function operator+<T>(first: NewSet<T>; second: EmptyCollection): NewSet<T> := first;
|
||||||
static function operator+<T>(first: NewSetEmpty; second: NewSet<T>): NewSet<T> := second;
|
static function operator+<T>(first: EmptyCollection; second: NewSet<T>): NewSet<T> := second;
|
||||||
static function operator*<T>(first: NewSet<T>; second: NewSetEmpty): NewSet<T>; begin end;
|
static function operator*<T>(first: NewSet<T>; second: EmptyCollection): NewSet<T>; begin end;
|
||||||
static function operator*<T>(first: NewSetEmpty; second: NewSet<T>): NewSet<T>; begin end;
|
static function operator*<T>(first: EmptyCollection; second: NewSet<T>): NewSet<T>; begin end;
|
||||||
static function operator-<T>(first: NewSet<T>; second: NewSetEmpty): NewSet<T> := first;
|
static function operator-<T>(first: NewSet<T>; second: EmptyCollection): NewSet<T> := first;
|
||||||
static function operator-<T>(first: NewSetEmpty; second: NewSet<T>): NewSet<T>; begin end;
|
static function operator-<T>(first: EmptyCollection; second: NewSet<T>): NewSet<T>; begin end;
|
||||||
|
|
||||||
static function operator*<T>(first: NewSetEmpty; second: array of T): NewSet<T>; begin end;
|
static function operator*<T>(first: EmptyCollection; second: array of T): NewSet<T>; begin end;
|
||||||
static function operator*<T>(first: array of T; second: NewSetEmpty): NewSet<T>; begin end;
|
static function operator*<T>(first: array of T; second: EmptyCollection): NewSet<T>; begin end;
|
||||||
static function operator-<T>(first: NewSetEmpty; second: array of T): NewSet<T>; begin end;
|
static function operator-<T>(first: EmptyCollection; second: array of T): NewSet<T>; begin end;
|
||||||
static function operator-<T>(first: array of T; second: NewSetEmpty): NewSet<T>;
|
static function operator-<T>(first: array of T; second: EmptyCollection): NewSet<T>;
|
||||||
begin
|
begin
|
||||||
Result.hs.UnionWith(first);
|
Result.hs.UnionWith(first);
|
||||||
end;
|
end;
|
||||||
function ToString: string; override := '{}';
|
function ToString: string; override := '{}';
|
||||||
function ToSet<T>(): NewSet<T>; begin end;
|
function ToSet<T>(): NewSet<T>; begin end;
|
||||||
|
|
||||||
static function operator implicit<T>(Self: NewSetEmpty): array of T;
|
static function operator implicit<T>(Self: EmptyCollection): array of T;
|
||||||
begin
|
begin
|
||||||
Result := new T[0];
|
Result := new T[0]//System.Array.Empty&<T>;
|
||||||
end;
|
end;
|
||||||
static function operator implicit<T>(Self: NewSetEmpty): HashSet<T>;
|
static function operator implicit<T>(Self: EmptyCollection): HashSet<T>;
|
||||||
begin
|
begin
|
||||||
Result := new HashSet<T>;
|
Result := new HashSet<T>;
|
||||||
end;
|
end;
|
||||||
|
static function operator implicit<T>(Self: EmptyCollection): SortedSet<T>;
|
||||||
|
begin
|
||||||
|
Result := new SortedSet<T>;
|
||||||
|
end;
|
||||||
|
static function operator implicit<T>(Self: EmptyCollection): List<T>;
|
||||||
|
begin
|
||||||
|
Result := new List<T>;
|
||||||
|
end;
|
||||||
|
static function operator implicit<K,V>(Self: EmptyCollection): Dictionary<K,V>;
|
||||||
|
begin
|
||||||
|
Result := new Dictionary<K,V>;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
@ -667,7 +681,7 @@ type
|
||||||
end;
|
end;
|
||||||
|
|
||||||
/// Значение пустого множества
|
/// Значение пустого множества
|
||||||
function EmptySet: NewSetEmpty;
|
function EmptySet: EmptyCollection;
|
||||||
|
|
||||||
/// Генератор множества
|
/// Генератор множества
|
||||||
function __NewSetCreatorInternal<T>(params a: array of T): NewSet<T>;
|
function __NewSetCreatorInternal<T>(params a: array of T): NewSet<T>;
|
||||||
|
|
@ -14689,6 +14703,81 @@ begin
|
||||||
&to.IndexValue := Self.Count - &to.IndexValue + 1;
|
&to.IndexValue := Self.Count - &to.IndexValue + 1;
|
||||||
Result := SystemSliceStringImplQuestion(Self, situation, from.IndexValue, &to.IndexValue, step, 0);
|
Result := SystemSliceStringImplQuestion(Self, situation, from.IndexValue, &to.IndexValue, step, 0);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
//--------------------------------------------
|
||||||
|
//>> Методы расширения типа faststring (StringBuilder) # Extension methods for faststring (StringBuilder)
|
||||||
|
//--------------------------------------------
|
||||||
|
/// Возвращает индекс вхождения подстроки в быструю строку
|
||||||
|
function IndexOf(Self: faststring; subs: string; from: integer := 0): integer; extensionmethod;
|
||||||
|
begin
|
||||||
|
var lens := Self.Length;
|
||||||
|
var lens1 := subs.Length;
|
||||||
|
|
||||||
|
if (from < 0) or (lens1 > lens - from) then
|
||||||
|
begin
|
||||||
|
Result := -1;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if lens1 = 0 then
|
||||||
|
begin
|
||||||
|
Result := from;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
for var i := from to lens - lens1 do
|
||||||
|
begin
|
||||||
|
var found := True;
|
||||||
|
for var j := 0 to lens1 - 1 do
|
||||||
|
begin
|
||||||
|
if Self[i + j] <> subs[j + 1] then
|
||||||
|
begin
|
||||||
|
found := False;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if found then
|
||||||
|
begin
|
||||||
|
Result := i;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Result := -1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
/// Преобразует быструю строку в последовательность символов
|
||||||
|
function ToSequence(Self: faststring): sequence of char; extensionmethod;
|
||||||
|
begin
|
||||||
|
for var i:=0 to Self.Length - 1 do
|
||||||
|
yield Self[i];
|
||||||
|
end;
|
||||||
|
|
||||||
|
function operator in(subs: string; s: faststring): boolean; extensionmethod;
|
||||||
|
begin
|
||||||
|
Result := s.IndexOf(subs) <> -1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
/// Замещает n вхождений указанной строки на другую строку (все при n = 0)
|
||||||
|
function Replace(Self: faststring; OldValue, NewValue: string; n: integer): faststring; extensionmethod;
|
||||||
|
begin
|
||||||
|
if n = 0 then
|
||||||
|
Self.Replace(OldValue, NewValue) // стандартный метод StringBuilder
|
||||||
|
else begin
|
||||||
|
var from := 0;
|
||||||
|
loop n do
|
||||||
|
begin
|
||||||
|
var index := Self.IndexOf(OldValue, from);
|
||||||
|
if index = -1 then exit;
|
||||||
|
Self.Remove(index, OldValue.Length);
|
||||||
|
Self.Insert(index, NewValue);
|
||||||
|
from := index + NewValue.Length;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
Result := Self;
|
||||||
|
end;
|
||||||
|
|
||||||
//--------------------------------------------
|
//--------------------------------------------
|
||||||
//>> Методы расширения типа Func # Extension methods for Func
|
//>> Методы расширения типа Func # Extension methods for Func
|
||||||
//--------------------------------------------
|
//--------------------------------------------
|
||||||
|
|
@ -15415,7 +15504,7 @@ end;}
|
||||||
|
|
||||||
// Присваивание реализовано в PABCExtensions. Здесь не работает
|
// Присваивание реализовано в PABCExtensions. Здесь не работает
|
||||||
|
|
||||||
var _emptyset: NewSetEmpty := new NewSetEmpty;
|
var _emptyset: EmptyCollection := new EmptyCollection;
|
||||||
|
|
||||||
type
|
type
|
||||||
SetCreatorFunctionAttribute = class(Attribute)
|
SetCreatorFunctionAttribute = class(Attribute)
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,9 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
using PascalABCCompiler.SemanticTree;
|
using PascalABCCompiler.SemanticTree;
|
||||||
|
using PascalABCCompiler.SyntaxTree;
|
||||||
using PascalABCCompiler.TreeRealization;
|
using PascalABCCompiler.TreeRealization;
|
||||||
|
using static PascalABCCompiler.SyntaxTree.SyntaxTreeBuilder;
|
||||||
|
|
||||||
namespace PascalABCCompiler.TreeConverter
|
namespace PascalABCCompiler.TreeConverter
|
||||||
{
|
{
|
||||||
|
|
@ -1208,36 +1210,56 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// SSM 20/01/25 - Tuple<int,int> -> Tuple<double,double>
|
// SSM 20/01/25 - Tuple<int,int> -> Tuple<double,double>
|
||||||
/*if (formal_param_type.original_generic != null
|
if (formal_param_type.original_generic != null
|
||||||
&& formal_param_type.original_generic.BaseFullName.StartsWith("System.Tuple`")
|
&& formal_param_type.original_generic.BaseFullName.StartsWith("System.Tuple`")
|
||||||
&& factparams[i].type.original_generic != null
|
&& factparams[i].type.original_generic != null
|
||||||
&& factparams[i].type.original_generic.BaseFullName.StartsWith("System.Tuple`")
|
&& factparams[i].type.original_generic.BaseFullName.StartsWith("System.Tuple`")
|
||||||
&& formal_param_type.instance_params.Count == factparams[i].type.instance_params.Count
|
&& formal_param_type.instance_params.Count == factparams[i].type.instance_params.Count
|
||||||
&& factparams[i] is IFunctionCallNode fpf
|
//&& factparams[i] is IFunctionCallNode fpf
|
||||||
&& fpf.function.name == "Create")
|
//&& fpf.function.name == "Create"
|
||||||
|
)
|
||||||
{
|
{
|
||||||
expressions_list el = null;
|
syntax_tree_visitor.contextChanger.SaveContextAndUpToGlobalLevel();
|
||||||
function_node fn = null;
|
var sl = new statement_list();
|
||||||
if (fpf is common_static_method_call fpf1) {
|
var rettype = new semantic_type_node(formal_param_type);
|
||||||
el = fpf1.parameters;
|
|
||||||
fn = fpf1.function_node;
|
//expressions_list parameters = null;
|
||||||
}
|
//if (fpf is common_static_method_call fpf1) {
|
||||||
else if (fpf is compiled_static_method_call fpf2) {
|
// parameters = fpf1.parameters;
|
||||||
el = fpf2.parameters;
|
//}
|
||||||
fn = fpf2.function_node;
|
//else if (fpf is compiled_static_method_call fpf2) {
|
||||||
}
|
// parameters = fpf2.parameters;
|
||||||
var ccc = syntax_tree_visitor.create_constructor_call(formal_param_type,
|
//}
|
||||||
el, factparams[i].location);
|
|
||||||
|
var el = new expression_list();
|
||||||
|
for (int ii = 1; ii <= formal_param_type.instance_params.Count; ii++)
|
||||||
|
el.Add(new dot_node(new ident("x"), new ident("Item" + ii.ToString(),
|
||||||
|
factparams[i].location)));
|
||||||
|
//parameters[ii-1].location)));
|
||||||
|
SyntaxTree.expression ex = new SyntaxTree.new_expr(rettype,el);
|
||||||
|
sl.Add(new SyntaxTree.assign("Result", ex));
|
||||||
|
// Определим функцию преобразования на внешнем уровне
|
||||||
|
var fun = BuildSimpleFunctionOneParameter("_conv" + UniqueString(), "x",
|
||||||
|
new SyntaxTree.semantic_type_node(factparams[i].type),
|
||||||
|
rettype,
|
||||||
|
sl
|
||||||
|
);
|
||||||
|
// Теперь ее надо обойти
|
||||||
|
syntax_tree_visitor.ProcessNode(fun);
|
||||||
|
// Теперь до нее доберемся
|
||||||
|
var fn = syntax_tree_visitor.context.last_created_function.sym_info as function_node;
|
||||||
|
syntax_tree_visitor.contextChanger.RestoreCurrentContext();
|
||||||
|
//var ccc = syntax_tree_visitor.create_constructor_call(formal_param_type,
|
||||||
|
// el, factparams[i].location);
|
||||||
//factparams[i] = ccc;
|
//factparams[i] = ccc;
|
||||||
possible_type_convertions ptci = new possible_type_convertions();
|
possible_type_convertions ptci = new possible_type_convertions();
|
||||||
var ttttt = (ccc as compiled_constructor_call).function_node;
|
ptci.first = new type_conversion(fn);
|
||||||
ptci.first = new type_conversion(ttttt);
|
|
||||||
ptci.second = null;
|
ptci.second = null;
|
||||||
ptci.from = factparams[i].type;
|
ptci.from = factparams[i].type;
|
||||||
ptci.to = formal_param_type;
|
ptci.to = formal_param_type;
|
||||||
tc.AddElement(ptci);
|
tc.AddElement(ptci);
|
||||||
return tc;
|
return tc;
|
||||||
}*/
|
}
|
||||||
|
|
||||||
//issue #2161 - SSM 12.03.2020
|
//issue #2161 - SSM 12.03.2020
|
||||||
//issue #348
|
//issue #348
|
||||||
|
|
|
||||||
|
|
@ -15460,7 +15460,7 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
{
|
{
|
||||||
// Отдельно для пустого множества
|
// Отдельно для пустого множества
|
||||||
common_namespace_function_call cnfc = expr as common_namespace_function_call;
|
common_namespace_function_call cnfc = expr as common_namespace_function_call;
|
||||||
if (cnfc.type.name == "NewSetEmpty")
|
if (cnfc.type.name == "EmptyCollection")
|
||||||
{
|
{
|
||||||
constant = new common_namespace_function_call_as_constant(expr as common_namespace_function_call, loc);
|
constant = new common_namespace_function_call_as_constant(expr as common_namespace_function_call, loc);
|
||||||
return constant;
|
return constant;
|
||||||
|
|
@ -15475,7 +15475,7 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
return constant;
|
return constant;
|
||||||
}
|
}
|
||||||
else if (expr is common_namespace_function_call_as_constant cnfcac
|
else if (expr is common_namespace_function_call_as_constant cnfcac
|
||||||
&& cnfcac.type.name == "NewSetEmpty")
|
&& cnfcac.type.name == "EmptyCollection")
|
||||||
{
|
{
|
||||||
expr = create_constructor_call(tn, new expressions_list(), loc);
|
expr = create_constructor_call(tn, new expressions_list(), loc);
|
||||||
constant = new common_constructor_call_as_constant(expr as common_constructor_call, loc);
|
constant = new common_constructor_call_as_constant(expr as common_constructor_call, loc);
|
||||||
|
|
|
||||||
|
|
@ -235,6 +235,7 @@
|
||||||
<Key word = "word" />
|
<Key word = "word" />
|
||||||
<Key word = "integer" />
|
<Key word = "integer" />
|
||||||
<Key word = "BigInteger" />
|
<Key word = "BigInteger" />
|
||||||
|
<Key word = "Complex" />
|
||||||
<Key word = "longword" />
|
<Key word = "longword" />
|
||||||
<Key word = "uint64" />
|
<Key word = "uint64" />
|
||||||
<Key word = "cardinal" />
|
<Key word = "cardinal" />
|
||||||
|
|
@ -242,6 +243,7 @@
|
||||||
<Key word = "single" />
|
<Key word = "single" />
|
||||||
<Key word = "longint" />
|
<Key word = "longint" />
|
||||||
<Key word = "string" />
|
<Key word = "string" />
|
||||||
|
<Key word = "faststring" />
|
||||||
<Key word = "char" />
|
<Key word = "char" />
|
||||||
<Key word = "real" />
|
<Key word = "real" />
|
||||||
<Key word = "double" />
|
<Key word = "double" />
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ type
|
||||||
|
|
||||||
/// Представляет произвольно большое целое число
|
/// Представляет произвольно большое целое число
|
||||||
BigInteger = System.Numerics.BigInteger;
|
BigInteger = System.Numerics.BigInteger;
|
||||||
|
|
||||||
/// Представляет дату и время
|
/// Представляет дату и время
|
||||||
DateTime = System.DateTime;
|
DateTime = System.DateTime;
|
||||||
|
|
||||||
|
|
@ -181,6 +181,9 @@ type
|
||||||
/// Представляет изменяемую строку символов
|
/// Представляет изменяемую строку символов
|
||||||
StringBuilder = System.Text.StringBuilder;
|
StringBuilder = System.Text.StringBuilder;
|
||||||
|
|
||||||
|
/// Представляет строку с эффективным изменением
|
||||||
|
faststring = StringBuilder;
|
||||||
|
|
||||||
/// Тип кодировки символов
|
/// Тип кодировки символов
|
||||||
Encoding = System.Text.Encoding;
|
Encoding = System.Text.Encoding;
|
||||||
|
|
||||||
|
|
@ -483,7 +486,7 @@ type
|
||||||
end;}
|
end;}
|
||||||
|
|
||||||
type
|
type
|
||||||
NewSetEmpty = class;
|
EmptyCollection = class;
|
||||||
|
|
||||||
/// Тип встроенного множества
|
/// Тип встроенного множества
|
||||||
NewSet<T> = record(IEnumerable<T>)
|
NewSet<T> = record(IEnumerable<T>)
|
||||||
|
|
@ -558,66 +561,77 @@ type
|
||||||
begin
|
begin
|
||||||
Result._hs := new HashSet<T>(a);
|
Result._hs := new HashSet<T>(a);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
static function operator implicit(ns: NewSetEmpty): NewSet<T>; begin end;
|
|
||||||
static function operator:=(var s: NewSet<T>; st: NewSet<T>): NewSet<T>; // Эту функцию обязательно здесь определять
|
static function operator:=(var s: NewSet<T>; st: NewSet<T>): NewSet<T>; // Эту функцию обязательно здесь определять
|
||||||
begin
|
begin
|
||||||
s._hs := new HashSet<T>(st.hs);
|
s._hs := new HashSet<T>(st.hs);
|
||||||
end;
|
end;
|
||||||
|
static function operator implicit(ns: EmptyCollection): NewSet<T>; begin end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
NewSetEmpty = class
|
EmptyCollection = class
|
||||||
public
|
public
|
||||||
static function operator=<T>(s1: NewSet<T>; s2: NewSetEmpty): boolean := s1.Count = 0;
|
static function operator=<T>(s1: NewSet<T>; s2: EmptyCollection): boolean := s1.Count = 0;
|
||||||
static function operator=<T>(s2: NewSetEmpty; s1: NewSet<T>): boolean := s1.Count = 0;
|
static function operator=<T>(s2: EmptyCollection; s1: NewSet<T>): boolean := s1.Count = 0;
|
||||||
static function operator<><T>(s1: NewSet<T>; s2: NewSetEmpty): boolean := not (s1 = s2);
|
static function operator<><T>(s1: NewSet<T>; s2: EmptyCollection): boolean := not (s1 = s2);
|
||||||
static function operator<><T>(s2: NewSetEmpty; s1: NewSet<T>): boolean := not (s1 = s2);
|
static function operator<><T>(s2: EmptyCollection; s1: NewSet<T>): boolean := not (s1 = s2);
|
||||||
static function operator><T>(s1: NewSet<T>; s2: NewSetEmpty): boolean := s1.Count > 0;
|
static function operator><T>(s1: NewSet<T>; s2: EmptyCollection): boolean := s1.Count > 0;
|
||||||
static function operator><T>(s2: NewSetEmpty; s1: NewSet<T>): boolean := False;
|
static function operator><T>(s2: EmptyCollection; s1: NewSet<T>): boolean := False;
|
||||||
static function operator<<T>(s1: NewSet<T>; s2: NewSetEmpty): boolean := False;
|
static function operator<<T>(s1: NewSet<T>; s2: EmptyCollection): boolean := False;
|
||||||
static function operator<<T>(s2: NewSetEmpty; s1: NewSet<T>): boolean := s1.Count > 0;
|
static function operator<<T>(s2: EmptyCollection; s1: NewSet<T>): boolean := s1.Count > 0;
|
||||||
static function operator>=<T>(s1: NewSet<T>; s2: NewSetEmpty): boolean := s1.Count >= 0;
|
static function operator>=<T>(s1: NewSet<T>; s2: EmptyCollection): boolean := s1.Count >= 0;
|
||||||
static function operator>=<T>(s2: NewSetEmpty; s1: NewSet<T>): boolean := False;
|
static function operator>=<T>(s2: EmptyCollection; s1: NewSet<T>): boolean := False;
|
||||||
static function operator<=<T>(s1: NewSet<T>; s2: NewSetEmpty): boolean := False;
|
static function operator<=<T>(s1: NewSet<T>; s2: EmptyCollection): boolean := False;
|
||||||
static function operator<=<T>(s2: NewSetEmpty; s1: NewSet<T>): boolean := s1.Count >= 0;
|
static function operator<=<T>(s2: EmptyCollection; s1: NewSet<T>): boolean := s1.Count >= 0;
|
||||||
// ToDo: определить то же для массивов на будущее
|
// ToDo: определить то же для массивов на будущее
|
||||||
|
|
||||||
static function operator+(first, second: NewSetEmpty): NewSetEmpty := new NewSetEmpty;
|
static function operator+(first, second: EmptyCollection): EmptyCollection := new EmptyCollection;
|
||||||
static function operator-(first, second: NewSetEmpty): NewSetEmpty := new NewSetEmpty;
|
static function operator-(first, second: EmptyCollection): EmptyCollection := new EmptyCollection;
|
||||||
static function operator*(first, second: NewSetEmpty): NewSetEmpty := new NewSetEmpty;
|
static function operator*(first, second: EmptyCollection): EmptyCollection := new EmptyCollection;
|
||||||
static function operator+<T>(first: NewSetEmpty; second: array of T): NewSet<T>;
|
static function operator+<T>(first: EmptyCollection; second: array of T): NewSet<T>;
|
||||||
begin
|
begin
|
||||||
Result.hs.UnionWith(second);
|
Result.hs.UnionWith(second);
|
||||||
end;
|
end;
|
||||||
static function operator+<T>(first: array of T; second: NewSetEmpty): NewSet<T>;
|
static function operator+<T>(first: array of T; second: EmptyCollection): NewSet<T>;
|
||||||
begin
|
begin
|
||||||
Result.hs.UnionWith(first);
|
Result.hs.UnionWith(first);
|
||||||
end;
|
end;
|
||||||
static function operator+<T>(first: NewSet<T>; second: NewSetEmpty): NewSet<T> := first;
|
static function operator+<T>(first: NewSet<T>; second: EmptyCollection): NewSet<T> := first;
|
||||||
static function operator+<T>(first: NewSetEmpty; second: NewSet<T>): NewSet<T> := second;
|
static function operator+<T>(first: EmptyCollection; second: NewSet<T>): NewSet<T> := second;
|
||||||
static function operator*<T>(first: NewSet<T>; second: NewSetEmpty): NewSet<T>; begin end;
|
static function operator*<T>(first: NewSet<T>; second: EmptyCollection): NewSet<T>; begin end;
|
||||||
static function operator*<T>(first: NewSetEmpty; second: NewSet<T>): NewSet<T>; begin end;
|
static function operator*<T>(first: EmptyCollection; second: NewSet<T>): NewSet<T>; begin end;
|
||||||
static function operator-<T>(first: NewSet<T>; second: NewSetEmpty): NewSet<T> := first;
|
static function operator-<T>(first: NewSet<T>; second: EmptyCollection): NewSet<T> := first;
|
||||||
static function operator-<T>(first: NewSetEmpty; second: NewSet<T>): NewSet<T>; begin end;
|
static function operator-<T>(first: EmptyCollection; second: NewSet<T>): NewSet<T>; begin end;
|
||||||
|
|
||||||
static function operator*<T>(first: NewSetEmpty; second: array of T): NewSet<T>; begin end;
|
static function operator*<T>(first: EmptyCollection; second: array of T): NewSet<T>; begin end;
|
||||||
static function operator*<T>(first: array of T; second: NewSetEmpty): NewSet<T>; begin end;
|
static function operator*<T>(first: array of T; second: EmptyCollection): NewSet<T>; begin end;
|
||||||
static function operator-<T>(first: NewSetEmpty; second: array of T): NewSet<T>; begin end;
|
static function operator-<T>(first: EmptyCollection; second: array of T): NewSet<T>; begin end;
|
||||||
static function operator-<T>(first: array of T; second: NewSetEmpty): NewSet<T>;
|
static function operator-<T>(first: array of T; second: EmptyCollection): NewSet<T>;
|
||||||
begin
|
begin
|
||||||
Result.hs.UnionWith(first);
|
Result.hs.UnionWith(first);
|
||||||
end;
|
end;
|
||||||
function ToString: string; override := '{}';
|
function ToString: string; override := '{}';
|
||||||
function ToSet<T>(): NewSet<T>; begin end;
|
function ToSet<T>(): NewSet<T>; begin end;
|
||||||
|
|
||||||
static function operator implicit<T>(Self: NewSetEmpty): array of T;
|
static function operator implicit<T>(Self: EmptyCollection): array of T;
|
||||||
begin
|
begin
|
||||||
Result := new T[0];
|
Result := new T[0]//System.Array.Empty&<T>;
|
||||||
end;
|
end;
|
||||||
static function operator implicit<T>(Self: NewSetEmpty): HashSet<T>;
|
static function operator implicit<T>(Self: EmptyCollection): HashSet<T>;
|
||||||
begin
|
begin
|
||||||
Result := new HashSet<T>;
|
Result := new HashSet<T>;
|
||||||
end;
|
end;
|
||||||
|
static function operator implicit<T>(Self: EmptyCollection): SortedSet<T>;
|
||||||
|
begin
|
||||||
|
Result := new SortedSet<T>;
|
||||||
|
end;
|
||||||
|
static function operator implicit<T>(Self: EmptyCollection): List<T>;
|
||||||
|
begin
|
||||||
|
Result := new List<T>;
|
||||||
|
end;
|
||||||
|
static function operator implicit<K,V>(Self: EmptyCollection): Dictionary<K,V>;
|
||||||
|
begin
|
||||||
|
Result := new Dictionary<K,V>;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
@ -667,7 +681,7 @@ type
|
||||||
end;
|
end;
|
||||||
|
|
||||||
/// Значение пустого множества
|
/// Значение пустого множества
|
||||||
function EmptySet: NewSetEmpty;
|
function EmptySet: EmptyCollection;
|
||||||
|
|
||||||
/// Генератор множества
|
/// Генератор множества
|
||||||
function __NewSetCreatorInternal<T>(params a: array of T): NewSet<T>;
|
function __NewSetCreatorInternal<T>(params a: array of T): NewSet<T>;
|
||||||
|
|
@ -14689,6 +14703,81 @@ begin
|
||||||
&to.IndexValue := Self.Count - &to.IndexValue + 1;
|
&to.IndexValue := Self.Count - &to.IndexValue + 1;
|
||||||
Result := SystemSliceStringImplQuestion(Self, situation, from.IndexValue, &to.IndexValue, step, 0);
|
Result := SystemSliceStringImplQuestion(Self, situation, from.IndexValue, &to.IndexValue, step, 0);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
//--------------------------------------------
|
||||||
|
//>> Методы расширения типа faststring (StringBuilder) # Extension methods for faststring (StringBuilder)
|
||||||
|
//--------------------------------------------
|
||||||
|
/// Возвращает индекс вхождения подстроки в быструю строку
|
||||||
|
function IndexOf(Self: faststring; subs: string; from: integer := 0): integer; extensionmethod;
|
||||||
|
begin
|
||||||
|
var lens := Self.Length;
|
||||||
|
var lens1 := subs.Length;
|
||||||
|
|
||||||
|
if (from < 0) or (lens1 > lens - from) then
|
||||||
|
begin
|
||||||
|
Result := -1;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if lens1 = 0 then
|
||||||
|
begin
|
||||||
|
Result := from;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
for var i := from to lens - lens1 do
|
||||||
|
begin
|
||||||
|
var found := True;
|
||||||
|
for var j := 0 to lens1 - 1 do
|
||||||
|
begin
|
||||||
|
if Self[i + j] <> subs[j + 1] then
|
||||||
|
begin
|
||||||
|
found := False;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if found then
|
||||||
|
begin
|
||||||
|
Result := i;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Result := -1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
/// Преобразует быструю строку в последовательность символов
|
||||||
|
function ToSequence(Self: faststring): sequence of char; extensionmethod;
|
||||||
|
begin
|
||||||
|
for var i:=0 to Self.Length - 1 do
|
||||||
|
yield Self[i];
|
||||||
|
end;
|
||||||
|
|
||||||
|
function operator in(subs: string; s: faststring): boolean; extensionmethod;
|
||||||
|
begin
|
||||||
|
Result := s.IndexOf(subs) <> -1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
/// Замещает n вхождений указанной строки на другую строку (все при n = 0)
|
||||||
|
function Replace(Self: faststring; OldValue, NewValue: string; n: integer): faststring; extensionmethod;
|
||||||
|
begin
|
||||||
|
if n = 0 then
|
||||||
|
Self.Replace(OldValue, NewValue) // стандартный метод StringBuilder
|
||||||
|
else begin
|
||||||
|
var from := 0;
|
||||||
|
loop n do
|
||||||
|
begin
|
||||||
|
var index := Self.IndexOf(OldValue, from);
|
||||||
|
if index = -1 then exit;
|
||||||
|
Self.Remove(index, OldValue.Length);
|
||||||
|
Self.Insert(index, NewValue);
|
||||||
|
from := index + NewValue.Length;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
Result := Self;
|
||||||
|
end;
|
||||||
|
|
||||||
//--------------------------------------------
|
//--------------------------------------------
|
||||||
//>> Методы расширения типа Func # Extension methods for Func
|
//>> Методы расширения типа Func # Extension methods for Func
|
||||||
//--------------------------------------------
|
//--------------------------------------------
|
||||||
|
|
@ -15415,7 +15504,7 @@ end;}
|
||||||
|
|
||||||
// Присваивание реализовано в PABCExtensions. Здесь не работает
|
// Присваивание реализовано в PABCExtensions. Здесь не работает
|
||||||
|
|
||||||
var _emptyset: NewSetEmpty := new NewSetEmpty;
|
var _emptyset: EmptyCollection := new EmptyCollection;
|
||||||
|
|
||||||
type
|
type
|
||||||
SetCreatorFunctionAttribute = class(Attribute)
|
SetCreatorFunctionAttribute = class(Attribute)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue