Несколько новых перегрузок методов расширений для массивов
This commit is contained in:
miks1965 2016-07-17 20:09:53 +03:00
parent f5310b31e6
commit e7b65c421b
9 changed files with 268 additions and 34 deletions

View file

@ -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 = "1270";
public const string Revision = "1271";
public const string MainVersion = Major + "." + Minor;
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;

View file

@ -1,4 +1,4 @@
%MINOR%=1
%REVISION%=1270
%COREVERSION%=0
%REVISION%=1271
%MINOR%=1
%MAJOR%=3

View file

@ -770,6 +770,28 @@
</Node>
<Node Name="Yield">
<Items>
<Node Name="visit(procedure_definition pd)">
<FileName>\Yield\SyntaxVisitors\YieldVisitors\ProcessYieldsCapturedVars.cs</FileName>
<Text>public override void visit(procedure_definition pd)</Text>
<OCtx>
<i Type="Method">public override void visit ( procedure_definition pd )</i>
<i Type="ClassOrNamespace">public class ProcessYieldCapturedVarsVisitor : BaseChangeVisitor</i>
<i Type="ClassOrNamespace">namespace SyntaxVisitors</i>
<i Type="CS_TreeNode">
</i>
</OCtx>
</Node>
<Node Name="root.visit(new ProcessYieldCapturedVarsVisitor());">
<FileName>\Yield\YieldConversionSyntax\YieldDesugarSyntaxTreeConverter.cs</FileName>
<Text>root.visit(new ProcessYieldCapturedVarsVisitor());</Text>
<OCtx>
<i Type="Method">public syntax_tree_node Convert ( syntax_tree_node root )</i>
<i Type="ClassOrNamespace">public class YieldDesugarSyntaxTreeConverter : ISyntaxTreeConverter</i>
<i Type="ClassOrNamespace">namespace YieldDesugarSyntaxTreeConverter</i>
<i Type="CS_TreeNode">
</i>
</OCtx>
</Node>
<Node Name="NewConstructFiniteAutomata">
<Items>
<Node Name="ConstructFiniteAutomata1">
@ -787,7 +809,7 @@
<FileName>\yield\syntaxvisitors\yieldvisitors\processyieldscapturedvars.cs</FileName>
<Text>type_declarations GenClassesForYield(procedure_definition pd,</Text>
<OCtx>
<i Type="Method">type_declarations GenClassesForYield ( procedure_definition pd , IEnumerable &lt; var_def_statement &gt; fields , IDictionary &lt; string , string &gt; localsMap , IDictionary &lt; string , string &gt; formalParamsMap , IDictionary &lt; var_def_statement , var_def_statement &gt; localsCloneMap )</i>
<i Type="Method">type_declarations GenClassesForYield ( procedure_definition pd , IEnumerable &lt; var_def_statement &gt; fields , IDictionary &lt; string , string &gt; localsMap , IDictionary &lt; string , string &gt; formalParamsMap )</i>
<i Type="ClassOrNamespace">public class ProcessYieldCapturedVarsVisitor : BaseChangeVisitor</i>
<i Type="ClassOrNamespace">namespace SyntaxVisitors</i>
<i Type="CS_TreeNode">
@ -796,17 +818,6 @@
</Node>
</Items>
</Node>
<Node Name="root.visit(new ProcessYieldCapturedVarsVisitor());">
<FileName>\Yield\YieldConversionSyntax\YieldDesugarSyntaxTreeConverter.cs</FileName>
<Text>root.visit(new ProcessYieldCapturedVarsVisitor());</Text>
<OCtx>
<i Type="Method">public syntax_tree_node Convert ( syntax_tree_node root )</i>
<i Type="ClassOrNamespace">public class YieldDesugarSyntaxTreeConverter : ISyntaxTreeConverter</i>
<i Type="ClassOrNamespace">namespace YieldDesugarSyntaxTreeConverter</i>
<i Type="CS_TreeNode">
</i>
</OCtx>
</Node>
<Node Name="YieldHelpers">
<FileName>\TreeConverter\TreeConversion\syntax_tree_visitor.cs</FileName>
<Text>string Consts__Self = YieldHelpers.YieldConsts.Self;</Text>
@ -822,7 +833,7 @@
<FileName>\yield\syntaxvisitors\yieldvisitors\processyieldscapturedvars.cs</FileName>
<Text>function_header nfh = ObjectCopier.Clone(fh);</Text>
<OCtx>
<i Type="Method">type_declarations GenClassesForYield ( procedure_definition pd , IEnumerable &lt; var_def_statement &gt; fields , IDictionary &lt; string , string &gt; localsMap , IDictionary &lt; string , string &gt; formalParamsMap , IDictionary &lt; var_def_statement , var_def_statement &gt; localsCloneMap )</i>
<i Type="Method">type_declarations GenClassesForYield ( procedure_definition pd , IEnumerable &lt; var_def_statement &gt; fields , IDictionary &lt; string , string &gt; localsMap , IDictionary &lt; string , string &gt; formalParamsMap )</i>
<i Type="ClassOrNamespace">public class ProcessYieldCapturedVarsVisitor : BaseChangeVisitor</i>
<i Type="ClassOrNamespace">namespace SyntaxVisitors</i>
<i Type="CS_TreeNode">
@ -844,7 +855,7 @@
<FileName>\yield\syntaxvisitors\yieldvisitors\processyieldscapturedvars.cs</FileName>
<Text>//InsertHelperMethod(pd, pdCloned); // SSM 13.07.16 - вызов этого метода можно не добавлять</Text>
<OCtx>
<i Type="Method">private void CreateLocalVariablesTypeProxies ( procedure_definition pd , out IEnumerable &lt; var_def_statement &gt; localsClonesCollection )</i>
<i Type="Method">private void CreateErrorCheckerHelper ( procedure_definition pd )</i>
<i Type="ClassOrNamespace">public class ProcessYieldCapturedVarsVisitor : BaseChangeVisitor</i>
<i Type="ClassOrNamespace">namespace SyntaxVisitors</i>
<i Type="CS_TreeNode">
@ -1011,8 +1022,30 @@
</i>
</OCtx>
</Node>
<Node Name="if (pd.has_yield) // SSM bug fix #219">
<FileName>\Yield\SyntaxVisitors\YieldVisitors\MarkMethodHasYieldVisitor.cs</FileName>
<Text>if (pd.has_yield) // SSM bug fix #219</Text>
<OCtx>
<i Type="Method">public override void visit ( procedure_definition pd )</i>
<i Type="ClassOrNamespace">public class MarkMethodHasYieldAndCheckSomeErrorsVisitor : WalkingVisitorNew</i>
<i Type="ClassOrNamespace">namespace SyntaxVisitors</i>
<i Type="CS_TreeNode">
</i>
</OCtx>
</Node>
</Items>
</Node>
<Node Name="id.name.ToLower() == &quot;result&quot;">
<FileName>\Yield\SyntaxVisitors\YieldVisitors\MarkMethodHasYieldVisitor.cs</FileName>
<Text>if (id.name.ToLower() == "result")</Text>
<OCtx>
<i Type="Method">public override void visit ( ident id )</i>
<i Type="ClassOrNamespace">public class MarkMethodHasYieldVisitor : WalkingVisitorNew</i>
<i Type="ClassOrNamespace">namespace SyntaxVisitors</i>
<i Type="CS_TreeNode">
</i>
</OCtx>
</Node>
</Items>
</Node>
</AspectFile>

View file

@ -1 +1 @@
!define VERSION '3.1.0.1270'
!define VERSION '3.1.0.1271'

View file

@ -1270,6 +1270,10 @@ procedure Str(s1: string; var s: string);
function Pos(subs, s: string; from: integer := 1): integer;
/// Возвращает позицию подстроки subs в строке s начиная с позиции from. Если не найдена, возвращает 0
function PosEx(subs, s: string; from: integer := 1): integer;
/// Возвращает позицию последнего вхождения подстроки subs в строке s. Если не найдена, возвращает 0
function LastPos(subs, s: string): integer;
/// Возвращает позицию последнего вхождения подстроки subs в строке s начиная с позиции from. Если не найдена, возвращает 0
function LastPos(subs, s: string; from: integer): integer;
/// Возвращает длину строки
function Length(s: string): integer;
/// Устанавливает длину строки s равной n
@ -7178,6 +7182,21 @@ begin
else Result := s.IndexOf(subs, from - 1) + 1;
end;
function LastPos(subs, s: string): integer;
begin
if (subs = nil) or (subs.Length = 0) then
Result := 0
else Result := s.LastIndexOf(subs, s.Length - 1) + 1;
end;
function LastPos(subs, s: string; from: integer): integer;
begin
if (subs = nil) or (subs.Length = 0) then
Result := 0
else Result := s.LastIndexOf(subs, from - 1) + 1;
end;
function Length(s: string): integer;
begin
if s <> nil then
@ -8448,10 +8467,10 @@ begin
end;
/// Находит первую пару подряд идущих одинаковых элементов и возвращает индекс первого элемента пары. Если не найден, возвращается -1
function AdjacentFind<T>(Self: array of T): integer; extensionmethod;
function AdjacentFind<T>(Self: array of T; start: integer := 0): integer; extensionmethod;
begin
Result := -1;
for var i:=0 to Self.Length-2 do
for var i:=start to Self.Length-2 do
if Self[i]=Self[i+1] then
begin
Result := i;
@ -8459,12 +8478,24 @@ begin
end;
end;
/// Возвращает индекс первого минимального элемента
function IndexMin<T>(Self: array of T): integer; extensionmethod; where T: System.IComparable<T>;
/// Находит первую пару подряд идущих одинаковых элементов, используя функцию сравнения eq, и возвращает индекс первого элемента пары. Если не найден, возвращается -1
function AdjacentFind<T>(Self: array of T; eq: (T,T)->boolean; start: integer := 0): integer; extensionmethod;
begin
var min := Self[0];
Result := 0;
for var i:=1 to Self.Length-1 do
Result := -1;
for var i:=start to Self.Length-2 do
if eq(Self[i],Self[i+1]) then
begin
Result := i;
exit;
end;
end;
/// Возвращает индекс первого минимального элемента начиная с позиции start
function IndexMin<T>(Self: array of T; start: integer := 0): integer; extensionmethod; where T: System.IComparable<T>;
begin
var min := Self[start];
Result := start;
for var i:=start+1 to Self.Length-1 do
if Self[i].CompareTo(min)<0 then
begin
Result := i;
@ -8485,6 +8516,45 @@ begin
end;
end;
/// Возвращает индекс первого максимального элемента начиная с позиции start
function IndexMax<T>(self: array of T; start: integer): integer; extensionmethod; where T: System.IComparable<T>;
begin
var max := Self[start];
Result := start;
for var i:=start+1 to Self.Length-1 do
if Self[i].CompareTo(max)>0 then
begin
Result := i;
max := Self[i];
end;
end;
/// Возвращает индекс последнего минимального элемента
function LastIndexMin<T>(Self: array of T): integer; extensionmethod; where T: System.IComparable<T>;
begin
var min := Self[Self.Length-1];
Result := Self.Length-1;
for var i:=Self.Length-2 downto 0 do
if Self[i].CompareTo(min)<0 then
begin
Result := i;
min := Self[i];
end;
end;
/// Возвращает индекс последнего минимального элемента начиная с позиции start
function LastIndexMin<T>(Self: array of T; start: integer): integer; extensionmethod; where T: System.IComparable<T>;
begin
var min := Self[start];
Result := start;
for var i:=start-1 downto 0 do
if Self[i].CompareTo(min)<0 then
begin
Result := i;
min := Self[i];
end;
end;
/// Заменяет в массиве все вхождения одного значения на другое
procedure Replace<T>(Self: array of T; oldValue,newValue: T); extensionmethod;
begin
@ -8524,6 +8594,12 @@ begin
Result := System.Array.FindIndex(self,p);
end;
/// Выполняет поиск индекса первого элемента в массиве, удовлетворяющего предикату, начиная с индекса start. Если не найден, возвращается -1
function FindIndex<T>(self: array of T; start: integer; p: T->boolean): integer; extensionmethod;
begin
Result := System.Array.FindIndex(self,start,p);
end;
/// Возвращает в виде массива все элементы, удовлетворяющие предикату
function FindAll<T>(self: array of T; p: T->boolean): array of T; extensionmethod;
begin
@ -8542,18 +8618,36 @@ begin
Result := System.Array.FindLastIndex(self,p);
end;
/// Выполняет поиск индекса последнего элемента в массиве, удовлетворяющего предикату, начиная с индекса start. Если не найден, возвращается нулевое значение соответствующего типа
function FindLastIndex<T>(self: array of T; start: integer; p: T->boolean): integer; extensionmethod;
begin
Result := System.Array.FindLastIndex(self,start,p);
end;
/// Возвращает индекс первого вхождения элемента или -1 если элемент не найден
function IndexOf<T>(self: array of T; x: T): integer; extensionmethod;
begin
Result := System.Array.IndexOf(self,x);
end;
/// Возвращает индекс первого вхождения элемента начиная с индекса start или -1 если элемент не найден
function IndexOf<T>(self: array of T; x: T; start: integer): integer; extensionmethod;
begin
Result := System.Array.IndexOf(self,x,start);
end;
/// Возвращает индекс последнего вхождения элемента или -1 если элемент не найден
function LastIndexOf<T>(self: array of T; x: T): integer; extensionmethod;
begin
Result := System.Array.LastIndexOf(self,x);
end;
/// Возвращает индекс последнего вхождения элемента начиная с индекса start или -1 если элемент не найден
function LastIndexOf<T>(self: array of T; x: T; start: integer): integer; extensionmethod;
begin
Result := System.Array.LastIndexOf(self,x,start);
end;
/// Меняет размер массива
procedure Resize<T>(self: array of T; x: integer); extensionmethod;
begin

View file

@ -10,7 +10,7 @@ using PascalABCCompiler.Errors;
namespace SyntaxVisitors
{
public class MarkMethodHasYieldVisitor : WalkingVisitorNew
public class MarkMethodHasYieldAndCheckSomeErrorsVisitor : WalkingVisitorNew
{
private bool HasYields = false;
private procedure_definition CurrentMethod = null;
@ -48,6 +48,19 @@ namespace SyntaxVisitors
base.visit(pd);
pd.has_yield = HasYields;
if (pd.has_yield) // SSM bug fix #219
{
var ee = pd.proc_body as block;
if (ee != null)
{
var FirstTypeDeclaration = ee.defs.DescendantNodes().OfType<type_declarations>().First();
if (FirstTypeDeclaration != null)
{
throw new SyntaxError("Функции с yield не могут содержать локальные определения типов", "", FirstTypeDeclaration.source_context, FirstTypeDeclaration);
}
}
}
var innerPds = pd.DescendantNodes().OfType<procedure_definition>();
if (pd.has_yield && innerPds.Count() > 0

View file

@ -24,7 +24,7 @@ namespace YieldDesugarSyntaxTreeConverter
public ExecutionOrder ExecutionOrder { get; set; }
public syntax_tree_node Convert(syntax_tree_node root)
{
root.visit(new MarkMethodHasYieldVisitor());
root.visit(new MarkMethodHasYieldAndCheckSomeErrorsVisitor());
root.visit(new ProcessYieldCapturedVarsVisitor());
#if DEBUG

Binary file not shown.

View file

@ -1270,6 +1270,10 @@ procedure Str(s1: string; var s: string);
function Pos(subs, s: string; from: integer := 1): integer;
/// Возвращает позицию подстроки subs в строке s начиная с позиции from. Если не найдена, возвращает 0
function PosEx(subs, s: string; from: integer := 1): integer;
/// Возвращает позицию последнего вхождения подстроки subs в строке s. Если не найдена, возвращает 0
function LastPos(subs, s: string): integer;
/// Возвращает позицию последнего вхождения подстроки subs в строке s начиная с позиции from. Если не найдена, возвращает 0
function LastPos(subs, s: string; from: integer): integer;
/// Возвращает длину строки
function Length(s: string): integer;
/// Устанавливает длину строки s равной n
@ -7178,6 +7182,21 @@ begin
else Result := s.IndexOf(subs, from - 1) + 1;
end;
function LastPos(subs, s: string): integer;
begin
if (subs = nil) or (subs.Length = 0) then
Result := 0
else Result := s.LastIndexOf(subs, s.Length - 1) + 1;
end;
function LastPos(subs, s: string; from: integer): integer;
begin
if (subs = nil) or (subs.Length = 0) then
Result := 0
else Result := s.LastIndexOf(subs, from - 1) + 1;
end;
function Length(s: string): integer;
begin
if s <> nil then
@ -8448,10 +8467,10 @@ begin
end;
/// Находит первую пару подряд идущих одинаковых элементов и возвращает индекс первого элемента пары. Если не найден, возвращается -1
function AdjacentFind<T>(Self: array of T): integer; extensionmethod;
function AdjacentFind<T>(Self: array of T; start: integer := 0): integer; extensionmethod;
begin
Result := -1;
for var i:=0 to Self.Length-2 do
for var i:=start to Self.Length-2 do
if Self[i]=Self[i+1] then
begin
Result := i;
@ -8459,12 +8478,24 @@ begin
end;
end;
/// Возвращает индекс первого минимального элемента
function IndexMin<T>(Self: array of T): integer; extensionmethod; where T: System.IComparable<T>;
/// Находит первую пару подряд идущих одинаковых элементов, используя функцию сравнения eq, и возвращает индекс первого элемента пары. Если не найден, возвращается -1
function AdjacentFind<T>(Self: array of T; eq: (T,T)->boolean; start: integer := 0): integer; extensionmethod;
begin
var min := Self[0];
Result := 0;
for var i:=1 to Self.Length-1 do
Result := -1;
for var i:=start to Self.Length-2 do
if eq(Self[i],Self[i+1]) then
begin
Result := i;
exit;
end;
end;
/// Возвращает индекс первого минимального элемента начиная с позиции start
function IndexMin<T>(Self: array of T; start: integer := 0): integer; extensionmethod; where T: System.IComparable<T>;
begin
var min := Self[start];
Result := start;
for var i:=start+1 to Self.Length-1 do
if Self[i].CompareTo(min)<0 then
begin
Result := i;
@ -8485,6 +8516,45 @@ begin
end;
end;
/// Возвращает индекс первого максимального элемента начиная с позиции start
function IndexMax<T>(self: array of T; start: integer): integer; extensionmethod; where T: System.IComparable<T>;
begin
var max := Self[start];
Result := start;
for var i:=start+1 to Self.Length-1 do
if Self[i].CompareTo(max)>0 then
begin
Result := i;
max := Self[i];
end;
end;
/// Возвращает индекс последнего минимального элемента
function LastIndexMin<T>(Self: array of T): integer; extensionmethod; where T: System.IComparable<T>;
begin
var min := Self[Self.Length-1];
Result := Self.Length-1;
for var i:=Self.Length-2 downto 0 do
if Self[i].CompareTo(min)<0 then
begin
Result := i;
min := Self[i];
end;
end;
/// Возвращает индекс последнего минимального элемента начиная с позиции start
function LastIndexMin<T>(Self: array of T; start: integer): integer; extensionmethod; where T: System.IComparable<T>;
begin
var min := Self[start];
Result := start;
for var i:=start-1 downto 0 do
if Self[i].CompareTo(min)<0 then
begin
Result := i;
min := Self[i];
end;
end;
/// Заменяет в массиве все вхождения одного значения на другое
procedure Replace<T>(Self: array of T; oldValue,newValue: T); extensionmethod;
begin
@ -8524,6 +8594,12 @@ begin
Result := System.Array.FindIndex(self,p);
end;
/// Выполняет поиск индекса первого элемента в массиве, удовлетворяющего предикату, начиная с индекса start. Если не найден, возвращается -1
function FindIndex<T>(self: array of T; start: integer; p: T->boolean): integer; extensionmethod;
begin
Result := System.Array.FindIndex(self,start,p);
end;
/// Возвращает в виде массива все элементы, удовлетворяющие предикату
function FindAll<T>(self: array of T; p: T->boolean): array of T; extensionmethod;
begin
@ -8542,18 +8618,36 @@ begin
Result := System.Array.FindLastIndex(self,p);
end;
/// Выполняет поиск индекса последнего элемента в массиве, удовлетворяющего предикату, начиная с индекса start. Если не найден, возвращается нулевое значение соответствующего типа
function FindLastIndex<T>(self: array of T; start: integer; p: T->boolean): integer; extensionmethod;
begin
Result := System.Array.FindLastIndex(self,start,p);
end;
/// Возвращает индекс первого вхождения элемента или -1 если элемент не найден
function IndexOf<T>(self: array of T; x: T): integer; extensionmethod;
begin
Result := System.Array.IndexOf(self,x);
end;
/// Возвращает индекс первого вхождения элемента начиная с индекса start или -1 если элемент не найден
function IndexOf<T>(self: array of T; x: T; start: integer): integer; extensionmethod;
begin
Result := System.Array.IndexOf(self,x,start);
end;
/// Возвращает индекс последнего вхождения элемента или -1 если элемент не найден
function LastIndexOf<T>(self: array of T; x: T): integer; extensionmethod;
begin
Result := System.Array.LastIndexOf(self,x);
end;
/// Возвращает индекс последнего вхождения элемента начиная с индекса start или -1 если элемент не найден
function LastIndexOf<T>(self: array of T; x: T; start: integer): integer; extensionmethod;
begin
Result := System.Array.LastIndexOf(self,x,start);
end;
/// Меняет размер массива
procedure Resize<T>(self: array of T; x: integer); extensionmethod;
begin