Исправил реализацию SeqGen

This commit is contained in:
miks1965 2016-02-15 22:27:20 +03:00
parent c3b262329f
commit 9c3fe75d87
3 changed files with 221 additions and 77 deletions

View file

@ -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)

View file

@ -8054,6 +8054,108 @@
</OuterContext>
<Items />
</PointOfInterest>
<PointOfInterest>
<Name>SeqBase class</Name>
<FileName>\PABCSystem.pas</FileName>
<Text>SeqBase = class(IEnumerable&lt;object&gt;,IEnumerator&lt;object&gt;)</Text>
<OuterContext>
<OuterContextItem Type="Class">
<string>SeqBase</string>
<string>=</string>
<string>class</string>
<string>(</string>
<string>IEnumerable</string>
<string>&lt;</string>
<string>object</string>
<string>&gt;</string>
<string>,</string>
<string>IEnumerator</string>
<string>&lt;</string>
<string>object</string>
<string>&gt;</string>
<string>)</string>
</OuterContextItem>
<OuterContextItem Type="Defs">
<string>type</string>
</OuterContextItem>
<OuterContextItem Type="PAS_TreeNode" />
</OuterContext>
<InnerContext>
<InnerContextItem Type="ClassMethod">
<string>function</string>
<string>System</string>
<string>.</string>
<string>Collections</string>
<string>.</string>
<string>IEnumerable</string>
<string>.</string>
<string>GetEnumerator</string>
<string>(</string>
<string>)</string>
<string>:</string>
<string>System</string>
<string>.</string>
<string>Collections</string>
<string>.</string>
<string>IEnumerator</string>
</InnerContextItem>
<InnerContextItem Type="ClassMethod">
<string>function</string>
<string>GetEnumerator</string>
<string>(</string>
<string>)</string>
<string>:</string>
<string>IEnumerator</string>
<string>&lt;</string>
<string>object</string>
<string>&gt;</string>
</InnerContextItem>
<InnerContextItem Type="ClassMethod">
<string>function</string>
<string>get_Current</string>
<string>:</string>
<string>object</string>
<string>virtual</string>
</InnerContextItem>
<InnerContextItem Type="ClassMethod">
<string>function</string>
<string>System</string>
<string>.</string>
<string>Collections</string>
<string>.</string>
<string>IEnumerator</string>
<string>.</string>
<string>get_Current</string>
<string>(</string>
<string>)</string>
<string>:</string>
<string>object</string>
</InnerContextItem>
<InnerContextItem Type="ClassMethod">
<string>function</string>
<string>MoveNext</string>
<string>(</string>
<string>)</string>
<string>:</string>
<string>boolean</string>
<string>virtual</string>
</InnerContextItem>
<InnerContextItem Type="ClassMethod">
<string>procedure</string>
<string>Dispose</string>
<string>(</string>
<string>)</string>
<string>virtual</string>
</InnerContextItem>
<InnerContextItem Type="ClassMethod">
<string>procedure</string>
<string>Reset</string>
<string>(</string>
<string>)</string>
</InnerContextItem>
</InnerContext>
<Items />
</PointOfInterest>
</Items>
</PointOfInterest>
</AspectFile>

View file

@ -3431,6 +3431,45 @@ end;
// -----------------------------------------------------------------------------
// Функции для последовательностей и динамических массивов
// -----------------------------------------------------------------------------
type
// Вспомогательный класс для генерации всех последовательностей. К сожалению, пока с object
SeqBase = class(IEnumerable<object>,IEnumerator<object>)
public
function System.Collections.IEnumerable.GetEnumerator(): System.Collections.IEnumerator;
begin
Result := Self;
end;
function GetEnumerator(): IEnumerator<object>;
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<T> = class
// Вспомогательный класс для генерации рекуррентных последовательностей
IterateClass<T> = class(SeqBase,IEnumerable<object>,IEnumerator<object>)
private
first: T;
next: Func<T,T>;
count: integer;
constructor (f: T; n: Func<T,T>; 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<T> = class
// Вспомогательный класс для генерации рекуррентных последовательностей по двум предыдущим значениям
Iterate2Class<T> = class(SeqBase,IEnumerable<object>,IEnumerator<object>)
private
first,second: T;
next: Func2<T,T,T>;
count: integer;
constructor (f,s: T; n: Func2<T,T,T>; 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<T> = class
first: T;
next: Func<T,T>;
pred: Func<T,boolean>;
constructor (f: T; n: Func<T,T>; p: Func<T,boolean>);
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<T> = class
first,second: T;
next: Func2<T,T,T>;
pred: Func<T,boolean>;
constructor (f,s: T; n: Func2<T,T,T>; p: Func<T,boolean>);
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<T>(first: T; next: T->T): sequence of T;
begin
Result := IterateClass&<T>.Create(first,next).Select(x->T(x));
end;
/// Возвращает бесконечную рекуррентную последовательность элементов, задаваемую начальным элементом и функцией next
function Iterate<T>(Self: T; next: T -> T): sequence of T; extensionmethod;
begin
Result := Iterate&<T>(Self,next);
end;
function Iterate<T>(first,second: T; next: (T,T)->T): sequence of T;
begin
Result := Iterate2Class&<T>.Create(first,second,next).Select(x->T(x));
end;
function SeqGen<T>(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<T>(first,next,count);
Result := tt.f();
Result := Iterate(first,next).Take(count);
end;
function SeqGen<T>(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<T>(first,second,next,count);
Result := tt.f();
Result := Iterate(first,second,next).Take(count);
end;
function SeqWhile<T>(first: T; next: T -> T; pred: T -> boolean): sequence of T;
begin
var tt := new SeqWhileClass<T>(first,next,pred);
Result := tt.f();
Result := Iterate(first,next).TakeWhile(pred);
end;
function SeqWhile<T>(first,second: T; next: (T,T) -> T; pred: T -> boolean): sequence of T;
begin
var tt := new SeqWhileClass2<T>(first,second,next,pred);
Result := tt.f();
Result := Iterate(first,second,next).TakeWhile(pred);
end;
function ArrGen<T>(count: integer; first: T; next: T -> T): array of T;