diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index 5745e7e7a..bf73f088d 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -4931,7 +4931,8 @@ namespace PascalABCCompiler.TreeConverter } //lroman// #endregion - exprs.AddElement(convert_strong(en)); + var cen = convert_strong(en); + exprs.AddElement(cen); } } @@ -11161,6 +11162,7 @@ namespace PascalABCCompiler.TreeConverter if (fh != null && fh.return_type == null) { // попытаемся поступить как в лямбдах + //fh.return_type = new SyntaxTree.lambda_inferred_type(); //fh.return_type = new semantic_type_node(new LambdaResultTypeInferrer(fh, _procedure_definition.proc_body, this).InferResultType(1)); var bl = _procedure_definition.proc_body as SyntaxTree.block; if (bl != null && bl.program_code != null) diff --git a/bin/Lib/PABCSystem.axml b/bin/Lib/PABCSystem.axml index 1ffe5c132..0427cc51c 100644 --- a/bin/Lib/PABCSystem.axml +++ b/bin/Lib/PABCSystem.axml @@ -8054,6 +8054,108 @@ + + SeqBase class + \PABCSystem.pas + SeqBase = class(IEnumerable<object>,IEnumerator<object>) + + + SeqBase + = + class + ( + IEnumerable + < + object + > + , + IEnumerator + < + object + > + ) + + + type + + + + + + function + System + . + Collections + . + IEnumerable + . + GetEnumerator + ( + ) + : + System + . + Collections + . + IEnumerator + + + function + GetEnumerator + ( + ) + : + IEnumerator + < + object + > + + + function + get_Current + : + object + virtual + + + function + System + . + Collections + . + IEnumerator + . + get_Current + ( + ) + : + object + + + function + MoveNext + ( + ) + : + boolean + virtual + + + procedure + Dispose + ( + ) + virtual + + + procedure + Reset + ( + ) + + + + \ No newline at end of file diff --git a/bin/Lib/PABCSystem.pas b/bin/Lib/PABCSystem.pas index 2e779d9ca..46a840cdd 100644 --- a/bin/Lib/PABCSystem.pas +++ b/bin/Lib/PABCSystem.pas @@ -3431,6 +3431,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 +3484,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 +3577,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;