Многомерные срезы - пока без семантического контроля

И интеллисенс a[1,:] неверно показывает тип
This commit is contained in:
Mikhalkovich Stanislav 2021-02-24 18:41:51 +03:00
parent 7c3273aae8
commit 05f158875d
16 changed files with 154 additions and 50 deletions

View file

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

View file

@ -1,4 +1,4 @@
%MINOR%=7
%REVISION%=2827
%COREVERSION%=2
%REVISION%=2830
%MINOR%=7
%MAJOR%=3

View file

@ -2,7 +2,7 @@
// This CSharp output file generated by Gardens Point LEX
// Version: 1.1.3.301
// Machine: DESKTOP-G8V08V4
// DateTime: 24.02.2021 0:24:55
// DateTime: 24.02.2021 14:31:41
// UserName: ?????????
// GPLEX input file <ABCPascal.lex>
// GPLEX frame file <embedded resource>

View file

@ -4185,7 +4185,7 @@ variable
}
else
{
ll.Add(Tuple.Create(ex, ex, (expression)new int32_const(int.MaxValue, ex.source_context))); // ñêàëÿðíîå çíà÷åíèå âìåñòî ñðåçà
ll.Add(Tuple.Create(ex, (expression)new int32_const(0, ex.source_context), (expression)new int32_const(int.MaxValue, ex.source_context))); // ñêàëÿðíîå çíà÷åíèå âìåñòî ñðåçà
}
}
var sle = new slice_expr($1 as addressed_value,null,null,null,@$);

View file

@ -2,7 +2,7 @@
// GPPG version 1.3.6
// Machine: DESKTOP-G8V08V4
// DateTime: 24.02.2021 0:24:55
// DateTime: 24.02.2021 14:31:42
// UserName: ?????????
// Input file <D:\PABC_Git\Parsers\PascalABCParserNewSaushkin\ABCPascal.y>
@ -6609,7 +6609,7 @@ public partial class GPPGParser: ShiftReduceParser<PascalABCSavParser.Union, Lex
}
else
{
ll.Add(Tuple.Create(ex, ex, (expression)new int32_const(int.MaxValue, ex.source_context))); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
ll.Add(Tuple.Create(ex, (expression)new int32_const(0, ex.source_context), (expression)new int32_const(int.MaxValue, ex.source_context))); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
}
}
var sle = new slice_expr(ValueStack[ValueStack.Depth-4].ex as addressed_value,null,null,null,CurrentLocationSpan);

View file

@ -313,5 +313,6 @@ script=

View file

@ -1 +1 @@
3.7.2.2827
3.7.2.2830

View file

@ -1 +1 @@
!define VERSION '3.7.2.2827'
!define VERSION '3.7.2.2830'

View file

@ -47,7 +47,8 @@ namespace PascalABCCompiler.SyntaxTreeConverters
// tuple_node
TupleVisitor.New.ProcessNode(root);
// index
// index
IndexVisitor.New.ProcessNode(root);
// assign_tuple и assign_var_tuple
@ -56,6 +57,7 @@ namespace PascalABCCompiler.SyntaxTreeConverters
// slice_expr и slice_expr_question
SliceDesugarVisitor.New.ProcessNode(root);
// question_point_desugar_visitor
QuestionPointDesugarVisitor.New.ProcessNode(root);

View file

@ -61,7 +61,7 @@ namespace SyntaxVisitors.SugarVisitors
mc = indexCreation;
}
//var sug = new sugared_expression(ind, mc, ind.source_context);
Replace(ind, mc);
ReplaceUsingParent(ind, mc);
visit(mc);
}

View file

@ -25,10 +25,16 @@ namespace SyntaxVisitors.SugarVisitors
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);
// пытаемся разобраться с ^1
var sl1 = slice.Item1;
eel.Add(sl1);
IndexVisitor.New.ProcessNode(sl1); // индексный визитор сам не вызывается поскольку в многомерных срезах хранится List кортежей троек expression, который сам не обходится
var sl2 = slice.Item2;
eel.Add(slice.Item2);
IndexVisitor.New.ProcessNode(sl2);
eel.Add(slice.Item3);
var mc = new method_call(tup, eel, sc); // sc - не очень хорошо - ошибка будет в общем месте
el.Add(mc);
@ -51,7 +57,7 @@ namespace SyntaxVisitors.SugarVisitors
if (sl.from is index fromInd)
{
fromInverted = fromInd.inverted;
fromInverted = fromInd.inverted; // странно, но не используется
fromExpr = fromInd.index_expr;
}
@ -59,7 +65,7 @@ namespace SyntaxVisitors.SugarVisitors
var toExpr = sl.to;
if (sl.to is index toInd)
{
toInverted = toInd.inverted;
toInverted = toInd.inverted; // странно, но не используется
toExpr = toInd.index_expr;
}
@ -142,8 +148,9 @@ namespace SyntaxVisitors.SugarVisitors
// Столько - сколько в 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);
var sug = sugared_addressed_value.NewP(sl, mc, sl.source_context);
// пока без семантической проверки
ReplaceUsingParent(sl, mc);
ReplaceUsingParent(sl, sug);
visit(mc);
}
}

View file

@ -12046,20 +12046,26 @@ end;
type
SliceType = class
situation,from, &to, step, count: integer;
oneelem: boolean;
constructor (sit,f,t: integer; st: integer := 1; oneel: boolean := false);
fromInverted, toInverted: boolean;
function oneelem: boolean := step = integer.MaxValue; // если шаг = integer.MaxValue, то это один элемент, а не срез (договорённость)
constructor (sit,f,t: integer; st: integer := 1);
begin
situation := sit;
from := f;
&to := t;
fromInverted := False;
toInverted := False;
step := st;
count := -1; // заполняется во внешней функции
oneelem := oneel;
if step = integer.MaxValue then
oneelem := True;
count := -1; // заполняется во внешней функции CorrectSliceAndCalcCount при известной длине по данной размерности
//oneelem := step = integer.MaxValue; // если шаг = integer.MaxValue, то это один элемент, а не срез (договорённость)
end;
procedure CorrectSliceAndCalcCount(len: integer);
begin
if fromInverted then // Надеюсь, что ровно здесь. Это означает, что эти значения точно не пропущены
from := len - from;
if toInverted then
&to := len - &to;
if oneelem then
count := 1
else count := CheckAndCorrectFromToAndCalcCountForSystemSlice(situation, len, from, &to, step);
@ -12067,21 +12073,28 @@ type
static function operator implicit(i: integer): SliceType;
static function operator implicit(ir: IntRange): SliceType;
static function operator implicit(sl: (integer,integer,integer)): SliceType;
static function operator implicit(sl: (SystemIndex,SystemIndex,integer)): SliceType; // a[^1:,^2]
static function operator implicit(sl: (integer,SystemIndex,integer)): SliceType; // a[^1:,^2]
static function operator implicit(sl: (SystemIndex,integer,integer)): SliceType; // a[^1:,^2]
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;
function Diap(f, t: integer) := new SliceType(0, f, t, 1);
function Elem(ind: integer) := new SliceType(0, ind, ind+1, integer.MaxValue);
function Slice(f, t: integer; st: integer := 1): 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);
Result := new SliceType(sit, f, t, st);
end;
{function Slice(f, t: SystemIndex; st: integer := 1): SliceType;
begin
Result := Slice(f.IndexValue, t.IndexValue, st);
Result.fromInverted := f.IsInverted;
Result.toInverted := t.IsInverted;
end;}
static function SliceType.operator implicit(i: integer): SliceType;
begin
@ -12098,6 +12111,24 @@ begin
Result := Slice(sl[0],sl[1],sl[2]);
end;
static function SliceType.operator implicit(sl: (SystemIndex,SystemIndex,integer)): SliceType;
begin
Result := Slice(sl[0].IndexValue,sl[1].IndexValue,sl[2]);
Result.fromInverted := sl[0].IsInverted;
Result.toInverted := sl[1].IsInverted;
end;
static function SliceType.operator implicit(sl: (integer,SystemIndex,integer)): SliceType;
begin
Result := Slice(sl[0],sl[1].IndexValue,sl[2]);
Result.toInverted := sl[1].IsInverted;
end;
static function SliceType.operator implicit(sl: (SystemIndex,integer,integer)): SliceType;
begin
Result := Slice(sl[0].IndexValue,sl[1],sl[2]);
Result.fromInverted := sl[0].IsInverted;
end;
function ToOneDim<T>(a: array [,] of T; l: array of SliceType): array of T;
begin
@ -12192,7 +12223,6 @@ 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
@ -12207,7 +12237,6 @@ 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
@ -12223,7 +12252,6 @@ 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
@ -12266,7 +12294,7 @@ begin
Result := FromOneDimN(r,l);
end;
{type
{type // это не компилируется в PABCSystem
ArrT<T> = array of T;
Arr2T<T> = array [,] of T;
Arr3T<T> = array [,,] of T;

View file

@ -0,0 +1,30 @@
procedure AssertEq<T>(m: array [,] of T; a: array of array of T);
begin
Assert(m.MatrEqual(MatrByRow(a)));
end;
procedure AssertEq<T>(m,a: array [,] of T);
begin
Assert(m.MatrEqual(a));
end;
procedure AssertEq<T>(m: array of T; a: array of T);
begin
Assert(m.SequenceEqual(a));
end;
begin
var d := [[6,7,8],[10,11,12]];
var m := MatrByRow(||1,2,3,4|,|5,6,7,8|,|9,10,11,12||);
AssertEq(m[:,:],m);
AssertEq(m[::1,::1],m);
AssertEq(m[1:3,1:4],||6,7,8|,|10,11,12||);
AssertEq(m[::2,::3],||1,4|,|9,12||);
AssertEq(m[::-2,::-1],||12,11,10,9|,|4,3,2,1||);
AssertEq(m[^2::-1,^2::-1],||7,6,5|,|3,2,1||);
AssertEq(m[:^1,:^1],||1,2,3|,|5,6,7||);
AssertEq(m[1,:],|5,6,7,8|);
AssertEq(m[^1,:],|9,10,11,12|);
AssertEq(m[:,^1],|4,8,12|);
Print(m[:,^1]);
end.

View file

@ -136,6 +136,12 @@ namespace PascalABCCompiler.TreeConverter
}
}
void semantic_check_method_call_as_slice_expr_multi(SyntaxTree.method_call mc)
{
}
/*void semantic_check_tuple(SyntaxTree.tuple_node tup)
{
//if (tup.el.expressions.Count > 7)

View file

@ -21019,9 +21019,11 @@ namespace PascalABCCompiler.TreeConverter
{
semantic_check_method_call_as_diapason_expr(av.new_addr_value as SyntaxTree.method_call);
}
else if (av.sugared_expr is SyntaxTree.slice_expr) // и slice_expr_question
else if (av.sugared_expr is SyntaxTree.slice_expr slex) // и slice_expr_question
{
semantic_check_method_call_as_slice_expr(av.new_addr_value as SyntaxTree.method_call);
if (slex.slices == null)
semantic_check_method_call_as_slice_expr(av.new_addr_value as SyntaxTree.method_call);
else semantic_check_method_call_as_slice_expr_multi(av.new_addr_value as SyntaxTree.method_call);
}
else if (av.sugared_expr is SyntaxTree.dot_question_node)
{

View file

@ -12046,20 +12046,26 @@ end;
type
SliceType = class
situation,from, &to, step, count: integer;
oneelem: boolean;
constructor (sit,f,t: integer; st: integer := 1; oneel: boolean := false);
fromInverted, toInverted: boolean;
function oneelem: boolean := step = integer.MaxValue; // если шаг = integer.MaxValue, то это один элемент, а не срез (договорённость)
constructor (sit,f,t: integer; st: integer := 1);
begin
situation := sit;
from := f;
&to := t;
fromInverted := False;
toInverted := False;
step := st;
count := -1; // заполняется во внешней функции
oneelem := oneel;
if step = integer.MaxValue then
oneelem := True;
count := -1; // заполняется во внешней функции CorrectSliceAndCalcCount при известной длине по данной размерности
//oneelem := step = integer.MaxValue; // если шаг = integer.MaxValue, то это один элемент, а не срез (договорённость)
end;
procedure CorrectSliceAndCalcCount(len: integer);
begin
if fromInverted then // Надеюсь, что ровно здесь. Это означает, что эти значения точно не пропущены
from := len - from;
if toInverted then
&to := len - &to;
if oneelem then
count := 1
else count := CheckAndCorrectFromToAndCalcCountForSystemSlice(situation, len, from, &to, step);
@ -12067,21 +12073,28 @@ type
static function operator implicit(i: integer): SliceType;
static function operator implicit(ir: IntRange): SliceType;
static function operator implicit(sl: (integer,integer,integer)): SliceType;
static function operator implicit(sl: (SystemIndex,SystemIndex,integer)): SliceType; // a[^1:,^2]
static function operator implicit(sl: (integer,SystemIndex,integer)): SliceType; // a[^1:,^2]
static function operator implicit(sl: (SystemIndex,integer,integer)): SliceType; // a[^1:,^2]
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;
function Diap(f, t: integer) := new SliceType(0, f, t, 1);
function Elem(ind: integer) := new SliceType(0, ind, ind+1, integer.MaxValue);
function Slice(f, t: integer; st: integer := 1): 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);
Result := new SliceType(sit, f, t, st);
end;
{function Slice(f, t: SystemIndex; st: integer := 1): SliceType;
begin
Result := Slice(f.IndexValue, t.IndexValue, st);
Result.fromInverted := f.IsInverted;
Result.toInverted := t.IsInverted;
end;}
static function SliceType.operator implicit(i: integer): SliceType;
begin
@ -12098,6 +12111,24 @@ begin
Result := Slice(sl[0],sl[1],sl[2]);
end;
static function SliceType.operator implicit(sl: (SystemIndex,SystemIndex,integer)): SliceType;
begin
Result := Slice(sl[0].IndexValue,sl[1].IndexValue,sl[2]);
Result.fromInverted := sl[0].IsInverted;
Result.toInverted := sl[1].IsInverted;
end;
static function SliceType.operator implicit(sl: (integer,SystemIndex,integer)): SliceType;
begin
Result := Slice(sl[0],sl[1].IndexValue,sl[2]);
Result.toInverted := sl[1].IsInverted;
end;
static function SliceType.operator implicit(sl: (SystemIndex,integer,integer)): SliceType;
begin
Result := Slice(sl[0].IndexValue,sl[1],sl[2]);
Result.fromInverted := sl[0].IsInverted;
end;
function ToOneDim<T>(a: array [,] of T; l: array of SliceType): array of T;
begin
@ -12192,7 +12223,6 @@ 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
@ -12207,7 +12237,6 @@ 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
@ -12223,7 +12252,6 @@ 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
@ -12266,7 +12294,7 @@ begin
Result := FromOneDimN(r,l);
end;
{type
{type // это не компилируется в PABCSystem
ArrT<T> = array of T;
Arr2T<T> = array [,] of T;
Arr3T<T> = array [,,] of T;