diff --git a/Configuration/GlobalAssemblyInfo.cs b/Configuration/GlobalAssemblyInfo.cs index d1fe6a607..c23e230be 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 = "6"; public const string Build = "3"; - public const string Revision = "2505"; + public const string Revision = "2507"; 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 05f322eb3..8599f7dae 100644 --- a/Configuration/Version.defs +++ b/Configuration/Version.defs @@ -1,4 +1,4 @@ %MINOR%=6 -%REVISION%=2505 +%REVISION%=2507 %COREVERSION%=3 %MAJOR%=3 diff --git a/Release/pabcversion.txt b/Release/pabcversion.txt index ea14cb695..354036f2f 100644 --- a/Release/pabcversion.txt +++ b/Release/pabcversion.txt @@ -1 +1 @@ -3.6.3.2505 +3.6.3.2507 diff --git a/ReleaseGenerators/PascalABCNET_version.nsh b/ReleaseGenerators/PascalABCNET_version.nsh index 033efc722..377cccad2 100644 --- a/ReleaseGenerators/PascalABCNET_version.nsh +++ b/ReleaseGenerators/PascalABCNET_version.nsh @@ -1 +1 @@ -!define VERSION '3.6.3.2505' +!define VERSION '3.6.3.2507' diff --git a/TreeConverter/TreeRealization/generics.cs b/TreeConverter/TreeRealization/generics.cs index d31651aa1..887057df0 100644 --- a/TreeConverter/TreeRealization/generics.cs +++ b/TreeConverter/TreeRealization/generics.cs @@ -1011,11 +1011,6 @@ namespace PascalABCCompiler.TreeRealization } //Выведение типов - //Странно, что для вывода ОДНОГО параметра передаётся весь массив deduced!!! - //Непонятно, что делать, если мы сюда заходим, а он уже в том месте заполнен. Это ошибка или нет? - //Может ли быть такое, что deduced[par_num] заполнен, а возвращается false? - //Не может ли быть, что при рекурсивном вызове deduced начинает перезаполняться вовсе для других параметров? - //Где потом используется deduced? public static bool DeduceInstanceTypes(type_node formal_type, type_node fact_type, type_node[] deduced, List nils, List generic_params) { if (fact_type == null)//issue #347 @@ -1819,39 +1814,55 @@ namespace PascalABCCompiler.TreeRealization var tn1 = tn as compiled_type_node; var ff = tn1.find_in_type("IndexOf");*/ - generic_instance_type_node compr_type = find_instance_type_from(tn); + generic_instance_type_node compr_type = find_instance_type_from(tn); // #1647 tn = IEnumerable if (compr_type == null) { - compiled_function_node cfn = orig_node as compiled_function_node; + compiled_type_node bbt = null; // SSM 14/06/20 - это для #1647 IGrouping: IEnumerable + foreach (type_node tn1 in ImplementingInterfaces) + { + var bt = tn1 as compiled_type_node; + if (bt != null && bt.original_generic == tn) + { + bbt = bt; // #1647 bbt = IEnumerable + break; + } + } + compiled_function_node cfn = orig_node as compiled_function_node; // #1647 orig_node = cfn = IEnumerator GetEnumerator() if (cfn == null) { return orig_node; } - compiled_type_node cct = tn as compiled_type_node; + compiled_type_node cct = tn as compiled_type_node; // cct = IEnumerable + if (bbt != null) // #1647 + cct = orig_member.comperehensive_type as compiled_type_node; + type_node inst_type = this; - do - { - inst_type = inst_type.base_type; - } - while (inst_type.semantic_node_type != semantic_node_type.compiled_type_node || - (inst_type != cct && inst_type.original_generic != cct)); + // До этого цикла проверить bbt - если оно не null, то в роли inst_type как раз и надо брать bbt!!! + if (bbt == null) + do + { + inst_type = inst_type.base_type; + } + while (inst_type.semantic_node_type != semantic_node_type.compiled_type_node || + (inst_type != cct && inst_type.original_generic != cct)); + else inst_type = bbt; // #1647 - MethodInfo[] meths = cct._compiled_type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | + MethodInfo[] meths = cct._compiled_type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); - int num = System.Array.IndexOf(meths, cfn.method_info); + int num = System.Array.IndexOf(meths, cfn.method_info); MethodInfo mi = ((compiled_type_node)inst_type)._compiled_type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | - BindingFlags.Static | BindingFlags.Instance)[num]; + BindingFlags.Static | BindingFlags.Instance)[num]; return compiled_function_node.get_compiled_method(mi); } else return compr_type.ConvertMember(orig_node); - // } else return orig_node; } + SemanticTree.ILocated orig_loc = orig_node as SemanticTree.ILocated; location loc = (orig_loc == null) ? null : (orig_loc.Location as location); switch (orig_node.general_node_type) diff --git a/TreeConverter/TreeRealization/types.cs b/TreeConverter/TreeRealization/types.cs index 3ca7c1686..594c22564 100644 --- a/TreeConverter/TreeRealization/types.cs +++ b/TreeConverter/TreeRealization/types.cs @@ -2673,6 +2673,8 @@ namespace PascalABCCompiler.TreeRealization [Serializable] public class compiled_type_node : wrapped_type, SemanticTree.ICompiledTypeNode , SemanticTree.ILocated { + public override string ToString() => PrintableName; + internal System.Type _compiled_type; protected compiled_type_node _base_type; @@ -3829,7 +3831,11 @@ namespace PascalABCCompiler.TreeRealization return generic_convertions.MakePseudoInstanceName(name, ctypes, true); } if (!_compiled_type.IsPrimitive && base.PrintableName == _compiled_type.Name) - return _compiled_type.FullName; + { + if (_compiled_type.FullName != null && _compiled_type.FullName != "") + return _compiled_type.FullName; + else return _compiled_type.Name; + } return base.PrintableName; } } diff --git a/bin/Lib/School.pas b/bin/Lib/School.pas index 0e79ca744..29a6dbb8d 100644 --- a/bin/Lib/School.pas +++ b/bin/Lib/School.pas @@ -36,19 +36,25 @@ function MinMax(s: sequence of integer): (integer, integer); function НОДНОК(a, b: int64): (int64, int64); /// Разложение числа на простые множители -function Factorize(n: int64): array of int64; +function Factorize(n: int64): List; /// Рразложение числа на простые множители -function Factorize(n: integer): array of integer; +function Factorize(n: integer): List; /// Простые числа на интервале [2;n] -function Primes(n: integer): array of integer; +function Primes(n: integer): List; /// Первые n простых чисел -function FirstPrimes(n: integer): array of integer; +function FirstPrimes(n: integer): List; /// Возвращает массив, содержащий цифры числа -function Digits(n: int64): array of integer; +function Digits(n: int64): List; + +/// возвращает список делителей натурального числа +function Divizors(n: int64): List; + +/// возвращает список делителей натурального числа +function Divizors(n: integer): List; /// Возвращает Sin угла, заданного в градусах function SinDegrees(x: real): real; @@ -97,7 +103,7 @@ begin Result := byte(x) + r end; -{$region} +{$endregion} {$region Oct} @@ -119,8 +125,7 @@ begin Result := byte(x) + r end; -{$region} - +{$endregion} {$region Hex} function Hex(x: int64): string; @@ -143,7 +148,7 @@ begin Result := s[byte(x) + 1] + r end; -{$region} +{$endregion} {$region Dec} @@ -189,7 +194,7 @@ begin end end; -{$region} +{$endregion} {$region MinMax} @@ -225,7 +230,7 @@ function MinMax(Self: sequence of int64): (int64, int64); extensionmethod := function MinMax(Self: sequence of integer): (integer, integer); extensionmethod := MinMax(Self); -{$region} +{$endregion} {$region НОДНОК} @@ -239,12 +244,12 @@ begin Result := (a, a1 div a * b1) end; -{$region} +{$endregion} {$region Factorize} /// Разложение числа на простые множители -function Factorize(n: int64): array of int64; +function Factorize(n: int64): List; begin n := Abs(n); var i: int64 := 2; @@ -261,11 +266,11 @@ begin i += i = 2 ? 1 : 2; if n > 1 then L.Add(n); - Result := L.ToArray + Result := L end; /// Разложение числа на простые множители -function Factorize(n: integer): array of integer; +function Factorize(n: integer): List; begin n := Abs(n); var i := 2; @@ -282,23 +287,23 @@ begin i += i = 2 ? 1 : 2; if n > 1 then L.Add(n); - Result := L.ToArray + Result := L end; /// разложение числа на простые множители -function Factorize(Self: int64): array of int64; extensionmethod := +function Factorize(Self: int64): List; extensionmethod := Factorize(Self); /// Разложение числа на простые множители -function Factorize(Self: integer): array of integer; extensionmethod := +function Factorize(Self: integer): List; extensionmethod := Factorize(Self); -{$region} +{$endregion} {$region Primes} /// Простые числа на интервале [2;n] -function Primes(n: integer): array of integer; +function Primes(n: integer): List; // Модифицированное решето Эратосфена на [2;n] begin var Mas := ArrFill(n, True); @@ -317,20 +322,15 @@ begin Inc(i) end; n := Mas.Count(t -> t); - Result := new integer[n-1]; - i := 0; + Result := new List; for var j := 1 to Mas.High do - if Mas[j] then - begin - Result[i] := j+1; - Inc(i) - end + if Mas[j] then Result.Add(j + 1) end; /// Первые n простых чисел -function FirstPrimes(n: integer): array of integer; +function FirstPrimes(n: integer): List; // Модифицированное решето Эратосфена -begin +begin var n1 := Trunc(Exp((Ln(n)+1.088)/0.8832)); var Mas := ArrFill(n1, True); var i := 2; @@ -348,15 +348,14 @@ begin Inc(i) end; //n := Mas.Count(t -> t); - Result := new integer[n]; + Result := new List; i := 0; for var j := 1 to Mas.High do if Mas[j] then begin - Result[i] := j+1; + Result.Add(j + 1); Inc(i); - if i = n then - break + if i = n then break end end; @@ -400,17 +399,16 @@ begin Result := True end; -{$region} +{$endregion} {$region Digits} /// Возвращает массив, содержащий цифры числа -function Digits(n: int64): array of integer; +function Digits(n: int64): List; begin var St := new Stack; n := Abs(n); - if n = 0 then - Result := Arr(0) + if n = 0 then Result.Add(0) else begin while n > 0 do @@ -418,29 +416,95 @@ begin St.Push(n mod 10); n := n div 10 end; - Result := St.ToArray + Result := St.ToList end end; /// Возвращает массив, содержащий цифры числа -function Digits(Self: integer): array of integer; +function Digits(Self: integer): List; extensionmethod := Digits(Self); /// возвращает массив, содержащий цифры числа -function Digits(Self: int64): array of integer; +function Digits(Self: int64): List; extensionmethod := Digits(Self); -{$region} +{$endregion} + +{$region Divisors} + +/// возвращает список всех делителей натурального числа +function Divizors(n: integer): List; +begin + n := Abs(n); // foolproof + var L := new List; + L.Add(1); + L.Add(n); + if n > 3 then + begin + var k := 2; + while (k * k <= n) and (k < 46341) do + begin + if n mod k = 0 then + begin + var t := n div k; + L.Add(k); + if k < t then L.Add(t) + else break + end; + Inc(k) + end; + L.Sort; + end; + Result := L +end; + +/// возвращает список всех делителей натурального числа +function Divizors(n: int64): List; +begin + n := Abs(n); // foolproof + var L := new List; + L.Add(1); + L.Add(n); + if n > 3 then + begin + var k := int64(2); + while (k * k <= n) and (k < 3037000500) do + begin + if n mod k = 0 then + begin + var t := n div k; + L.Add(k); + if k < t then L.Add(t) + else break + end; + Inc(k) + end; + L.Sort; + end; + Result := L +end; + +/// возвращает список делителей натурального числа +function Divizors(Self: integer): List; extensionmethod := + Divizors(Self); + +/// возвращает список делителей натурального числа +function Divizors(Self: int64): List; extensionmethod := + Divizors(Self); + +{$endregion} {$region Trig} function SinDegrees(x: real): real := Sin(DegToRad(x)); function CosDegrees(x: real): real := Cos(DegToRad(x)); - -{$region} -{$refion Random} +function TanDegrees(x: real): real := Tan(DegToRad(x)); + +{$endregion} + +{$region Random} /// Возвращает вещественный массив, заполненный случайными значениями /// на интервале [a; b) с t знаками в дробной части @@ -469,6 +533,6 @@ begin Result[i, j] := Round(Random * (b - a) + a, t); end; -{$region} +{$endregion} end. \ No newline at end of file