From a07d7bb8e557c29d9c98e703de7083b519fceb9c Mon Sep 17 00:00:00 2001 From: Ivan Bondarev Date: Fri, 29 Mar 2024 12:19:02 +0100 Subject: [PATCH] bug fix #3055 --- NETGenerator/NETGenerator.cs | 2 + TestSuite/CompilationSamples/School.pas | 60 ++++++++++++++++++++++--- TestSuite/CompilationSamples/WPF.pas | 13 +++--- TestSuite/generics74.pas | 25 +++++++++++ 4 files changed, 89 insertions(+), 11 deletions(-) create mode 100644 TestSuite/generics74.pas diff --git a/NETGenerator/NETGenerator.cs b/NETGenerator/NETGenerator.cs index 013d458a6..4b7bb93a8 100644 --- a/NETGenerator/NETGenerator.cs +++ b/NETGenerator/NETGenerator.cs @@ -5881,6 +5881,8 @@ namespace PascalABCCompiler.NETGenerator bool tmp_virtual_method_call = virtual_method_call; virtual_method_call = false; value.obj.visit(this); + if (value.obj is ICommonClassFieldReferenceNode) + is_field_reference = true; virtual_method_call = tmp_virtual_method_call; is_addr = temp_is_addr; FldInfo fi_info = helper.GetField(value.field); diff --git a/TestSuite/CompilationSamples/School.pas b/TestSuite/CompilationSamples/School.pas index a71145dd8..1de59151b 100644 --- a/TestSuite/CompilationSamples/School.pas +++ b/TestSuite/CompilationSamples/School.pas @@ -1,4 +1,4 @@ -/// Учебный модуль, реализующий базовые алгоритмы информатики (27.02.2024) +/// Учебный модуль, реализующий базовые алгоритмы информатики (24.03.2024) unit School; interface @@ -218,14 +218,25 @@ function PrimeDivisorsCount(n: integer): integer; /// Возвращает целочисленный список расширенного представления /// десятичного числа n по основанию base. /// По умолчанию base=10 и возвращается список десятичных цифр числа n. -/// Обратное действие выполняет функция Refold. +/// Обратное действие выполняет функция DigitsToInt64. function Digits(n: int64; base: integer := 10): List; +/// Возвращает целочисленный список расширенного представления +/// десятичного числа n по основанию base. +/// По умолчанию base=10 и возвращается список десятичных цифр числа n. +/// Обратное действие выполняют функции DigitsToInt64 и DigitsToBigInteger. +function Digits(n: BigInteger; base: integer := 10): List; + /// Возвращает целое десятичное число на основе его расширенного представления /// по основанию base (по умолчанию base=10). /// Функция выполняет действие, обратное функции Digits, function DigitsToInt64(ext: List; base: integer := 10): int64; +/// Возвращает целое десятичное число на основе его расширенного представления +/// по основанию base (по умолчанию base=10). +/// Функция выполняет действие, обратное функции Digits, +function DigitsToBigInteger(ext: List; base: integer := 10): BigInteger; + /// Возвращает список делителей натурального числа n function Divisors(n: integer): List; @@ -844,11 +855,11 @@ function PrimeDivisorsCount(Self: integer): integer; extensionmethod := PrimeDiv /// Возвращает целочисленный список расширенного представления /// десятичного числа n по основанию base. /// По умолчанию base=10 и возвращается список десятичных цифр числа n. -/// Обратное действие выполняет функция Refold. +/// Обратное действие выполняет функция DigitsToInt64. function Digits(n: int64; base: integer): List; begin Result := new List; - if (n < 0) or (base < 2) then exit; + if (n < 0) or (base < 2) or (base > integer.MaxValue) then exit; if n = 0 then Result := Lst(0) else while n > 0 do @@ -866,6 +877,28 @@ function Digits(Self: integer; base: integer := 10): List; function Digits(Self: int64; base: integer := 10): List; extensionmethod := Digits(Self, base); +/// Возвращает целочисленный список расширенного представления +/// десятичного числа n по основанию base. +/// По умолчанию base=10 и возвращается список десятичных цифр числа n. +/// Обратное действие выполняют функции DigitsToInt64 и DigitsToBigInteger. +function Digits(n: BigInteger; base: integer): List; +begin + Result := new List; + if (n < 0) or (base < 2) or (base > integer.MaxValue) then exit; + if n = 0 then Result := Lst(0) + else + while n > 0 do + begin + var rem := integer(n mod base); + Result.Add(rem); + n := n div base + end; + Result.Reverse +end; + +function Digits(Self: Biginteger; base: integer := 10): List; + extensionmethod := Digits(Self, base); + /// Возвращает целое десятичное число на основе его расширенного представления /// по основанию base (по умолчанию base=10). /// Функция выполняет действие, обратное функции Digits @@ -881,7 +914,24 @@ begin end; function DigitsToInt64(Self: List; base: integer := 10): int64; - extensionmethod := DigitsToInt64(Self, base); + extensionmethod := DigitsToInt64(Self, base); + +/// Возвращает целое десятичное число на основе его расширенного представления +/// по основанию base (по умолчанию base=10). +/// Функция выполняет действие, обратное функции Digits, +function DigitsToBigInteger(ext: List; base: integer): BigInteger; +begin + Result := BigInteger.Zero; + var p := BigInteger.One; + for var i := ext.Count -1 downto 0 do + begin + Result += ext[i] * p; + p *= base + end +end; + +function DigitsToBigInteger(Self: List; base: integer := 10): BigInteger; + extensionmethod := DigitsToBigInteger(Self, base); {$endregion} diff --git a/TestSuite/CompilationSamples/WPF.pas b/TestSuite/CompilationSamples/WPF.pas index 640559e0d..e8e9703d6 100644 --- a/TestSuite/CompilationSamples/WPF.pas +++ b/TestSuite/CompilationSamples/WPF.pas @@ -308,17 +308,18 @@ begin Result := Self; end; -function LoadFromXaml(fname: string): object; +function ParseXaml(s: string): object; begin - var s := ReadAllText(fname); var context := new ParserContext(); context.XmlnsDictionary.Add('','http://schemas.microsoft.com/winfx/2006/xaml/presentation'); context.XmlnsDictionary.Add('x', 'http://schemas.microsoft.com/winfx/2006/xaml'); - Result := System.Windows.Markup.XamlReader.Parse(ReadAllText(fname),nil); + Result := System.Windows.Markup.XamlReader.Parse(s,context); +end; - //var s := new System.IO.FileStream(fname, System.IO.FileMode.Open); - //Result := System.Windows.Markup.XamlReader.Load(s); - //s.Close(); +function LoadFromXaml(fname: string): object; +begin + var s := ReadAllText(fname); + Result := ParseXaml(s); end; // Функции создания элементов управления diff --git a/TestSuite/generics74.pas b/TestSuite/generics74.pas new file mode 100644 index 000000000..8045b7cf0 --- /dev/null +++ b/TestSuite/generics74.pas @@ -0,0 +1,25 @@ +var s: string; +type + // не обязательно auto класс, я добавил только ради конструктора + t0 = auto class + f: byte; + end; + +procedure p1(o: T); where T: t0; +begin + s := o.f.ToString; // Выводит 0 вместо 123 + + // Обязательно захватить параметр и локальную переменную лямбдой + var x := 0; + var p := procedure-> + begin + o := o; + x := x; + end; + +end; + +begin + p1(new t0(byte(123))); + assert(s = '123'); +end. \ No newline at end of file