Устранен ряд ошибок в foreach
This commit is contained in:
parent
e4aaf57b99
commit
8f9b8c860f
|
|
@ -15,7 +15,7 @@ internal static class RevisionClass
|
|||
public const string Major = "3";
|
||||
public const string Minor = "2";
|
||||
public const string Build = "0";
|
||||
public const string Revision = "1492";
|
||||
public const string Revision = "1504";
|
||||
|
||||
public const string MainVersion = Major + "." + Minor;
|
||||
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
%MINOR%=2
|
||||
%REVISION%=1492
|
||||
%REVISION%=1504
|
||||
%COREVERSION%=0
|
||||
%MAJOR%=3
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
!define VERSION '3.2.0.1492'
|
||||
!define VERSION '3.2.0.1504'
|
||||
|
|
|
|||
|
|
@ -551,6 +551,27 @@ procedure Read(var x: boolean);
|
|||
/// Вводит значения a,b,... с клавиатуры и осуществляет переход на следующую строку
|
||||
procedure Readln;
|
||||
|
||||
/// Вводит числовое значение x клавиатуры. Возвращает False если при вводе произошла ошибка
|
||||
function TryRead(var x: integer): boolean;
|
||||
///--
|
||||
function TryRead(var x: real): boolean;
|
||||
///--
|
||||
function TryRead(var x: byte): boolean;
|
||||
///--
|
||||
function TryRead(var x: shortint): boolean;
|
||||
///--
|
||||
function TryRead(var x: smallint): boolean;
|
||||
///--
|
||||
function TryRead(var x: word): boolean;
|
||||
///--
|
||||
function TryRead(var x: longword): boolean;
|
||||
///--
|
||||
function TryRead(var x: int64): boolean;
|
||||
///--
|
||||
function TryRead(var x: uint64): boolean;
|
||||
///--
|
||||
function TryRead(var x: single): boolean;
|
||||
|
||||
/// Возвращает значение типа integer, введенное с клавиатуры
|
||||
function ReadInteger: integer;
|
||||
/// Возвращает значение типа real, введенное с клавиатуры
|
||||
|
|
@ -1632,11 +1653,11 @@ procedure Sort<T>(l: List<T>; cmp: (T,T)->integer);
|
|||
procedure Sort<T>(l: List<T>; less: (T,T)->boolean);
|
||||
/// Изменяет порядок элементов в динамическом массиве на противоположный
|
||||
procedure Reverse<T>(a: array of T);
|
||||
/// Изменяет порядок элементов на противоположный в диапазоне динамического массива длины length начиная с индекса index
|
||||
/// Изменяет порядок элементов на противоположный в диапазоне динамического массива длины count, начиная с индекса index
|
||||
procedure Reverse<T>(a: array of T; index,count: integer);
|
||||
/// Изменяет порядок элементов в списке на противоположный
|
||||
procedure Reverse<T>(a: List<T>);
|
||||
/// Изменяет порядок элементов на противоположный в диапазоне списка длины length начиная с индекса index
|
||||
/// Изменяет порядок элементов на противоположный в диапазоне списка длины count, начиная с индекса index
|
||||
procedure Reverse<T>(a: List<T>; index,count: integer);
|
||||
/// Перемешивает динамический массив случайным образом
|
||||
procedure Shuffle<T>(a: array of T);
|
||||
|
|
@ -2614,9 +2635,9 @@ end;
|
|||
class function TypedSet.operator implicit<T>(s: TypedSet): HashSet<T>;
|
||||
begin
|
||||
var hs := new HashSet<T>();
|
||||
foreach key: T in s.ht.Keys do
|
||||
foreach var key in s.ht.Keys do
|
||||
begin
|
||||
hs.Add(key);
|
||||
hs.Add(T(key));
|
||||
end;
|
||||
Result := hs;
|
||||
end;
|
||||
|
|
@ -4460,7 +4481,7 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure read(var x: integer);
|
||||
procedure Read(var x: integer);
|
||||
begin
|
||||
if input.sr <> nil then
|
||||
read(input, x)
|
||||
|
|
@ -4473,7 +4494,7 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure read(var x: real);
|
||||
procedure Read(var x: real);
|
||||
begin
|
||||
if input.sr <> nil then
|
||||
read(input, x)
|
||||
|
|
@ -4486,7 +4507,7 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure read(var x: char);
|
||||
procedure Read(var x: char);
|
||||
begin
|
||||
if input.sr <> nil then
|
||||
read(input, x)
|
||||
|
|
@ -4499,7 +4520,7 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure read(var x: string);
|
||||
procedure Read(var x: string);
|
||||
begin
|
||||
if input.sr <> nil then
|
||||
read(input, x)
|
||||
|
|
@ -4512,7 +4533,7 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure read(var x: byte);
|
||||
procedure Read(var x: byte);
|
||||
begin
|
||||
if input.sr <> nil then
|
||||
read(input, x)
|
||||
|
|
@ -4525,7 +4546,7 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure read(var x: shortint);
|
||||
procedure Read(var x: shortint);
|
||||
begin
|
||||
if input.sr <> nil then
|
||||
read(input, x)
|
||||
|
|
@ -4538,7 +4559,7 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure read(var x: smallint);
|
||||
procedure Read(var x: smallint);
|
||||
begin
|
||||
if input.sr <> nil then
|
||||
read(input, x)
|
||||
|
|
@ -4551,7 +4572,7 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure read(var x: word);
|
||||
procedure Read(var x: word);
|
||||
begin
|
||||
if input.sr <> nil then
|
||||
read(input, x)
|
||||
|
|
@ -4564,7 +4585,7 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure read(var x: longword);
|
||||
procedure Read(var x: longword);
|
||||
begin
|
||||
if input.sr <> nil then
|
||||
read(input, x)
|
||||
|
|
@ -4577,7 +4598,7 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure read(var x: int64);
|
||||
procedure Read(var x: int64);
|
||||
begin
|
||||
if input.sr <> nil then
|
||||
read(input, x)
|
||||
|
|
@ -4590,7 +4611,7 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure read(var x: uint64);
|
||||
procedure Read(var x: uint64);
|
||||
begin
|
||||
if input.sr <> nil then
|
||||
read(input, x)
|
||||
|
|
@ -4603,7 +4624,7 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure read(var x: single);
|
||||
procedure Read(var x: single);
|
||||
begin
|
||||
if input.sr <> nil then
|
||||
read(input, x)
|
||||
|
|
@ -4616,7 +4637,7 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure read(var x: boolean);
|
||||
procedure Read(var x: boolean);
|
||||
begin
|
||||
if input.sr <> nil then
|
||||
read(input, x)
|
||||
|
|
@ -4629,6 +4650,107 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function TryRead(var x: integer): boolean;
|
||||
begin
|
||||
Result := True;
|
||||
try
|
||||
Read(x)
|
||||
except
|
||||
Result := False;
|
||||
end
|
||||
end;
|
||||
|
||||
function TryRead(var x: real): boolean;
|
||||
begin
|
||||
Result := True;
|
||||
try
|
||||
Read(x)
|
||||
except
|
||||
Result := False;
|
||||
end
|
||||
end;
|
||||
|
||||
function TryRead(var x: byte): boolean;
|
||||
begin
|
||||
Result := True;
|
||||
try
|
||||
Read(x)
|
||||
except
|
||||
Result := False;
|
||||
end
|
||||
end;
|
||||
|
||||
function TryRead(var x: shortint): boolean;
|
||||
begin
|
||||
Result := True;
|
||||
try
|
||||
Read(x)
|
||||
except
|
||||
Result := False;
|
||||
end
|
||||
end;
|
||||
|
||||
function TryRead(var x: smallint): boolean;
|
||||
begin
|
||||
Result := True;
|
||||
try
|
||||
Read(x)
|
||||
except
|
||||
Result := False;
|
||||
end
|
||||
end;
|
||||
|
||||
function TryRead(var x: word): boolean;
|
||||
begin
|
||||
Result := True;
|
||||
try
|
||||
Read(x)
|
||||
except
|
||||
Result := False;
|
||||
end
|
||||
end;
|
||||
|
||||
function TryRead(var x: longword): boolean;
|
||||
begin
|
||||
Result := True;
|
||||
try
|
||||
Read(x)
|
||||
except
|
||||
Result := False;
|
||||
end
|
||||
end;
|
||||
|
||||
function TryRead(var x: int64): boolean;
|
||||
begin
|
||||
Result := True;
|
||||
try
|
||||
Read(x)
|
||||
except
|
||||
Result := False;
|
||||
end
|
||||
end;
|
||||
|
||||
function TryRead(var x: uint64): boolean;
|
||||
begin
|
||||
Result := True;
|
||||
try
|
||||
Read(x)
|
||||
except
|
||||
Result := False;
|
||||
end
|
||||
end;
|
||||
|
||||
function TryRead(var x: single): boolean;
|
||||
begin
|
||||
Result := True;
|
||||
try
|
||||
Read(x)
|
||||
except
|
||||
Result := False;
|
||||
end
|
||||
end;
|
||||
|
||||
|
||||
function ReadInteger: integer;
|
||||
begin
|
||||
var x: integer;
|
||||
|
|
@ -10697,7 +10819,7 @@ begin
|
|||
input := new TextFile();
|
||||
//var tmp := __CONFIG__;
|
||||
if (Environment.OSVersion.Platform = PlatformID.Unix) or (Environment.OSVersion.Platform = PlatformID.MacOSX) then
|
||||
foreach listener: System.Diagnostics.TraceListener in System.Diagnostics.Trace.Listeners do
|
||||
foreach var listener in System.Diagnostics.Trace.Listeners do
|
||||
if listener is System.Diagnostics.DefaultTraceListener then
|
||||
(listener as System.Diagnostics.DefaultTraceListener).AssertUiEnabled := true;
|
||||
end;
|
||||
|
|
|
|||
9
TestSuite/CompilationSamples/foreach_ArrayList.pas
Normal file
9
TestSuite/CompilationSamples/foreach_ArrayList.pas
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
begin
|
||||
//var a: array [1..5] of integer := (1,3,5,7,9);
|
||||
//var a := Arr(1,2,3,4,5);
|
||||
//var a := Arr(1.0,2.0);
|
||||
var a := new System.Collections.ArrayList();
|
||||
a.Add(2);
|
||||
foreach x: integer in a do
|
||||
Print(x);
|
||||
end.
|
||||
14
TestSuite/CompilationSamples/foreach_Person_Student.pas
Normal file
14
TestSuite/CompilationSamples/foreach_Person_Student.pas
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
type
|
||||
Person = class
|
||||
|
||||
end;
|
||||
Student = class(Person)
|
||||
public
|
||||
i: integer;
|
||||
end;
|
||||
|
||||
begin
|
||||
var persons := Arr(new Student, new Student);
|
||||
foreach x: Person in persons do
|
||||
Print(x.GetType);
|
||||
end.
|
||||
8
TestSuite/CompilationSamples/foreach_real_int.pas
Normal file
8
TestSuite/CompilationSamples/foreach_real_int.pas
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
begin
|
||||
//var a: array [1..5] of integer := (1,3,5,7,9);
|
||||
var a := Arr(1,2,3,4,5);
|
||||
//var a := Arr(1.0,2.0);
|
||||
//var a := new System.Collections.ArrayList();
|
||||
foreach x: real in a do
|
||||
Print(x);
|
||||
end.
|
||||
8
TestSuite/errors/err0226.pas
Normal file
8
TestSuite/errors/err0226.pas
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
begin
|
||||
//var a: array [1..5] of integer := (1,3,5,7,9);
|
||||
//var a := Arr(1,2,3,4,5);
|
||||
var a := Arr(1.0,2.0);
|
||||
//var a := new System.Collections.ArrayList();
|
||||
foreach x: integer in a do
|
||||
Print(x);
|
||||
end.
|
||||
14
TestSuite/errors/err0227.pas
Normal file
14
TestSuite/errors/err0227.pas
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
type
|
||||
Person = class
|
||||
|
||||
end;
|
||||
Student = class(Person)
|
||||
public
|
||||
i: integer;
|
||||
end;
|
||||
|
||||
begin
|
||||
var persons := Arr(new Person, new Person);
|
||||
foreach x: Student in persons do
|
||||
Print(x.GetType);
|
||||
end.
|
||||
|
|
@ -426,8 +426,8 @@ namespace TreeConverter.LambdaExpressions.Closure
|
|||
type_node elemType = null;
|
||||
if (inWhat.type == null)
|
||||
inWhat = tmp;
|
||||
|
||||
_visitor.FindIEnumerableElementType(/*_foreach_stmt, */inWhat.type, ref elemType);
|
||||
bool bb; // здесь bb не нужно. Оно нужно в foreach
|
||||
_visitor.FindIEnumerableElementType(/*_foreach_stmt, */inWhat.type, ref elemType, out bb);
|
||||
|
||||
if (_foreach_stmt.type_name == null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -599,7 +599,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
possible_type_convertions pct = type_table.get_convertions(from, to);
|
||||
if (pct.second != null)
|
||||
throw new TwoTypeConversionsPossibleT(pct.first, pct.second, loc);
|
||||
if (pct.first == null && !type_table.is_derived(from, to))
|
||||
if (pct.first == null /*&& !type_table.is_derived(from, to)*/)
|
||||
throw new CanNotConvertTypes(null, from, to, loc);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15970,7 +15970,8 @@ namespace PascalABCCompiler.TreeConverter
|
|||
var tt = to.type;
|
||||
type_node elem_type = null;
|
||||
try_convert_typed_expression_to_function_call(ref from);
|
||||
var b = FindIEnumerableElementType(from.type, ref elem_type);
|
||||
bool bb; // здесь bb не нужно. Оно нужно в foreach
|
||||
var b = FindIEnumerableElementType(from.type, ref elem_type, out bb);
|
||||
if (!b)
|
||||
AddError(from.location, "CAN_NOT_EXECUTE_FOREACH_BY_EXPR_OF_TYPE_{0}", from.type.full_name);
|
||||
|
||||
|
|
@ -16558,8 +16559,9 @@ namespace PascalABCCompiler.TreeConverter
|
|||
return false;
|
||||
}
|
||||
|
||||
public bool FindIEnumerableElementType(/*SyntaxTree.foreach_stmt _foreach_stmt, */type_node tn, ref type_node elem_type)
|
||||
public bool FindIEnumerableElementType(type_node tn, ref type_node elem_type, out bool sys_coll_ienum)
|
||||
{
|
||||
sys_coll_ienum = false;
|
||||
var IEnstring = "System.Collections.IEnumerable";
|
||||
compiled_type_node ctn = compiled_type_node.get_type_node(NetHelper.NetHelper.FindType(IEnstring));
|
||||
if (tn is compiled_type_node || tn is compiled_generic_instance_type_node) // Если этот тип зашит в .NET
|
||||
|
|
@ -16628,6 +16630,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
if (itn == ctn)
|
||||
{
|
||||
elem_type = SystemLibrary.SystemLibrary.object_type;
|
||||
sys_coll_ienum = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -16691,6 +16694,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
if (itn == ctn)
|
||||
{
|
||||
elem_type = SystemLibrary.SystemLibrary.object_type;
|
||||
sys_coll_ienum = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -16717,7 +16721,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
expression_node in_what = convert_strong(_foreach_stmt.in_what);
|
||||
|
||||
// SSM 29.07.16 - если in_what - одномерный массив, то заменить код foreach на for
|
||||
var is1dimdynarr = false;
|
||||
/*var is1dimdynarr = false;
|
||||
var comptn = in_what.type as compiled_type_node;
|
||||
if (comptn != null && comptn.type_special_kind == SemanticTree.type_special_kind.array_kind && comptn.rank == 1)
|
||||
{
|
||||
|
|
@ -16775,7 +16779,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
//visit(fornode);
|
||||
|
||||
return;
|
||||
}
|
||||
}*/
|
||||
/// SSM 29.07.16
|
||||
|
||||
//throw new NotSupportedError(get_location(_foreach_stmt));
|
||||
|
|
@ -16793,8 +16797,8 @@ namespace PascalABCCompiler.TreeConverter
|
|||
|
||||
//(in_what.type as common_type_node).internal_type_special_kind == SemanticTree.type_special_kind.array_kind
|
||||
//in_what.type as compiled_type_node
|
||||
|
||||
if (!FindIEnumerableElementType(/*_foreach_stmt, */in_what.type, ref elem_type))
|
||||
bool sys_coll_ienum; // bb = true означает, что мы нашли тип object у интерфейса System.Collections.IEnumerable
|
||||
if (!FindIEnumerableElementType(in_what.type, ref elem_type, out sys_coll_ienum))
|
||||
//if (!IsGetEnumerator(in_what.type, ref elem_type))
|
||||
AddError(in_what.location, "CAN_NOT_EXECUTE_FOREACH_BY_EXPR_OF_TYPE_{0}", in_what.type.name);
|
||||
|
||||
|
|
@ -16829,8 +16833,8 @@ namespace PascalABCCompiler.TreeConverter
|
|||
}
|
||||
|
||||
//elem_type = vdn.type;
|
||||
if (!(vdn.type is compiled_generic_instance_type_node))
|
||||
convertion_data_and_alghoritms.check_convert_type_with_inheritance(vdn.type, elem_type, get_location(_foreach_stmt.identifier));
|
||||
if (!(vdn.type is compiled_generic_instance_type_node) && !sys_coll_ienum)
|
||||
convertion_data_and_alghoritms.check_convert_type_with_inheritance(elem_type, vdn.type, get_location(_foreach_stmt.identifier));
|
||||
|
||||
//if (!convertion_data_and_alghoritms.eq_type_nodes(elem_type, vdn.type))
|
||||
//AddError(new TypesOfVarAndElementsInForeachMustBeEqual(vdn.type.name,elem_type.name,get_location(_foreach_stmt.identifier)));
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1653,11 +1653,11 @@ procedure Sort<T>(l: List<T>; cmp: (T,T)->integer);
|
|||
procedure Sort<T>(l: List<T>; less: (T,T)->boolean);
|
||||
/// Изменяет порядок элементов в динамическом массиве на противоположный
|
||||
procedure Reverse<T>(a: array of T);
|
||||
/// Изменяет порядок элементов на противоположный в диапазоне динамического массива длины length начиная с индекса index
|
||||
/// Изменяет порядок элементов на противоположный в диапазоне динамического массива длины count, начиная с индекса index
|
||||
procedure Reverse<T>(a: array of T; index,count: integer);
|
||||
/// Изменяет порядок элементов в списке на противоположный
|
||||
procedure Reverse<T>(a: List<T>);
|
||||
/// Изменяет порядок элементов на противоположный в диапазоне списка длины length начиная с индекса index
|
||||
/// Изменяет порядок элементов на противоположный в диапазоне списка длины count, начиная с индекса index
|
||||
procedure Reverse<T>(a: List<T>; index,count: integer);
|
||||
/// Перемешивает динамический массив случайным образом
|
||||
procedure Shuffle<T>(a: array of T);
|
||||
|
|
@ -2635,9 +2635,9 @@ end;
|
|||
class function TypedSet.operator implicit<T>(s: TypedSet): HashSet<T>;
|
||||
begin
|
||||
var hs := new HashSet<T>();
|
||||
foreach key: T in s.ht.Keys do
|
||||
foreach var key in s.ht.Keys do
|
||||
begin
|
||||
hs.Add(key);
|
||||
hs.Add(T(key));
|
||||
end;
|
||||
Result := hs;
|
||||
end;
|
||||
|
|
@ -10819,7 +10819,7 @@ begin
|
|||
input := new TextFile();
|
||||
//var tmp := __CONFIG__;
|
||||
if (Environment.OSVersion.Platform = PlatformID.Unix) or (Environment.OSVersion.Platform = PlatformID.MacOSX) then
|
||||
foreach listener: System.Diagnostics.TraceListener in System.Diagnostics.Trace.Listeners do
|
||||
foreach var listener in System.Diagnostics.Trace.Listeners do
|
||||
if listener is System.Diagnostics.DefaultTraceListener then
|
||||
(listener as System.Diagnostics.DefaultTraceListener).AssertUiEnabled := true;
|
||||
end;
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Reference in a new issue