diff --git a/Configuration/GlobalAssemblyInfo.cs b/Configuration/GlobalAssemblyInfo.cs index f438bea6a..dcbed8e97 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 = "11"; public const string Build = "0"; - public const string Revision = "3676"; + public const string Revision = "3677"; 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 d147780c6..b6f201d5a 100644 --- a/Configuration/Version.defs +++ b/Configuration/Version.defs @@ -1,4 +1,4 @@ -%COREVERSION%=0 -%REVISION%=3676 %MINOR%=11 +%REVISION%=3677 +%COREVERSION%=0 %MAJOR%=3 diff --git a/InstallerSamples/!Tutorial/06_ForWhileRepeat/For1.pas b/InstallerSamples/!Tutorial/06_ForWhileRepeat/For1.pas index f2340e3a6..7e4bf5403 100644 --- a/InstallerSamples/!Tutorial/06_ForWhileRepeat/For1.pas +++ b/InstallerSamples/!Tutorial/06_ForWhileRepeat/For1.pas @@ -6,15 +6,14 @@ begin Println('Числа от 1 до', n, ':'); for var i := 1 to n do Print(i); - Println; - Println; + Println(NewLine); + Println('Числа от', n, 'до 1:'); for var i := n downto 1 do Print(i); - Println; - Println; + Println(NewLine); + Println('Маленькие английские буквы:'); for var c := 'a' to 'z' do Print(c); - Println; end. diff --git a/InstallerSamples/!Tutorial/06_ForWhileRepeat/For2.pas b/InstallerSamples/!Tutorial/06_ForWhileRepeat/For2.pas index af4eadebd..b762f62a0 100644 --- a/InstallerSamples/!Tutorial/06_ForWhileRepeat/For2.pas +++ b/InstallerSamples/!Tutorial/06_ForWhileRepeat/For2.pas @@ -8,7 +8,7 @@ begin Println; Print('Случайные целые от 1 до 99:'); - for var i := n downto 1 do + for var i := 1 to n do Print(Random(1, 99)); Println; end. diff --git a/InstallerSamples/!Tutorial/06_ForWhileRepeat/Foreach1.pas b/InstallerSamples/!Tutorial/06_ForWhileRepeat/Foreach1.pas new file mode 100644 index 000000000..eee8c2c3c --- /dev/null +++ b/InstallerSamples/!Tutorial/06_ForWhileRepeat/Foreach1.pas @@ -0,0 +1,29 @@ +// Цикл foreach + +begin + // foreach по диапазону + foreach var x in 1..10 do + Print(x); + Println; + + var a := [1,3,5,7,9]; + // foreach по массиву + foreach var x in a do + Print(x); + Println; + + // foreach с индексом + foreach var x in a index i do + Print((i,x)); + Println; + + // foreach по словарю + var d := Dict('cat' to 'кошка', 'dog' to 'собака'); + foreach var kv in d do + Print(kv); + Println; + + // foreach по словарю с распаковкой + foreach var (key,value) in d do + Println($'{key} → {value}'); +end. diff --git a/InstallerSamples/!Tutorial/07_CharString/String5.pas b/InstallerSamples/!Tutorial/07_CharString/String5.pas index 656769157..fa9635b98 100644 --- a/InstallerSamples/!Tutorial/07_CharString/String5.pas +++ b/InstallerSamples/!Tutorial/07_CharString/String5.pas @@ -4,9 +4,9 @@ var s1: string := 'NET'; begin - Writeln('Исходная строка: ''',s,''''); + Writeln('Исходная строка: ''',s,' '''); s := Trim(s); - Writeln('После вызова функции Trim: ''',s,''''); + Writeln('После вызова функции Trim: ''',s,' '''); var p := Pos(s1,s); WritelnFormat('Позиция подстроки ''{0}'' в строке ''{1}'' равна {2}',s1,s,p); Delete(s,7,2); diff --git a/InstallerSamples/!Tutorial/07_CharString/String6.pas b/InstallerSamples/!Tutorial/07_CharString/String6.pas index 8c9ec80ac..8ea595464 100644 --- a/InstallerSamples/!Tutorial/07_CharString/String6.pas +++ b/InstallerSamples/!Tutorial/07_CharString/String6.pas @@ -4,9 +4,9 @@ var s1: string := 'NET'; begin - Writeln('Исходная строка: ''',s,''''); + Writeln('Исходная строка: ''',s,' '''); s := s.Trim; - Writeln('После вызова s.Trim: ''',s,''''); + Writeln('После вызова s.Trim: ''',s,' '''); var p := s.IndexOf(s1); // Индексация - с нуля WritelnFormat('Позиция подстроки ''{0}'' в строке ''{1}'' равна {2}',s1,s,p); s := s.Remove(6,2); diff --git a/InstallerSamples/!Tutorial/07_CharString/StringInteger1.pas b/InstallerSamples/!Tutorial/07_CharString/StringInteger1.pas index 5c9dcd1d0..723eeeb7c 100644 --- a/InstallerSamples/!Tutorial/07_CharString/StringInteger1.pas +++ b/InstallerSamples/!Tutorial/07_CharString/StringInteger1.pas @@ -4,10 +4,10 @@ begin // Преобразование целого в строку var i := 234; var s := IntToStr(i); - WritelnFormat('Целое: {0}. После преобразования к строке: ''{1}''',i,s); + Println($'Целое: {i}. После преобразования к строке: ''{s}'''); // Преобразование строки в целое (может произойти исключение) s := '567'; i := StrToInt(s); - WritelnFormat('Строка: ''{0}''. После преобразования к целому: {1}',s,i); + Println($'Строка: ''{s}''. После преобразования к целому: {i}'); end. \ No newline at end of file diff --git a/InstallerSamples/!Tutorial/07_CharString/StringInteger2.pas b/InstallerSamples/!Tutorial/07_CharString/StringInteger2.pas deleted file mode 100644 index 5dfe155aa..000000000 --- a/InstallerSamples/!Tutorial/07_CharString/StringInteger2.pas +++ /dev/null @@ -1,18 +0,0 @@ -// Преобразование целое <-> строка в старом стиле (Val и Str) -var - s: string; - i: integer; - -begin - // Преобразование целого в строку - i := 234; - Str(i,s); - writelnFormat('Целое: {0}. После преобразования к строке: ''{1}''',i,s); - - // Преобразование строки в целое - s := '567'; - var err: integer; - Val(s,i,err); - if err=0 then - writelnFormat('Строка: ''{0}''. После преобразования к целому: {1}',s,i); -end. \ No newline at end of file diff --git a/InstallerSamples/!Tutorial/07_CharString/StringInteger3.pas b/InstallerSamples/!Tutorial/07_CharString/StringInteger3.pas index ce86a50a3..cb186ea96 100644 --- a/InstallerSamples/!Tutorial/07_CharString/StringInteger3.pas +++ b/InstallerSamples/!Tutorial/07_CharString/StringInteger3.pas @@ -1,16 +1,13 @@ -// Преобразование целое <-> строка в новом стиле -var - s: string; - i: integer; +// Преобразование целое <-> строка в новом стиле begin // Преобразование целого в строку - i := 234; - s := i.ToString; - writelnFormat('Целое: {0}. После преобразования к строке: ''{1}''',i,s); + var i := 234; + var s := i.ToString; + Println($'Целое: {i}. После преобразования к строке: ''{s}'''); // Преобразование строки в целое s := '567'; if integer.TryParse(s,i) then - writelnFormat('Строка: ''{0}''. После преобразования к целому: {1}',s,i); + Println($'Строка: ''{s}''. После преобразования к целому: {i}'); end. \ No newline at end of file diff --git a/InstallerSamples/!Tutorial/07_CharString/StringReal1.pas b/InstallerSamples/!Tutorial/07_CharString/StringReal1.pas index 4b1037b65..06eab8bc0 100644 --- a/InstallerSamples/!Tutorial/07_CharString/StringReal1.pas +++ b/InstallerSamples/!Tutorial/07_CharString/StringReal1.pas @@ -1,16 +1,13 @@ -// Преобразование вещественное <-> строка -var - s: string; - r: real; +// Преобразование вещественное <-> строка begin // Преобразование целого в строку - r := 3.1415; - s := FloatToStr(r); - writelnFormat('Целое: {0}. После преобразования к строке: ''{1}''',r,s); + var r := 3.1415; + var s := FloatToStr(r); + Println($'Число: {r}. После преобразования к строке: ''{s}'''); // Преобразование строки в целое (может произойти исключение) s := '3.1415'; r := StrToFloat(s); - writelnFormat('Строка: ''{0}''. После преобразования к целому: {1}',s,r); + Println($'Строка: ''{s}''. После преобразования к числу: {r}'); end. \ No newline at end of file diff --git a/InstallerSamples/!Tutorial/07_CharString/UpLowCase.pas b/InstallerSamples/!Tutorial/07_CharString/UpLowCase.pas index 2c7303586..c2dd3041d 100644 --- a/InstallerSamples/!Tutorial/07_CharString/UpLowCase.pas +++ b/InstallerSamples/!Tutorial/07_CharString/UpLowCase.pas @@ -1,22 +1,21 @@ -// Использование стандартных функций UpperCase, LowerCase -var c: char; +// Использование стандартных функций UpperCase, LowerCase begin - for c:='a' to 'z' do - write(UpperCase(c)); - writeln; - for c:='A' to 'Z' do - write(LowerCase(c)); - writeln; - for c:='А' to 'Я' do - write(UpperCase(c)); - writeln; - for c:='а' to 'я' do - write(LowerCase(c)); - writeln; + for var c:='a' to 'z' do + Write(UpperCase(c)); + Writeln; + for var c:='A' to 'Z' do + Write(LowerCase(c)); + Writeln; + for var c:='А' to 'Я' do + Write(UpperCase(c)); + Writeln; + for var c:='а' to 'я' do + Write(LowerCase(c)); + Writeln; var s := 'Папа у Васи силён в математике'; s := UpperCase(s); - writeln(s); + Writeln(s); s := LowerCase(s); - writeln(s); + Writeln(s); end. diff --git a/InstallerSamples/!Tutorial/08_ProcFunc/Fun1.pas b/InstallerSamples/!Tutorial/08_ProcFunc/Fun1.pas index 9aeffb0e6..d6b817adb 100644 --- a/InstallerSamples/!Tutorial/08_ProcFunc/Fun1.pas +++ b/InstallerSamples/!Tutorial/08_ProcFunc/Fun1.pas @@ -1,4 +1,4 @@ -// Определение функции. Вывод таблицы ее значений +// Определение функции. Вывод таблицы ее значений function MyFun(x: real): real; begin @@ -13,10 +13,10 @@ const begin var h := (b-a)/n; var x := a; - writeln('Таблица значений функции MyFun:'); + Println('Таблица значений функции MyFun:'); for var i := 0 to n do begin - writeln(x:5:2,MyFun(x):10:4); + Println(x:5:2,MyFun(x):9:4); x += h; end; end. \ No newline at end of file diff --git a/InstallerSamples/!Tutorial/08_ProcFunc/Fun2.pas b/InstallerSamples/!Tutorial/08_ProcFunc/Fun2.pas index 4994822e4..231506521 100644 --- a/InstallerSamples/!Tutorial/08_ProcFunc/Fun2.pas +++ b/InstallerSamples/!Tutorial/08_ProcFunc/Fun2.pas @@ -1,4 +1,4 @@ -// Функция Power +// Функция Power function Power(x: real; n: integer): real; begin @@ -7,11 +7,8 @@ begin Result *= x; end; -var - x: real; - n: integer; - begin - x := 2; n := 5; - writelnFormat('{0} в степени {1} = {2}',x,n,Power(x,n)); + var x: real := 2; + var n: integer := 5; + Println($'{x} в степени {n} = {Power(x,n)}'); end. \ No newline at end of file diff --git a/InstallerSamples/!Tutorial/08_ProcFunc/Proc1.pas b/InstallerSamples/!Tutorial/08_ProcFunc/Proc1.pas index 95f40b8a0..fe5a5e8cd 100644 --- a/InstallerSamples/!Tutorial/08_ProcFunc/Proc1.pas +++ b/InstallerSamples/!Tutorial/08_ProcFunc/Proc1.pas @@ -1,17 +1,17 @@ -// Параметры процедур +// Параметры процедур procedure Operations(a,b: integer); begin - writeln(a,' + ',b,' = ',a+b); - writeln(a,' - ',b,' = ',a-b); - writeln(a,' * ',b,' = ',a*b); - writeln(a,' / ',b,' = ',a/b); - writeln(a,' div ',b,' = ',a div b); - writeln(a,' mod ',b,' = ',a mod b); + Println(a,'+',b,'=',a+b); + Println(a,'-',b,'=',a-b); + Println(a,'*',b,'=',a*b); + Println(a,'/',b,'=',a/b); + Println(a,'div',b,'=',a div b); + Println(a,'mod',b,'=',a mod b); end; begin Operations(5,3); - writeln; + Println; Operations(7,4); end. \ No newline at end of file diff --git a/InstallerSamples/!Tutorial/08_ProcFunc/Proc2.pas b/InstallerSamples/!Tutorial/08_ProcFunc/Proc2.pas index c62936635..a77214f03 100644 --- a/InstallerSamples/!Tutorial/08_ProcFunc/Proc2.pas +++ b/InstallerSamples/!Tutorial/08_ProcFunc/Proc2.pas @@ -6,17 +6,14 @@ begin m := a mod b; end; -var - a,b: integer; - d,m: integer; - begin - a := 7; - b := 3; + var a := 7; + var b := 3; + var d,m: integer; DivMod(a,b,d,m); - writelnFormat('{0} div {1} = {2}; {0} mod {1} = {3}',a,b,d,m); + Println($'{a} div {b} = {d}; {a} mod {b} = {m}'); a := 23; b := 5; DivMod(a,b,d,m); - writelnFormat('{0} div {1} = {2}; {0} mod {1} = {3}',a,b,d,m); + Println($'{a} div {b} = {d}; {a} mod {b} = {m}'); end. \ No newline at end of file diff --git a/InstallerSamples/!Tutorial/08_ProcFunc/Proc3.pas b/InstallerSamples/!Tutorial/08_ProcFunc/Proc3.pas index ccbdb03a0..29443f97a 100644 --- a/InstallerSamples/!Tutorial/08_ProcFunc/Proc3.pas +++ b/InstallerSamples/!Tutorial/08_ProcFunc/Proc3.pas @@ -1,4 +1,4 @@ -// Упаковка параметров в запись +// Упаковка параметров в запись uses GraphABC; type diff --git a/InstallerSamples/!Tutorial/08_ProcFunc/Proc4.pas b/InstallerSamples/!Tutorial/08_ProcFunc/Proc4.pas new file mode 100644 index 000000000..5f632eb06 --- /dev/null +++ b/InstallerSamples/!Tutorial/08_ProcFunc/Proc4.pas @@ -0,0 +1,18 @@ +// Упаковка параметров в класс +uses GraphWPF; + +type + Point = auto class + x,y: integer; + end; + +procedure Line(p1,p2: Point) := Line(p1.x,p1.y,p2.x,p2.y); + +begin + var p1 := new Point(10,10); + var p2 := new Point(10,210); + var p3 := new Point(210,10); + Line(p1,p2); + Line(p2,p3); + Line(p3,p1); +end. \ No newline at end of file diff --git a/PABCNetHelp/LangGuide/PABCSystemUnit/Files/Extension methods for IDictionary.html b/PABCNetHelp/LangGuide/PABCSystemUnit/Files/Extension methods for IDictionary.html index 30d1be592..3f73c528d 100644 --- a/PABCNetHelp/LangGuide/PABCSystemUnit/Files/Extension methods for IDictionary.html +++ b/PABCNetHelp/LangGuide/PABCSystemUnit/Files/Extension methods for IDictionary.html @@ -2,6 +2,7 @@ + @@ -16,6 +17,10 @@
         function Get<Key, Value>(Self: IDictionary<Key, Value>; K: Key; V: Value := default(Value)): Value;
         , , , +function GetOrAdd<Key, Value>(Self: IDictionary<Key, Value>; K: Key; valueFactory: Key -> Value): Value; +
         , +function GetOrAdd<Key, Value>(Self: IDictionary<Key, Value>; K: Key; defaultValue: Value): Value; +
         function operator-<TKey, TVal>(Self: Dictionary<TKey, TVal>; key: TKey): Dictionary<TKey, TVal>;
         , function operator-<TKey, TVal>(Self: Dictionary<TKey, TVal>; keys: sequence of TKey): Dictionary<TKey, TVal>; diff --git a/PABCNetHelp/LangGuide/PABCSystemUnit/Files/Extension methods for string.html b/PABCNetHelp/LangGuide/PABCSystemUnit/Files/Extension methods for string.html index e82ff4112..89e8536db 100644 --- a/PABCNetHelp/LangGuide/PABCSystemUnit/Files/Extension methods for string.html +++ b/PABCNetHelp/LangGuide/PABCSystemUnit/Files/Extension methods for string.html @@ -35,6 +35,8 @@
         True ( ) function CountOf(Self: string; substring: string; allowOverlap: boolean := false): integer;
         +function CountOf(Self: string; c: char): integer; +
         function IndicesOf(Self, SubS: string; overlay: boolean := False): sequence of integer;
         overlay , function InRange(Self: string; a, b: string): boolean; diff --git a/Release/pabcversion.txt b/Release/pabcversion.txt index 4dd76ab74..34a3ac014 100644 --- a/Release/pabcversion.txt +++ b/Release/pabcversion.txt @@ -1 +1 @@ -3.11.0.3676 +3.11.0.3677 diff --git a/ReleaseGenerators/PascalABCNET_version.nsh b/ReleaseGenerators/PascalABCNET_version.nsh index 85fe93a58..e756d98d6 100644 --- a/ReleaseGenerators/PascalABCNET_version.nsh +++ b/ReleaseGenerators/PascalABCNET_version.nsh @@ -1 +1 @@ -!define VERSION '3.11.0.3676' +!define VERSION '3.11.0.3677' diff --git a/TestSuite/CompilationSamples/PABCSystem.pas b/TestSuite/CompilationSamples/PABCSystem.pas index d41300d78..4bcbeb4c7 100644 --- a/TestSuite/CompilationSamples/PABCSystem.pas +++ b/TestSuite/CompilationSamples/PABCSystem.pas @@ -3292,6 +3292,7 @@ const SEQUENCE_CANNOT_BE_EMPTY = 'Последовательность не может быть пустой!!Sequence cannot be empty'; ARRAY_CANNOT_BE_EMPTY = 'Массив не может быть пустым!!Array cannot be empty'; MIN_CANNOT_BE_GREATER_THAN_MAX = 'Clamp: min не может быть больше чем max!!Clamp: min cannot be greater than max'; + SUBSTRING_CANNOT_BE_EMPTY = 'Подстрока не может быть пустой!!Substring cannot be empty'; // ----------------------------------------------------- // WINAPI // ----------------------------------------------------- @@ -15078,26 +15079,51 @@ end; function CountOf(Self: string; substring: string; allowOverlap: boolean := false): integer; extensionmethod; begin if string.IsNullOrEmpty(substring) then - raise new System.ArgumentException('Подстрока не может быть пустой'); + raise new System.ArgumentException(GetTranslation(SUBSTRING_CANNOT_BE_EMPTY)); Result := 0; - var index := 0; - var substringLength := substring.Length; + var i := 1; + var m := substring.Length; + var n := Self.Length; - while true do + if (m = 0) or (m > n) then exit; + + var lastPossible := n - m + 1; + + while i <= lastPossible do begin - index := Self.IndexOf(substring, index); - if index = -1 then - break; + var isMatch := True; + // Проверяем первый символ до цикла - это частый случай несовпадения + if Self[i] <> substring[1] then + isMatch := False + else + for var j := 2 to m do + if Self[i + j - 1] <> substring[j] then + begin + isMatch := False; + break; + end; - Result += 1; - - if allowOverlap then - index += 1 // Для пересекающихся вхождений сдвигаем на 1 символ - else index += substringLength; // Для непересекающихся - на длину подстроки + if isMatch then + begin + Result += 1; + if allowOverlap then + i += 1 + else i += m; + end + else i += 1; end; end; +/// Возвращает количество вхождений символа в строку +function CountOf(Self: string; c: char): integer; extensionmethod; +begin + Result := 0; + for var i:=1 to Self.Length do + if Self[i] = c then + Result += 1; +end; + ///-- function CreateSliceFromStringInternal(Self: string; from, step, count: integer): string; @@ -15324,6 +15350,26 @@ begin Result := V; end; +/// Получает значение по ключу или добавляет новое, если ключ отсутствует +function GetOrAdd(Self: IDictionary; K: Key; valueFactory: Key -> Value): Value; extensionmethod; +begin + if not Self.TryGetValue(K, Result) then + begin + Result := valueFactory(K); + Self[K] := Result; + end; +end; + +/// Получает значение по ключу или добавляет значение по умолчанию +function GetOrAdd(Self: IDictionary; K: Key; defaultValue: Value): Value; extensionmethod; +begin + if not Self.TryGetValue(K, Result) then + begin + Result := defaultValue; + Self[K] := Result; + end; +end; + /// Возвращает словарь, сопоставляющий ключу группы количество элементов с данным ключом function EachCount(Self: sequence of System.Linq.IGrouping): Dictionary; extensionmethod; begin @@ -15345,12 +15391,14 @@ end; /// Возвращает словарь, сопоставляющий элементам последовательности определённые значения function Each(Self: sequence of Key; proj: Key -> Res): Dictionary; extensionmethod; begin - Result := Self.GroupBy(x->x).ToDictionary(g -> g.Key, g -> proj(g.Key)); + Result := Self.ToDictionary(x -> x, x -> proj(x)); end; /// Обновляет данные в словаре данными из другого словаря procedure Update(Self: Dictionary; update: Dictionary); extensionmethod; begin + if update = nil then Exit; + foreach var kv in update do Self[kv.Key] := kv.Value; end; @@ -15358,6 +15406,8 @@ end; /// Обновляет данные в словаре данными из другого словаря procedure operator+=(Self: Dictionary; update: Dictionary); extensionmethod; begin + if update = nil then Exit; + foreach var kv in update do Self[kv.Key] := kv.Value; end; @@ -15379,6 +15429,8 @@ end; /// Удаляет из словаря пары с указанными значениями ключа procedure operator-=(Self: IDictionary; keys: sequence of Key); extensionmethod; begin + if keys = nil then Exit; + foreach var k in keys do Self.Remove(k); end; @@ -15958,30 +16010,15 @@ function RuntimeDetermineType(T: System.Type): byte; begin result := 0; if T.IsValueType and (T.GetMethod('$Init$') <> nil) then - begin - result := 1; - exit; - end; + exit(1); if T = typeof(string) then - begin - result := 2; - exit; - end; + exit(2); if T = typeof(TypedSet) then - begin - result := 3; - exit; - end; + exit(3); if T = typeof(Text) then - begin - result := 4; - exit; - end; + exit(4); if T = typeof(BinaryFile) then - begin - result := 5; - exit; - end; + exit(5); end; function RuntimeInitialize(kind: byte; variable: object): object; @@ -16003,9 +16040,8 @@ begin end; function GetRuntimeSize: integer; -var - val: T; begin + var val: T; result := System.Runtime.InteropServices.Marshal.SizeOf(val); end; diff --git a/TestSuite/CompilationSamples/School.pas b/TestSuite/CompilationSamples/School.pas index e404da46d..6742351ea 100644 --- a/TestSuite/CompilationSamples/School.pas +++ b/TestSuite/CompilationSamples/School.pas @@ -191,15 +191,9 @@ function MinMax(seq: sequence of BigInteger): (BigInteger, BigInteger); /// Возвращает НОД пары чисел function НОД(a, b: int64): int64; -/// Возвращает НОД пары чисел -function GCD(a, b: int64): int64; - /// Возвращает НОК пары чисел function НОК(a, b: int64): int64; -/// Возвращает НОК пары чисел -function LCM(a, b: int64): int64; - /// Возвращает НОД и НОК пары чисел function НОДНОК(a, b: int64): (int64, int64); @@ -665,9 +659,6 @@ begin Result := Abs(a) end; -/// Возвращает НОД пары чисел -function GCD(a, b: int64) := НОД(a, b); - /// Возвращает НОК пары чисел function НОК(a, b: int64): int64; begin @@ -677,9 +668,6 @@ begin Result := Abs(a1 div a * b1) end; -/// Возвращает НОК пары чисел -function LCM(a, b: int64) := НОК(a, b); - /// Возвращает НОД и НОК пары чисел function НОДНОК(a, b: int64): (int64, int64); begin diff --git a/Yield/ParsePABC1/App.config b/Yield/ParsePABC1/App.config deleted file mode 100644 index 74ade9db5..000000000 --- a/Yield/ParsePABC1/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/Yield/ParsePABC1/ProgramOld.cs b/Yield/ParsePABC1/ProgramOld.cs deleted file mode 100644 index f7d1dd9fb..000000000 --- a/Yield/ParsePABC1/ProgramOld.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using PascalABCCompiler.Errors; -using PascalABCCompiler; -using PascalABCCompiler.SyntaxTree; -using PascalABCCompiler.ParserTools; - -using SyntaxVisitors; - -namespace ParsePABC1 -{ - class Program - { - // PascalABCSaushkinParser reference needed!!! DO NOT REMOVE!!! - - static syntax_tree_node ParseFile(string fname) - { - Compiler c = new Compiler(); - // c.SyntaxTreeChanger = new YieldDesugarSyntaxTreeConverter(); - var opts = new CompilerOptions(fname, CompilerOptions.OutputType.ConsoleApplicaton); - - var res = c.Compile(opts); - - var err = new List(); - - var txt = System.IO.File.ReadAllText(fname); - - var cu = c.ParsersController.Compile(fname, txt, err, PascalABCCompiler.Parsers.ParseMode.Normal); - - if (cu == null) - { - Console.WriteLine("Не распарсилось"); - } - return cu; - } - - static void Main(string[] args) - { - var cu = ParseFile(@"D:\PascalABC.NET\!PABC_Git\Yield\tests\basic\yieldSimpleMethodDef.pas"); - if (cu == null) - return; - - var yieldVis = new ProcessYieldCapturedVarsVisitor(); - cu.visit(yieldVis); - - - cu.visit(new SimplePrettyPrinterVisitor()); - - Console.ReadKey(); - } - } -} diff --git a/Yield/ParsePABC1/Properties/AssemblyInfo.cs b/Yield/ParsePABC1/Properties/AssemblyInfo.cs deleted file mode 100644 index 75b69173e..000000000 --- a/Yield/ParsePABC1/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// Управление общими сведениями о сборке осуществляется с помощью -// набора атрибутов. Измените значения этих атрибутов, чтобы изменить сведения, -// связанные со сборкой. -[assembly: AssemblyTitle("ParsePABC")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Hewlett-Packard")] -[assembly: AssemblyProduct("ParsePABC")] -[assembly: AssemblyCopyright("Copyright © Hewlett-Packard 2015")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Параметр ComVisible со значением FALSE делает типы в сборке невидимыми -// для COM-компонентов. Если требуется обратиться к типу в этой сборке через -// COM, задайте атрибуту ComVisible значение TRUE для этого типа. -[assembly: ComVisible(false)] - -// Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM -[assembly: Guid("d1b107ed-e2bb-4d21-98d0-a2f99c08d2b0")] - -// Сведения о версии сборки состоят из следующих четырех значений: -// -// Основной номер версии -// Дополнительный номер версии -// Номер сборки -// Редакция -// -// Можно задать все значения или принять номера сборки и редакции по умолчанию -// используя "*", как показано ниже: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Yield/ParsePABC1/YieldTest.csproj b/Yield/ParsePABC1/YieldTest.csproj deleted file mode 100644 index 1874a6e92..000000000 --- a/Yield/ParsePABC1/YieldTest.csproj +++ /dev/null @@ -1,111 +0,0 @@ - - - - - Debug - AnyCPU - {D1B107ED-E2BB-4D21-98D0-A2F99C08D2B0} - Exe - Properties - ParsePABC - ParsePABC - v4.0 - 512 - true - - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - False - ..\..\pascalabcnet\_ParsePABC1\dlls\ICSharpCode.NRefactory.dll - - - False - ..\..\bin\Localization.dll - - - - - - - - - - - - - - - - - - - - {a25d26fb-3043-4bcf-833e-e3f4c3be795e} - CompilerTools - - - {1e42361a-eda3-4872-88af-a3aaf600d36d} - Compiler - - - {44a01f9e-dce7-470c-aae5-c3de0ccbee3b} - Errors - - - {1443f539-dcc7-4491-b4fd-b716c739db3c} - PascalABCSaushkinParser - - - {af2efd7b-69dd-4b43-af65-b59b29349c23} - ParserTools - - - {f10a5330-dcf4-4533-877c-7b1b1be23884} - SyntaxTreeConverters - - - {c2cac65a-b2ae-4ccc-b067-e6b8e75df73a} - SyntaxTree - - - {a9ab4282-83b4-41a7-86c3-e5bf6a45e7e2} - SyntaxVisitors - - - {276ee073-60f6-46d2-8811-1b8026bcaada} - YieldConversionSyntax - - - {ce5c55c2-a11c-4e94-a9fa-3fc6ca3e4c09} - YieldHelpers - - - - - \ No newline at end of file diff --git a/bin/Lib/PABCSystem.pas b/bin/Lib/PABCSystem.pas index c39918b3d..4bcbeb4c7 100644 --- a/bin/Lib/PABCSystem.pas +++ b/bin/Lib/PABCSystem.pas @@ -15082,23 +15082,48 @@ begin raise new System.ArgumentException(GetTranslation(SUBSTRING_CANNOT_BE_EMPTY)); Result := 0; - var index := 0; - var substringLength := substring.Length; + var i := 1; + var m := substring.Length; + var n := Self.Length; - while true do + if (m = 0) or (m > n) then exit; + + var lastPossible := n - m + 1; + + while i <= lastPossible do begin - index := Self.IndexOf(substring, index); - if index = -1 then - break; + var isMatch := True; + // Проверяем первый символ до цикла - это частый случай несовпадения + if Self[i] <> substring[1] then + isMatch := False + else + for var j := 2 to m do + if Self[i + j - 1] <> substring[j] then + begin + isMatch := False; + break; + end; - Result += 1; - - if allowOverlap then - index += 1 // Для пересекающихся вхождений сдвигаем на 1 символ - else index += substringLength; // Для непересекающихся - на длину подстроки + if isMatch then + begin + Result += 1; + if allowOverlap then + i += 1 + else i += m; + end + else i += 1; end; end; +/// Возвращает количество вхождений символа в строку +function CountOf(Self: string; c: char): integer; extensionmethod; +begin + Result := 0; + for var i:=1 to Self.Length do + if Self[i] = c then + Result += 1; +end; + ///-- function CreateSliceFromStringInternal(Self: string; from, step, count: integer): string; @@ -15985,30 +16010,15 @@ function RuntimeDetermineType(T: System.Type): byte; begin result := 0; if T.IsValueType and (T.GetMethod('$Init$') <> nil) then - begin - result := 1; - exit; - end; + exit(1); if T = typeof(string) then - begin - result := 2; - exit; - end; + exit(2); if T = typeof(TypedSet) then - begin - result := 3; - exit; - end; + exit(3); if T = typeof(Text) then - begin - result := 4; - exit; - end; + exit(4); if T = typeof(BinaryFile) then - begin - result := 5; - exit; - end; + exit(5); end; function RuntimeInitialize(kind: byte; variable: object): object; @@ -16030,9 +16040,8 @@ begin end; function GetRuntimeSize: integer; -var - val: T; begin + var val: T; result := System.Runtime.InteropServices.Marshal.SizeOf(val); end; diff --git a/bin/PascalABCNET.chm b/bin/PascalABCNET.chm index 089e00746..446dfad5e 100644 Binary files a/bin/PascalABCNET.chm and b/bin/PascalABCNET.chm differ diff --git a/bin/PascalABCNET.chw b/bin/PascalABCNET.chw index e5740ec0f..acd3599f1 100644 Binary files a/bin/PascalABCNET.chw and b/bin/PascalABCNET.chw differ