diff --git a/Configuration/GlobalAssemblyInfo.cs b/Configuration/GlobalAssemblyInfo.cs index cb859df44..c9a5531fd 100644 --- a/Configuration/GlobalAssemblyInfo.cs +++ b/Configuration/GlobalAssemblyInfo.cs @@ -15,7 +15,7 @@ internal static class RevisionClass public const string Major = "3"; public const string Minor = "1"; public const string Build = "0"; - public const string Revision = "1170"; + public const string Revision = "1172"; public const string MainVersion = Major + "." + Minor; public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision; diff --git a/Configuration/Version.defs b/Configuration/Version.defs index 3438242e8..b81e0240f 100644 --- a/Configuration/Version.defs +++ b/Configuration/Version.defs @@ -1,4 +1,4 @@ %MINOR%=1 -%REVISION%=1170 +%REVISION%=1172 %COREVERSION%=0 %MAJOR%=3 diff --git a/Localization/DefaultLang.resources b/Localization/DefaultLang.resources index 97d5d5707..efd34e690 100644 Binary files a/Localization/DefaultLang.resources and b/Localization/DefaultLang.resources differ diff --git a/ReleaseGenerators/PascalABCNET_version.nsh b/ReleaseGenerators/PascalABCNET_version.nsh index e67921014..5f229d782 100644 --- a/ReleaseGenerators/PascalABCNET_version.nsh +++ b/ReleaseGenerators/PascalABCNET_version.nsh @@ -1 +1 @@ -!define VERSION '3.1.0.1170' +!define VERSION '3.1.0.1172' diff --git a/TestSuite/CompilationSamples/PABCSystem.pas b/TestSuite/CompilationSamples/PABCSystem.pas index 2e779d9ca..8c03c283e 100644 --- a/TestSuite/CompilationSamples/PABCSystem.pas +++ b/TestSuite/CompilationSamples/PABCSystem.pas @@ -2828,10 +2828,9 @@ begin else sb.Append(']'); Result := sb.ToString; end - else if o.GetType.Name.StartsWith('$pascal_array') then + else if o.GetType.GetField('NullBasedArray')<>nil then begin - var t := o.GetType; - var f := t.GetField('NullBasedArray'); + var f := o.GetType.GetField('NullBasedArray'); Result := StructuredObjectToString(f.GetValue(o)); end else @@ -3368,6 +3367,17 @@ begin action(x); end; +/// Применяет действие к каждому элементу последовательности, зависящее от номера элемента +procedure &ForEach(self: sequence of T; action: (T,integer) -> ()); extensionmethod; +begin + var i := 0; + foreach x: T in Self do + begin + action(x,i); + i += 1; + end; +end; + /// Возвращает отсортированную по возрастанию последовательность function Sorted(self: sequence of T): sequence of T; extensionmethod; begin @@ -3431,6 +3441,45 @@ end; // ----------------------------------------------------------------------------- // Функции для последовательностей и динамических массивов // ----------------------------------------------------------------------------- + +type +// Вспомогательный класс для генерации всех последовательностей. К сожалению, пока с object + SeqBase = class(IEnumerable,IEnumerator) + public + function System.Collections.IEnumerable.GetEnumerator(): System.Collections.IEnumerator; + begin + Result := Self; + end; + + function GetEnumerator(): IEnumerator; + begin + Result := Self; + end; + + function get_Current: object; virtual; + begin + Result := nil; + end; + + function System.Collections.IEnumerator.get_Current(): object; + begin + Result := Self.get_Current(); + end; + + function MoveNext(): boolean; virtual; + begin + Result := True; + end; + + procedure Dispose(); virtual; + begin + end; + + procedure Reset(); + begin + end; + end; + function Range(self: integer): sequence of integer; extensionmethod; begin Result := Range(1,self); @@ -3445,7 +3494,7 @@ end; function Range(c1,c2: char): sequence of char; begin - Result := Range(integer(c1),integer(c2)).Select(x->ChrUnicode(x)); + Result := Range(integer(c1),integer(c2)).Select(x->Chr(x)); end; type AB = class @@ -3538,122 +3587,123 @@ begin end; type - SeqGenClass = class +// Вспомогательный класс для генерации рекуррентных последовательностей + IterateClass = class(SeqBase,IEnumerable,IEnumerator) + private first: T; - next: Func; - count: integer; - constructor (f: T; n: Func; c: integer); + cur: T; + next: T->T; + isfirst := true; + public + constructor (first: T; next: T->T); begin - first := f; - next := n; - count := c; + Self.first := first; + cur := first; + Self.next := next; end; - function lam(x: integer): T; + function get_Current: object; virtual; begin - Result := first; first := next(first); + Result := cur; end; - - function f(): sequence of T; + + function MoveNext(): boolean; virtual; begin - Result := Range(1,count).Select(lam) + Result := True; + if isfirst then + isfirst := false + else cur := next(cur) + end; + + procedure Dispose(); override; + begin + cur := first; + isfirst := true; end; end; - - SeqGenClass2 = class + +// Вспомогательный класс для генерации рекуррентных последовательностей по двум предыдущим значениям + Iterate2Class = class(SeqBase,IEnumerable,IEnumerator) + private first,second: T; - next: Func2; - count: integer; - constructor (f,s: T; n: Func2; c: integer); + a,b: T; + next: (T,T)->T; + isfirst := true; + public + constructor (first,second: T; next: (T,T)->T); begin - first := f; - second := s; - next := n; - count := c; + Self.first := first; + Self.second := second; + a := first; + b := second; + Self.next := next; end; - function lam(x: integer): T; + function get_Current: object; virtual; begin - Result := first; first := second; second := next(Result,first); - end; - - function f(): sequence of T; - begin - Result := Range(1,count).Select(lam) - end; - end; - - SeqWhileClass = class - first: T; - next: Func; - pred: Func; - constructor (f: T; n: Func; p: Func); - begin - first := f; - next := n; - pred := p; + Result := a; end; - function lam(x: integer): T; + function MoveNext(): boolean; virtual; begin - Result := first; first := next(first); + Result := True; + if isfirst then + isfirst := false + else + begin + var v := next(a,b); + a := b; + b := v; + end; end; - function f(): sequence of T; + procedure Dispose(); override; begin - Result := Range(1,1000000000).Select(lam).TakeWhile(pred); - end; - end; - - SeqWhileClass2 = class - first,second: T; - next: Func2; - pred: Func; - constructor (f,s: T; n: Func2; p: Func); - begin - first := f; - second := s; - next := n; - pred := p; - end; - - function lam(x: integer): T; - begin - Result := first; first := second; second := next(Result,first); - end; - - function f(): sequence of T; - begin - Result := Range(1,1000000000).Select(lam).TakeWhile(pred); + a := first; + b := second; + isfirst := true; end; end; +/// Возвращает бесконечную рекуррентную последовательность элементов, задаваемую начальным элементом first и функцией next +function Iterate(first: T; next: T->T): sequence of T; +begin + Result := IterateClass&.Create(first,next).Select(x->T(x)); +end; + +/// Возвращает бесконечную рекуррентную последовательность элементов, задаваемую начальным элементом и функцией next +function Iterate(Self: T; next: T -> T): sequence of T; extensionmethod; +begin + Result := Iterate&(Self,next); +end; + +function Iterate(first,second: T; next: (T,T)->T): sequence of T; +begin + Result := Iterate2Class&.Create(first,second,next).Select(x->T(x)); +end; + function SeqGen(count: integer; first: T; next: T -> T): sequence of T; begin if count<1 then raise new System.ArgumentOutOfRangeException('count',count,GetTranslation(PARAMETER_COUNT_MUST_BE_GREATER_0)); - var tt := new SeqGenClass(first,next,count); - Result := tt.f(); + Result := Iterate(first,next).Take(count); end; function SeqGen(count: integer; first,second: T; next: (T,T) -> T): sequence of T; begin if count<1 then raise new System.ArgumentOutOfRangeException('count',count,GetTranslation(PARAMETER_COUNT_MUST_BE_GREATER_0)); - var tt := new SeqGenClass2(first,second,next,count); - Result := tt.f(); + Result := Iterate(first,second,next).Take(count); end; function SeqWhile(first: T; next: T -> T; pred: T -> boolean): sequence of T; begin - var tt := new SeqWhileClass(first,next,pred); - Result := tt.f(); + Result := Iterate(first,next).TakeWhile(pred); end; function SeqWhile(first,second: T; next: (T,T) -> T; pred: T -> boolean): sequence of T; begin - var tt := new SeqWhileClass2(first,second,next,pred); - Result := tt.f(); + Result := Iterate(first,second,next).TakeWhile(pred); end; function ArrGen(count: integer; first: T; next: T -> T): array of T; diff --git a/VisualPascalABCNET/VisualPascalABCNET.csproj b/VisualPascalABCNET/VisualPascalABCNET.csproj index 0babcaf44..f65a9aac5 100644 --- a/VisualPascalABCNET/VisualPascalABCNET.csproj +++ b/VisualPascalABCNET/VisualPascalABCNET.csproj @@ -48,7 +48,7 @@ prompt 4 AllRules.ruleset - false + true PdbOnly diff --git a/bin/Lib/PABCRtl.dll b/bin/Lib/PABCRtl.dll index 7b04c59fb..e9a306579 100644 Binary files a/bin/Lib/PABCRtl.dll and b/bin/Lib/PABCRtl.dll differ diff --git a/bin/Lib/PABCSystem.pas b/bin/Lib/PABCSystem.pas index 46a840cdd..8c03c283e 100644 --- a/bin/Lib/PABCSystem.pas +++ b/bin/Lib/PABCSystem.pas @@ -2828,10 +2828,9 @@ begin else sb.Append(']'); Result := sb.ToString; end - else if o.GetType.Name.StartsWith('$pascal_array') then + else if o.GetType.GetField('NullBasedArray')<>nil then begin - var t := o.GetType; - var f := t.GetField('NullBasedArray'); + var f := o.GetType.GetField('NullBasedArray'); Result := StructuredObjectToString(f.GetValue(o)); end else @@ -3368,6 +3367,17 @@ begin action(x); end; +/// Применяет действие к каждому элементу последовательности, зависящее от номера элемента +procedure &ForEach(self: sequence of T; action: (T,integer) -> ()); extensionmethod; +begin + var i := 0; + foreach x: T in Self do + begin + action(x,i); + i += 1; + end; +end; + /// Возвращает отсортированную по возрастанию последовательность function Sorted(self: sequence of T): sequence of T; extensionmethod; begin