Многомерные срезы без семантических проверок
Разрешил a as array [,] of T
This commit is contained in:
parent
b1323a6e0e
commit
7c3273aae8
|
|
@ -15,7 +15,7 @@ internal static class RevisionClass
|
|||
public const string Major = "3";
|
||||
public const string Minor = "7";
|
||||
public const string Build = "2";
|
||||
public const string Revision = "2823";
|
||||
public const string Revision = "2827";
|
||||
|
||||
public const string MainVersion = Major + "." + Minor;
|
||||
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
%MINOR%=7
|
||||
%REVISION%=2823
|
||||
%REVISION%=2827
|
||||
%COREVERSION%=2
|
||||
%MAJOR%=3
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// This CSharp output file generated by Gardens Point LEX
|
||||
// Version: 1.1.3.301
|
||||
// Machine: DESKTOP-G8V08V4
|
||||
// DateTime: 22.02.2021 17:50:28
|
||||
// DateTime: 24.02.2021 0:24:55
|
||||
// UserName: ?????????
|
||||
// GPLEX input file <ABCPascal.lex>
|
||||
// GPLEX frame file <embedded resource>
|
||||
|
|
|
|||
|
|
@ -3907,6 +3907,10 @@ as_expr
|
|||
{
|
||||
$$ = NewAsIsExpr($1, op_typecast.as_op, $3, @$);
|
||||
}
|
||||
| term tkAs array_type
|
||||
{
|
||||
$$ = NewAsIsExpr($1, op_typecast.as_op, $3, @$);
|
||||
}
|
||||
;
|
||||
|
||||
is_type_expr
|
||||
|
|
@ -3914,6 +3918,10 @@ is_type_expr
|
|||
{
|
||||
$$ = NewAsIsExpr($1, op_typecast.is_op, $3, @$);
|
||||
}
|
||||
| term tkIs array_type
|
||||
{
|
||||
$$ = NewAsIsExpr($1, op_typecast.as_op, $3, @$);
|
||||
}
|
||||
;
|
||||
|
||||
power_expr
|
||||
|
|
@ -4159,6 +4167,31 @@ variable
|
|||
}
|
||||
$$ = new slice_expr($1 as addressed_value,fe.expr,fe.format1,fe.format2,@$);
|
||||
}
|
||||
// ìíîãîìåðíûå ñðåçû
|
||||
else if (el.expressions.Any(e => e is format_expr))
|
||||
{
|
||||
var ll = new List<Tuple<expression, expression, expression>>();
|
||||
foreach (var ex in el.expressions)
|
||||
{
|
||||
if (ex is format_expr fe)
|
||||
{
|
||||
if (fe.expr == null)
|
||||
fe.expr = new int32_const(int.MaxValue, fe.source_context);
|
||||
if (fe.format1 == null)
|
||||
fe.format1 = new int32_const(int.MaxValue, fe.source_context);
|
||||
if (fe.format2 == null)
|
||||
fe.format2 = new int32_const(1, fe.source_context);
|
||||
ll.Add(Tuple.Create(fe.expr, fe.format1, fe.format2));
|
||||
}
|
||||
else
|
||||
{
|
||||
ll.Add(Tuple.Create(ex, ex, (expression)new int32_const(int.MaxValue, ex.source_context))); // ñêàëÿðíîå çíà÷åíèå âìåñòî ñðåçà
|
||||
}
|
||||
}
|
||||
var sle = new slice_expr($1 as addressed_value,null,null,null,@$);
|
||||
sle.slices = ll;
|
||||
$$ = sle;
|
||||
}
|
||||
else $$ = new indexer($1 as addressed_value, el, @$);
|
||||
}
|
||||
| variable_or_literal_or_number tkQuestionSquareOpen format_expr tkSquareClose
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -306,6 +306,10 @@ script=
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
3.7.2.2823
|
||||
3.7.2.2827
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
!define VERSION '3.7.2.2823'
|
||||
!define VERSION '3.7.2.2827'
|
||||
|
|
|
|||
|
|
@ -1769,7 +1769,7 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
|
||||
public partial class slice_expr
|
||||
{
|
||||
public List<System.Tuple<expression, expression, expression>> slices = new List<Tuple<expression, expression, expression>>();
|
||||
public List<System.Tuple<expression, expression, expression>> slices; // = new List<Tuple<expression, expression, expression>>();
|
||||
public override string ToString() => this.v + "[" + this.from + ":" + this.to + ":" + this.step + "]";
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,26 @@ namespace SyntaxVisitors.SugarVisitors
|
|||
get { return new SliceDesugarVisitor(); }
|
||||
}
|
||||
|
||||
expression_list construct_expression_list_for_slice_expr_multi(slice_expr sl)
|
||||
{
|
||||
if (sl.slices == null)
|
||||
return null; // упадёт - это ошибка компилятора
|
||||
var el = new expression_list(); // будем наполнять кортежами - самое простое
|
||||
var sc = sl.source_context;
|
||||
foreach (var slice in sl.slices)
|
||||
{
|
||||
var tup = new dot_node(new dot_node(new ident("?System",sc), new ident("Tuple",sc), sc), new ident("Create",sc), sc);
|
||||
// пока без ^1
|
||||
var eel = new expression_list();
|
||||
eel.Add(slice.Item1);
|
||||
eel.Add(slice.Item2);
|
||||
eel.Add(slice.Item3);
|
||||
var mc = new method_call(tup, eel, sc); // sc - не очень хорошо - ошибка будет в общем месте
|
||||
el.Add(mc);
|
||||
// по идее все параметры готовы. Надо только проверить, что они целые
|
||||
}
|
||||
return el;
|
||||
}
|
||||
expression_list construct_expression_list_for_slice_expr(slice_expr sl)
|
||||
{
|
||||
// situation = 0 - ничего не пропущено
|
||||
|
|
@ -80,9 +100,19 @@ namespace SyntaxVisitors.SugarVisitors
|
|||
|
||||
public override void visit(slice_expr sl)
|
||||
{
|
||||
var el = construct_expression_list_for_slice_expr(sl);
|
||||
expression_list el = null;
|
||||
if (sl.slices == null)
|
||||
el = construct_expression_list_for_slice_expr(sl);
|
||||
else el = construct_expression_list_for_slice_expr_multi(sl); // то это многомерный массив
|
||||
// надо как-то запретить многомерные слайсы в левой части присваивания
|
||||
if (sl.Parent is assign parent_assign && parent_assign.to == sl)
|
||||
{
|
||||
// если это многомерный слайс - кинуть ошибку
|
||||
if (sl.slices != null)
|
||||
{
|
||||
// запретим пока или вовсе
|
||||
throw new SyntaxVisitorError("MULTIDIMENSIONAL_SLICES_FORBIDDEN_IN_LEFT_SIDE_OF_ASSIGNMENT", sl.source_context);
|
||||
}
|
||||
el.Insert(0, parent_assign.from);
|
||||
var mc = method_call.NewP(
|
||||
dot_node.NewP(
|
||||
|
|
@ -99,10 +129,23 @@ namespace SyntaxVisitors.SugarVisitors
|
|||
}
|
||||
else
|
||||
{
|
||||
var mc = method_call.NewP(dot_node.NewP(sl.v, new ident("SystemSlice", sl.v.source_context), sl.v.source_context), el, sl.source_context);
|
||||
var sug = sugared_addressed_value.NewP(sl, mc, sl.source_context);
|
||||
ReplaceUsingParent(sl, sug);
|
||||
visit(mc); // обойти заменённое на предмет наличия такого же синтаксического сахара
|
||||
if (sl.slices == null) // значит, это одномерный слайс - вызываем старый код
|
||||
{
|
||||
var mc = method_call.NewP(dot_node.NewP(sl.v, new ident("SystemSlice", sl.v.source_context), sl.v.source_context), el, sl.source_context);
|
||||
var sug = sugared_addressed_value.NewP(sl, mc, sl.source_context);
|
||||
ReplaceUsingParent(sl, sug);
|
||||
visit(mc); // обойти заменённое на предмет наличия такого же синтаксического сахара
|
||||
}
|
||||
else // многомерный слайс на чтение - вызываем груду новых функций
|
||||
{
|
||||
// Определим, сколько размерностей надо оставлять в многомерном слайсе
|
||||
// Столько - сколько в sl.slices кортежей с шагом int.MaxValue. Считаем:
|
||||
var N = sl.slices.Count(s => { var u = s.Item3 as int32_const; return u == null || u.val != int.MaxValue; });
|
||||
var mc = method_call.NewP(dot_node.NewP(sl.v, new ident("SystemSliceN"+N, sl.v.source_context), sl.v.source_context), el, sl.source_context);
|
||||
// пока без семантической проверки
|
||||
ReplaceUsingParent(sl, mc);
|
||||
visit(mc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12042,6 +12042,264 @@ begin
|
|||
Result := SystemSliceArrayImplQuestion(Self, situation, from, &to, step);
|
||||
end;
|
||||
|
||||
// Срезы многомерных массивов - вспомогательные типы и функции
|
||||
type
|
||||
SliceType = class
|
||||
situation,from, &to, step, count: integer;
|
||||
oneelem: boolean;
|
||||
constructor (sit,f,t: integer; st: integer := 1; oneel: boolean := false);
|
||||
begin
|
||||
situation := sit;
|
||||
from := f;
|
||||
&to := t;
|
||||
step := st;
|
||||
count := -1; // заполняется во внешней функции
|
||||
oneelem := oneel;
|
||||
if step = integer.MaxValue then
|
||||
oneelem := True;
|
||||
end;
|
||||
procedure CorrectSliceAndCalcCount(len: integer);
|
||||
begin
|
||||
if oneelem then
|
||||
count := 1
|
||||
else count := CheckAndCorrectFromToAndCalcCountForSystemSlice(situation, len, from, &to, step);
|
||||
end;
|
||||
static function operator implicit(i: integer): SliceType;
|
||||
static function operator implicit(ir: IntRange): SliceType;
|
||||
static function operator implicit(sl: (integer,integer,integer)): SliceType;
|
||||
end;
|
||||
|
||||
function Diap(f, t: integer) := new SliceType(0, f, t, 1, false);
|
||||
function Elem(ind: integer) := new SliceType(0, ind, ind+1, 1, true);
|
||||
function Slice(f, t: integer; st: integer := 1; oneel: boolean := false): SliceType;
|
||||
begin
|
||||
var sit := 0;
|
||||
if f = integer.MaxValue then
|
||||
sit += 1;
|
||||
if t = integer.MaxValue then
|
||||
sit += 2;
|
||||
if st = integer.MaxValue then
|
||||
oneel := True;
|
||||
Result := new SliceType(sit, f, t, st, oneel);
|
||||
end;
|
||||
|
||||
static function SliceType.operator implicit(i: integer): SliceType;
|
||||
begin
|
||||
Result := Elem(i);
|
||||
end;
|
||||
|
||||
static function SliceType.operator implicit(ir: IntRange): SliceType;
|
||||
begin
|
||||
Result := Diap(ir.Low,ir.High);
|
||||
end;
|
||||
|
||||
static function SliceType.operator implicit(sl: (integer,integer,integer)): SliceType;
|
||||
begin
|
||||
Result := Slice(sl[0],sl[1],sl[2]);
|
||||
end;
|
||||
|
||||
|
||||
function ToOneDim<T>(a: array [,] of T; l: array of SliceType): array of T;
|
||||
begin
|
||||
for var i:=0 to l.Length-1 do
|
||||
l[i].CorrectSliceAndCalcCount(a.GetLength(i));
|
||||
var onedimsz := l[0].count * l[1].count;
|
||||
var res := new T[onedimsz];
|
||||
if onedimsz>0 then
|
||||
begin
|
||||
var cur := 0;
|
||||
var i0 := l[0].from;
|
||||
loop l[0].count do
|
||||
begin
|
||||
var i1:=l[1].from;
|
||||
loop l[1].count do
|
||||
begin
|
||||
res[cur] := a[i0,i1];
|
||||
cur += 1;
|
||||
i1 += l[1].step;
|
||||
end;
|
||||
i0 += l[0].step;
|
||||
end;
|
||||
end;
|
||||
Result := res;
|
||||
end;
|
||||
|
||||
function ToOneDim<T>(a: array [,,] of T; l: array of SliceType): array of T;
|
||||
begin
|
||||
for var i:=0 to l.Length-1 do
|
||||
l[i].CorrectSliceAndCalcCount(a.GetLength(i));
|
||||
var onedimsz := l[0].count * l[1].count * l[2].count;
|
||||
var res := new T[onedimsz];
|
||||
if onedimsz>0 then
|
||||
begin
|
||||
var cur := 0;
|
||||
var i0 := l[0].from;
|
||||
loop l[0].count do
|
||||
begin
|
||||
var i1:=l[1].from;
|
||||
loop l[1].count do
|
||||
begin
|
||||
var i2 := l[2].from;
|
||||
loop l[2].count do
|
||||
begin
|
||||
res[cur] := a[i0,i1,i2];
|
||||
cur += 1;
|
||||
i2 += l[2].step;
|
||||
end;
|
||||
i1 += l[1].step;
|
||||
end;
|
||||
i0 += l[0].step;
|
||||
end;
|
||||
end;
|
||||
Result := res;
|
||||
end;
|
||||
|
||||
function ToOneDim<T>(a: array [,,,] of T; l: array of SliceType): array of T;
|
||||
begin
|
||||
for var i:=0 to l.Length-1 do
|
||||
l[i].CorrectSliceAndCalcCount(a.GetLength(i));
|
||||
var onedimsz := l[0].count * l[1].count * l[2].count * l[3].count;
|
||||
var res := new T[onedimsz];
|
||||
if onedimsz>0 then
|
||||
begin
|
||||
var cur := 0;
|
||||
var i0 := l[0].from;
|
||||
loop l[0].count do
|
||||
begin
|
||||
var i1:=l[1].from;
|
||||
loop l[1].count do
|
||||
begin
|
||||
var i2 := l[2].from;
|
||||
loop l[2].count do
|
||||
begin
|
||||
var i3 := l[3].from;
|
||||
loop l[3].count do
|
||||
begin
|
||||
res[cur] := a[i0,i1,i2,i3];
|
||||
cur += 1;
|
||||
i3 += l[3].step;
|
||||
end;
|
||||
i2 += l[2].step;
|
||||
end;
|
||||
i1 += l[1].step;
|
||||
end;
|
||||
i0 += l[0].step;
|
||||
end;
|
||||
end;
|
||||
Result := res;
|
||||
end;
|
||||
|
||||
function FromOneDim2<T>(r: array of T; l: array of SliceType): array [,] of T;
|
||||
begin
|
||||
var dims := l.FindAll(x -> x.oneelem = False).ConvertAll(x -> x.count);
|
||||
Assert(dims.Length = 2);
|
||||
var cur := 0;
|
||||
var res := new T[dims[0],dims[1]];
|
||||
for var i0:=0 to dims[0]-1 do
|
||||
for var i1:=0 to dims[1]-1 do
|
||||
begin
|
||||
res[i0,i1] := r[cur];
|
||||
cur += 1;
|
||||
end;
|
||||
Result := res;
|
||||
end;
|
||||
|
||||
function FromOneDim3<T>(r: array of T; l: array of SliceType): array [,,] of T;
|
||||
begin
|
||||
var dims := l.FindAll(x -> x.oneelem = False).ConvertAll(x -> x.count);
|
||||
Assert(dims.Length = 3);
|
||||
var cur := 0;
|
||||
var res := new T[dims[0],dims[1],dims[2]];
|
||||
for var i0:=0 to dims[0]-1 do
|
||||
for var i1:=0 to dims[1]-1 do
|
||||
for var i2:=0 to dims[2]-1 do
|
||||
begin
|
||||
res[i0,i1,i2] := r[cur];
|
||||
cur += 1;
|
||||
end;
|
||||
Result := res;
|
||||
end;
|
||||
|
||||
function FromOneDim4<T>(r: array of T; l: array of SliceType): array [,,,] of T;
|
||||
begin
|
||||
var dims := l.FindAll(x -> x.oneelem = False).ConvertAll(x -> x.count);
|
||||
Assert(dims.Length = 4);
|
||||
var cur := 0;
|
||||
var res := new T[dims[0],dims[1],dims[2],dims[3]];
|
||||
for var i0:=0 to dims[0]-1 do
|
||||
for var i1:=0 to dims[1]-1 do
|
||||
for var i2:=0 to dims[2]-1 do
|
||||
for var i3:=0 to dims[3]-1 do
|
||||
begin
|
||||
res[i0,i1,i2,i3] := r[cur];
|
||||
cur += 1;
|
||||
end;
|
||||
Result := res;
|
||||
end;
|
||||
|
||||
function FromOneDimN<T>(r: array of T; l: array of SliceType): System.Array;
|
||||
begin
|
||||
var rank := l.Count(x -> x.oneelem = False);
|
||||
case rank of
|
||||
1: Result := r;
|
||||
2: Result := FromOneDim2(r,l);
|
||||
3: Result := FromOneDim3(r,l);
|
||||
4: Result := FromOneDim4(r,l);
|
||||
end;
|
||||
end;
|
||||
|
||||
function SliceN<T>(a: array[,] of T; l: array of SliceType): System.Array;
|
||||
begin
|
||||
var r := ToOneDim(a,l);
|
||||
Result := FromOneDimN(r,l);
|
||||
end;
|
||||
|
||||
function SliceN<T>(a: array[,,] of T; l: array of SliceType): System.Array;
|
||||
begin
|
||||
var r := ToOneDim(a,l);
|
||||
Result := FromOneDimN(r,l);
|
||||
end;
|
||||
|
||||
function SliceN<T>(a: array[,,,] of T; l: array of SliceType): System.Array;
|
||||
begin
|
||||
var r := ToOneDim(a,l);
|
||||
Result := FromOneDimN(r,l);
|
||||
end;
|
||||
|
||||
{type
|
||||
ArrT<T> = array of T;
|
||||
Arr2T<T> = array [,] of T;
|
||||
Arr3T<T> = array [,,] of T;
|
||||
Arr4T<T> = array [,,,] of T;}
|
||||
|
||||
///--
|
||||
function SystemSliceN1<T>(Self: array[,] of T; params l: array of SliceType): array of T; extensionmethod
|
||||
:= SliceN(Self,l) as array of T;
|
||||
///--
|
||||
function SystemSliceN1<T>(Self: array[,,] of T; params l: array of SliceType): array of T; extensionmethod
|
||||
:= SliceN(Self,l) as array of T;
|
||||
///--
|
||||
function SystemSliceN1<T>(Self: array[,,,] of T; params l: array of SliceType): array of T; extensionmethod
|
||||
:= SliceN(Self,l) as array of T;
|
||||
///--
|
||||
function SystemSliceN2<T>(Self: array[,] of T; params l: array of SliceType): array[,] of T; extensionmethod
|
||||
:= SliceN(Self,l) as array [,] of T;
|
||||
///--
|
||||
function SystemSliceN2<T>(Self: array[,,] of T; params l: array of SliceType): array[,] of T; extensionmethod
|
||||
:= SliceN(Self,l) as array [,] of T;
|
||||
///--
|
||||
function SystemSliceN2<T>(Self: array[,,,] of T; params l: array of SliceType): array[,] of T; extensionmethod
|
||||
:= SliceN(Self,l) as array [,] of T;
|
||||
///--
|
||||
function SystemSliceN3<T>(Self: array[,,] of T; params l: array of SliceType): array[,,] of T; extensionmethod
|
||||
:= SliceN(Self,l) as array [,,] of T;
|
||||
///--
|
||||
function SystemSliceN3<T>(Self: array[,,,] of T; params l: array of SliceType): array[,,] of T; extensionmethod
|
||||
:= SliceN(Self,l) as array [,,] of T;
|
||||
///--
|
||||
function SystemSliceN4<T>(Self: array[,,,] of T; params l: array of SliceType): array[,,,] of T; extensionmethod
|
||||
:= SliceN(Self,l) as array [,,,] of T;
|
||||
|
||||
// -----------------------------------------------------
|
||||
//>> Методы расширения типа integer # Extension methods for integer
|
||||
// -----------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -12042,6 +12042,264 @@ begin
|
|||
Result := SystemSliceArrayImplQuestion(Self, situation, from, &to, step);
|
||||
end;
|
||||
|
||||
// Срезы многомерных массивов - вспомогательные типы и функции
|
||||
type
|
||||
SliceType = class
|
||||
situation,from, &to, step, count: integer;
|
||||
oneelem: boolean;
|
||||
constructor (sit,f,t: integer; st: integer := 1; oneel: boolean := false);
|
||||
begin
|
||||
situation := sit;
|
||||
from := f;
|
||||
&to := t;
|
||||
step := st;
|
||||
count := -1; // заполняется во внешней функции
|
||||
oneelem := oneel;
|
||||
if step = integer.MaxValue then
|
||||
oneelem := True;
|
||||
end;
|
||||
procedure CorrectSliceAndCalcCount(len: integer);
|
||||
begin
|
||||
if oneelem then
|
||||
count := 1
|
||||
else count := CheckAndCorrectFromToAndCalcCountForSystemSlice(situation, len, from, &to, step);
|
||||
end;
|
||||
static function operator implicit(i: integer): SliceType;
|
||||
static function operator implicit(ir: IntRange): SliceType;
|
||||
static function operator implicit(sl: (integer,integer,integer)): SliceType;
|
||||
end;
|
||||
|
||||
function Diap(f, t: integer) := new SliceType(0, f, t, 1, false);
|
||||
function Elem(ind: integer) := new SliceType(0, ind, ind+1, 1, true);
|
||||
function Slice(f, t: integer; st: integer := 1; oneel: boolean := false): SliceType;
|
||||
begin
|
||||
var sit := 0;
|
||||
if f = integer.MaxValue then
|
||||
sit += 1;
|
||||
if t = integer.MaxValue then
|
||||
sit += 2;
|
||||
if st = integer.MaxValue then
|
||||
oneel := True;
|
||||
Result := new SliceType(sit, f, t, st, oneel);
|
||||
end;
|
||||
|
||||
static function SliceType.operator implicit(i: integer): SliceType;
|
||||
begin
|
||||
Result := Elem(i);
|
||||
end;
|
||||
|
||||
static function SliceType.operator implicit(ir: IntRange): SliceType;
|
||||
begin
|
||||
Result := Diap(ir.Low,ir.High);
|
||||
end;
|
||||
|
||||
static function SliceType.operator implicit(sl: (integer,integer,integer)): SliceType;
|
||||
begin
|
||||
Result := Slice(sl[0],sl[1],sl[2]);
|
||||
end;
|
||||
|
||||
|
||||
function ToOneDim<T>(a: array [,] of T; l: array of SliceType): array of T;
|
||||
begin
|
||||
for var i:=0 to l.Length-1 do
|
||||
l[i].CorrectSliceAndCalcCount(a.GetLength(i));
|
||||
var onedimsz := l[0].count * l[1].count;
|
||||
var res := new T[onedimsz];
|
||||
if onedimsz>0 then
|
||||
begin
|
||||
var cur := 0;
|
||||
var i0 := l[0].from;
|
||||
loop l[0].count do
|
||||
begin
|
||||
var i1:=l[1].from;
|
||||
loop l[1].count do
|
||||
begin
|
||||
res[cur] := a[i0,i1];
|
||||
cur += 1;
|
||||
i1 += l[1].step;
|
||||
end;
|
||||
i0 += l[0].step;
|
||||
end;
|
||||
end;
|
||||
Result := res;
|
||||
end;
|
||||
|
||||
function ToOneDim<T>(a: array [,,] of T; l: array of SliceType): array of T;
|
||||
begin
|
||||
for var i:=0 to l.Length-1 do
|
||||
l[i].CorrectSliceAndCalcCount(a.GetLength(i));
|
||||
var onedimsz := l[0].count * l[1].count * l[2].count;
|
||||
var res := new T[onedimsz];
|
||||
if onedimsz>0 then
|
||||
begin
|
||||
var cur := 0;
|
||||
var i0 := l[0].from;
|
||||
loop l[0].count do
|
||||
begin
|
||||
var i1:=l[1].from;
|
||||
loop l[1].count do
|
||||
begin
|
||||
var i2 := l[2].from;
|
||||
loop l[2].count do
|
||||
begin
|
||||
res[cur] := a[i0,i1,i2];
|
||||
cur += 1;
|
||||
i2 += l[2].step;
|
||||
end;
|
||||
i1 += l[1].step;
|
||||
end;
|
||||
i0 += l[0].step;
|
||||
end;
|
||||
end;
|
||||
Result := res;
|
||||
end;
|
||||
|
||||
function ToOneDim<T>(a: array [,,,] of T; l: array of SliceType): array of T;
|
||||
begin
|
||||
for var i:=0 to l.Length-1 do
|
||||
l[i].CorrectSliceAndCalcCount(a.GetLength(i));
|
||||
var onedimsz := l[0].count * l[1].count * l[2].count * l[3].count;
|
||||
var res := new T[onedimsz];
|
||||
if onedimsz>0 then
|
||||
begin
|
||||
var cur := 0;
|
||||
var i0 := l[0].from;
|
||||
loop l[0].count do
|
||||
begin
|
||||
var i1:=l[1].from;
|
||||
loop l[1].count do
|
||||
begin
|
||||
var i2 := l[2].from;
|
||||
loop l[2].count do
|
||||
begin
|
||||
var i3 := l[3].from;
|
||||
loop l[3].count do
|
||||
begin
|
||||
res[cur] := a[i0,i1,i2,i3];
|
||||
cur += 1;
|
||||
i3 += l[3].step;
|
||||
end;
|
||||
i2 += l[2].step;
|
||||
end;
|
||||
i1 += l[1].step;
|
||||
end;
|
||||
i0 += l[0].step;
|
||||
end;
|
||||
end;
|
||||
Result := res;
|
||||
end;
|
||||
|
||||
function FromOneDim2<T>(r: array of T; l: array of SliceType): array [,] of T;
|
||||
begin
|
||||
var dims := l.FindAll(x -> x.oneelem = False).ConvertAll(x -> x.count);
|
||||
Assert(dims.Length = 2);
|
||||
var cur := 0;
|
||||
var res := new T[dims[0],dims[1]];
|
||||
for var i0:=0 to dims[0]-1 do
|
||||
for var i1:=0 to dims[1]-1 do
|
||||
begin
|
||||
res[i0,i1] := r[cur];
|
||||
cur += 1;
|
||||
end;
|
||||
Result := res;
|
||||
end;
|
||||
|
||||
function FromOneDim3<T>(r: array of T; l: array of SliceType): array [,,] of T;
|
||||
begin
|
||||
var dims := l.FindAll(x -> x.oneelem = False).ConvertAll(x -> x.count);
|
||||
Assert(dims.Length = 3);
|
||||
var cur := 0;
|
||||
var res := new T[dims[0],dims[1],dims[2]];
|
||||
for var i0:=0 to dims[0]-1 do
|
||||
for var i1:=0 to dims[1]-1 do
|
||||
for var i2:=0 to dims[2]-1 do
|
||||
begin
|
||||
res[i0,i1,i2] := r[cur];
|
||||
cur += 1;
|
||||
end;
|
||||
Result := res;
|
||||
end;
|
||||
|
||||
function FromOneDim4<T>(r: array of T; l: array of SliceType): array [,,,] of T;
|
||||
begin
|
||||
var dims := l.FindAll(x -> x.oneelem = False).ConvertAll(x -> x.count);
|
||||
Assert(dims.Length = 4);
|
||||
var cur := 0;
|
||||
var res := new T[dims[0],dims[1],dims[2],dims[3]];
|
||||
for var i0:=0 to dims[0]-1 do
|
||||
for var i1:=0 to dims[1]-1 do
|
||||
for var i2:=0 to dims[2]-1 do
|
||||
for var i3:=0 to dims[3]-1 do
|
||||
begin
|
||||
res[i0,i1,i2,i3] := r[cur];
|
||||
cur += 1;
|
||||
end;
|
||||
Result := res;
|
||||
end;
|
||||
|
||||
function FromOneDimN<T>(r: array of T; l: array of SliceType): System.Array;
|
||||
begin
|
||||
var rank := l.Count(x -> x.oneelem = False);
|
||||
case rank of
|
||||
1: Result := r;
|
||||
2: Result := FromOneDim2(r,l);
|
||||
3: Result := FromOneDim3(r,l);
|
||||
4: Result := FromOneDim4(r,l);
|
||||
end;
|
||||
end;
|
||||
|
||||
function SliceN<T>(a: array[,] of T; l: array of SliceType): System.Array;
|
||||
begin
|
||||
var r := ToOneDim(a,l);
|
||||
Result := FromOneDimN(r,l);
|
||||
end;
|
||||
|
||||
function SliceN<T>(a: array[,,] of T; l: array of SliceType): System.Array;
|
||||
begin
|
||||
var r := ToOneDim(a,l);
|
||||
Result := FromOneDimN(r,l);
|
||||
end;
|
||||
|
||||
function SliceN<T>(a: array[,,,] of T; l: array of SliceType): System.Array;
|
||||
begin
|
||||
var r := ToOneDim(a,l);
|
||||
Result := FromOneDimN(r,l);
|
||||
end;
|
||||
|
||||
{type
|
||||
ArrT<T> = array of T;
|
||||
Arr2T<T> = array [,] of T;
|
||||
Arr3T<T> = array [,,] of T;
|
||||
Arr4T<T> = array [,,,] of T;}
|
||||
|
||||
///--
|
||||
function SystemSliceN1<T>(Self: array[,] of T; params l: array of SliceType): array of T; extensionmethod
|
||||
:= SliceN(Self,l) as array of T;
|
||||
///--
|
||||
function SystemSliceN1<T>(Self: array[,,] of T; params l: array of SliceType): array of T; extensionmethod
|
||||
:= SliceN(Self,l) as array of T;
|
||||
///--
|
||||
function SystemSliceN1<T>(Self: array[,,,] of T; params l: array of SliceType): array of T; extensionmethod
|
||||
:= SliceN(Self,l) as array of T;
|
||||
///--
|
||||
function SystemSliceN2<T>(Self: array[,] of T; params l: array of SliceType): array[,] of T; extensionmethod
|
||||
:= SliceN(Self,l) as array [,] of T;
|
||||
///--
|
||||
function SystemSliceN2<T>(Self: array[,,] of T; params l: array of SliceType): array[,] of T; extensionmethod
|
||||
:= SliceN(Self,l) as array [,] of T;
|
||||
///--
|
||||
function SystemSliceN2<T>(Self: array[,,,] of T; params l: array of SliceType): array[,] of T; extensionmethod
|
||||
:= SliceN(Self,l) as array [,] of T;
|
||||
///--
|
||||
function SystemSliceN3<T>(Self: array[,,] of T; params l: array of SliceType): array[,,] of T; extensionmethod
|
||||
:= SliceN(Self,l) as array [,,] of T;
|
||||
///--
|
||||
function SystemSliceN3<T>(Self: array[,,,] of T; params l: array of SliceType): array[,,] of T; extensionmethod
|
||||
:= SliceN(Self,l) as array [,,] of T;
|
||||
///--
|
||||
function SystemSliceN4<T>(Self: array[,,,] of T; params l: array of SliceType): array[,,,] of T; extensionmethod
|
||||
:= SliceN(Self,l) as array [,,,] of T;
|
||||
|
||||
// -----------------------------------------------------
|
||||
//>> Методы расширения типа integer # Extension methods for integer
|
||||
// -----------------------------------------------------
|
||||
|
|
|
|||
Loading…
Reference in a new issue