diff --git a/Configuration/GlobalAssemblyInfo.cs b/Configuration/GlobalAssemblyInfo.cs index 45654ce1a..11a9e587d 100644 --- a/Configuration/GlobalAssemblyInfo.cs +++ b/Configuration/GlobalAssemblyInfo.cs @@ -15,7 +15,7 @@ internal static class RevisionClass public const string Major = "3"; public const string Minor = "8"; public const string Build = "3"; - public const string Revision = "3214"; + public const string Revision = "3218"; public const string MainVersion = Major + "." + Minor; public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision; diff --git a/Configuration/Version.defs b/Configuration/Version.defs index 7fd08ee74..ae14e7ec3 100644 --- a/Configuration/Version.defs +++ b/Configuration/Version.defs @@ -1,4 +1,4 @@ %COREVERSION%=3 -%REVISION%=3214 +%REVISION%=3218 %MINOR%=8 %MAJOR%=3 diff --git a/Release/pabcversion.txt b/Release/pabcversion.txt index 881b5b4e1..6b2d5e699 100644 --- a/Release/pabcversion.txt +++ b/Release/pabcversion.txt @@ -1 +1 @@ -3.8.3.3214 +3.8.3.3218 diff --git a/ReleaseGenerators/PascalABCNET_version.nsh b/ReleaseGenerators/PascalABCNET_version.nsh index 64a6a6b56..63e71cecb 100644 --- a/ReleaseGenerators/PascalABCNET_version.nsh +++ b/ReleaseGenerators/PascalABCNET_version.nsh @@ -1 +1 @@ -!define VERSION '3.8.3.3214' +!define VERSION '3.8.3.3218' diff --git a/TestSuite/CompilationSamples/ArrOfTuplesvsTupleUnpack.pas b/TestSuite/CompilationSamples/ArrOfTuplesvsTupleUnpack.pas new file mode 100644 index 000000000..748ec5e41 --- /dev/null +++ b/TestSuite/CompilationSamples/ArrOfTuplesvsTupleUnpack.pas @@ -0,0 +1,4 @@ +begin + var arr:=|12,23,34,45,56,67,78,89|; + arr.Numerate.Nwise(3).where(\(\(a,b),\(c,d),\(e,f)) → a(Self: sequence of T; n: integer):sequence of array of T; extensionmethod; +function Nwise(Self: sequence of T; n: integer): sequence of array of T; extensionmethod; begin var chunk := new Queue(n); foreach var x in Self do diff --git a/TreeConverter/TreeConversion/SyntaxTreeVisitorNodes/Foreach.cs b/TreeConverter/TreeConversion/SyntaxTreeVisitorNodes/Foreach.cs index 799136f63..c60ae0547 100644 --- a/TreeConverter/TreeConversion/SyntaxTreeVisitorNodes/Foreach.cs +++ b/TreeConverter/TreeConversion/SyntaxTreeVisitorNodes/Foreach.cs @@ -91,15 +91,9 @@ namespace PascalABCCompiler.TreeConverter if (t == null) AddError(inwhatloc, "TUPLE_OR_SEQUENCE_EXPECTED_FOREACH"); - var IsTuple = false; - var IsSequence = false; - if (t.FullName.StartsWith("System.Tuple") || t.FullName.StartsWith("System.ValueTuple")) - IsTuple = true; - if (!IsTuple) - { - if (t.Name.Equals("IEnumerable`1") || t.GetInterface("IEnumerable`1") != null) - IsSequence = true; - } + var IsTuple = IsTupleType(t); + var IsSequence = !IsTuple && IsSequenceType(t); + if (!IsTuple && !IsSequence) { AddError(inwhatloc, "TUPLE_OR_SEQUENCE_EXPECTED_FOREACH"); diff --git a/TreeConverter/TreeConversion/semantic_checks_for_sugar.cs b/TreeConverter/TreeConversion/semantic_checks_for_sugar.cs index 80a94a147..81853eab9 100644 --- a/TreeConverter/TreeConversion/semantic_checks_for_sugar.cs +++ b/TreeConverter/TreeConversion/semantic_checks_for_sugar.cs @@ -20,15 +20,9 @@ namespace PascalABCCompiler.TreeConverter if (t == null) AddError(expr.location, "TUPLE_OR_SEQUENCE_EXPECTED"); - var IsTuple = false; - var IsSequence = false; - if (t.FullName.StartsWith("System.Tuple") || t.FullName.StartsWith("System.ValueTuple")) - IsTuple = true; - if (!IsTuple) - { - if (t.Name.Equals("IEnumerable`1") || t.GetInterface("IEnumerable`1") != null) - IsSequence = true; - } + var IsTuple = IsTupleType(t); + var IsSequence = !IsTuple && IsSequenceType(t); + if (!IsTuple && !IsSequence) { AddError(expr.location, "TUPLE_OR_SEQUENCE_EXPECTED"); @@ -52,15 +46,9 @@ namespace PascalABCCompiler.TreeConverter if (t == null) AddError(expr.location, "TUPLE_OR_SEQUENCE_EXPECTED"); - var IsTuple = false; - var IsSequence = false; - if (t.FullName.StartsWith("System.Tuple") || t.FullName.StartsWith("System.ValueTuple")) - IsTuple = true; - if (!IsTuple) - { - if (t.Name.Equals("IEnumerable`1") || t.GetInterface("IEnumerable`1") != null) - IsSequence = true; - } + var IsTuple = IsTupleType(t); + var IsSequence = !IsTuple && IsSequenceType(t); + if (!IsTuple && !IsSequence) { AddError(expr.location, "TUPLE_OR_SEQUENCE_EXPECTED"); diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index 8bc0d4501..05f3a050c 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -15939,7 +15939,7 @@ namespace PascalABCCompiler.TreeConverter if (ent != null) { var t = ent.compiled_type; - if (t != null && !t.IsArray && t.FullName.StartsWith("System.Tuple")) + if (t != null && IsTupleType(t)) { expression eee = parameters.expressions[0]; @@ -21421,6 +21421,16 @@ namespace PascalABCCompiler.TreeConverter ProcessNode(av.new_addr_value); // обойти десахарное } + public bool IsTupleType(Type t) + { + return !t.IsArray && (t.FullName.StartsWith("System.Tuple") || t.FullName.StartsWith("System.ValueTuple")); + } + + public bool IsSequenceType(Type t) + { + return t.Name.Equals("IEnumerable`1") || t.GetInterface("IEnumerable`1") != null; + } + private void CheckUnpacking(expression ex, out expression_node sem_ex, out bool IsTuple, out bool IsSequence, int countvars, syntax_tree_node stn) { sem_ex = convert_strong(ex); @@ -21428,15 +21438,10 @@ namespace PascalABCCompiler.TreeConverter var t = ConvertSemanticTypeNodeToNETType(sem_ex.type); if (t == null) AddError(sem_ex.location, "TUPLE_OR_SEQUENCE_EXPECTED"); - IsTuple = false; - IsSequence = false; - if (t.FullName.StartsWith("System.Tuple")) - IsTuple = true; - if (!IsTuple) - { - if (t.Name.Equals("IEnumerable`1") || t.GetInterface("IEnumerable`1") != null) - IsSequence = true; - } + + IsTuple = IsTupleType(t); + IsSequence = !IsTuple && IsSequenceType(t); + if (!IsTuple && !IsSequence) { AddError(sem_ex.location, "TUPLE_OR_SEQUENCE_EXPECTED"); @@ -21508,11 +21513,11 @@ namespace PascalABCCompiler.TreeConverter var IsTuple = false; var IsSequence = false; - if (t.FullName.StartsWith("System.Tuple")) + if (IsTupleType(t)) IsTuple = true; if (!IsTuple) { - if (t.Name.Equals("IEnumerable`1") || t.GetInterface("IEnumerable`1") != null) + if (IsSequenceType(t)) IsSequence = true; } if (!IsTuple && !IsSequence) @@ -21572,15 +21577,10 @@ namespace PascalABCCompiler.TreeConverter var t = ConvertSemanticTypeNodeToNETType(sem_ex.type); if (t == null) AddError(sem_ex.location, "TUPLE_OR_SEQUENCE_EXPECTED"); - var IsTuple = false; - var IsSequence = false; - if ((t.FullName.StartsWith("System.Tuple") || t.FullName.StartsWith("System.ValueTuple")) && !(t.IsArray)) // ошибка - не проходит, когда есть System.Tuple[,][] т.е. массив туплов!!! - IsTuple = true; - if (!IsTuple) - { - if (t.Name.Equals("IEnumerable`1") || t.GetInterface("IEnumerable`1") != null) - IsSequence = true; - } + + var IsTuple = IsTupleType(t); + var IsSequence = !IsTuple && IsSequenceType(t); + if (!IsTuple && !IsSequence) { AddError(sem_ex.location, "TUPLE_OR_SEQUENCE_EXPECTED"); diff --git a/VisualPascalABCNETLinux/VisualPascalABCNETLinux.csproj b/VisualPascalABCNETLinux/VisualPascalABCNETLinux.csproj index 130fb52f2..963c0084a 100644 --- a/VisualPascalABCNETLinux/VisualPascalABCNETLinux.csproj +++ b/VisualPascalABCNETLinux/VisualPascalABCNETLinux.csproj @@ -82,10 +82,6 @@ ..\Libraries\Debugger.Core.dll - - False - FormsDesignerBinding\Libs\ICSharpCode.SharpDevelop.Dom.dll - diff --git a/bin/Lib/PABCSystem.pas b/bin/Lib/PABCSystem.pas index a1b28f0c5..72fad8285 100644 --- a/bin/Lib/PABCSystem.pas +++ b/bin/Lib/PABCSystem.pas @@ -10409,7 +10409,7 @@ begin end; /// Превращает последовательность в последовательность n-ок соседних элементов -function Nwise(Self: sequence of T; n: integer):sequence of array of T; extensionmethod; +function Nwise(Self: sequence of T; n: integer): sequence of array of T; extensionmethod; begin var chunk := new Queue(n); foreach var x in Self do