From f2d4637338ab6e4363a4f8e50741808f82e2f611 Mon Sep 17 00:00:00 2001 From: Mikhalkovich Stanislav Date: Fri, 29 Mar 2024 13:53:46 +0300 Subject: [PATCH] =?UTF-8?q?assign=20=D1=81=20first=5Fassignment=5Fdefines?= =?UTF-8?q?=5Ftype=20=D0=B8=20=D1=82=D0=B5=D1=81=D1=82=D0=BE=D0=B2=D1=8B?= =?UTF-8?q?=D0=BC=20=D0=BF=D1=80=D0=B8=D0=BC=D0=B5=D1=80=D0=BE=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Configuration/GlobalAssemblyInfo.cs | 2 +- Configuration/Version.defs | 2 +- Release/pabcversion.txt | 2 +- ReleaseGenerators/PascalABCNET_version.nsh | 2 +- SyntaxTree/tree/TreeHelper.cs | 1 + .../SugarVisitors/TestAssignIsDefVisitor.cs | 11 ++-- TestSuite/CompilationSamples/School.pas | 60 +++++++++++++++++-- TestSuite/CompilationSamples/WPF.pas | 13 ++-- .../SyntaxTreeVisitorNodes/Assign.cs | 23 ++++++- 9 files changed, 96 insertions(+), 20 deletions(-) diff --git a/Configuration/GlobalAssemblyInfo.cs b/Configuration/GlobalAssemblyInfo.cs index 4d12191c5..fdc0a1f00 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 = "9"; public const string Build = "0"; - public const string Revision = "3446"; + public const string Revision = "3450"; 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 db65b1f84..eebd37da2 100644 --- a/Configuration/Version.defs +++ b/Configuration/Version.defs @@ -1,4 +1,4 @@ %COREVERSION%=0 -%REVISION%=3446 +%REVISION%=3450 %MINOR%=9 %MAJOR%=3 diff --git a/Release/pabcversion.txt b/Release/pabcversion.txt index 33ab07b6d..b714564ce 100644 --- a/Release/pabcversion.txt +++ b/Release/pabcversion.txt @@ -1 +1 @@ -3.9.0.3446 +3.9.0.3450 diff --git a/ReleaseGenerators/PascalABCNET_version.nsh b/ReleaseGenerators/PascalABCNET_version.nsh index 57fa015a8..052c19b3f 100644 --- a/ReleaseGenerators/PascalABCNET_version.nsh +++ b/ReleaseGenerators/PascalABCNET_version.nsh @@ -1 +1 @@ -!define VERSION '3.9.0.3446' +!define VERSION '3.9.0.3450' diff --git a/SyntaxTree/tree/TreeHelper.cs b/SyntaxTree/tree/TreeHelper.cs index 6dfd654ec..94230093b 100644 --- a/SyntaxTree/tree/TreeHelper.cs +++ b/SyntaxTree/tree/TreeHelper.cs @@ -384,6 +384,7 @@ namespace PascalABCCompiler.SyntaxTree { return string.Format("{0} {1} {2}", to, OperatorServices.ToString(operator_type, LanguageId.PascalABCNET), from); } + public bool first_assignment_defines_type = false; } public partial class bin_expr diff --git a/SyntaxVisitors/SugarVisitors/TestAssignIsDefVisitor.cs b/SyntaxVisitors/SugarVisitors/TestAssignIsDefVisitor.cs index b8b7caa3a..3733224f9 100644 --- a/SyntaxVisitors/SugarVisitors/TestAssignIsDefVisitor.cs +++ b/SyntaxVisitors/SugarVisitors/TestAssignIsDefVisitor.cs @@ -19,15 +19,18 @@ namespace SyntaxVisitors.SugarVisitors public override void visit(assign ass) { - if ((ass.to as ident).name != "a") + if ((ass.to as ident).name == "a") // это для примера - это надо закомментировать + ass.first_assignment_defines_type = true; + + if (!ass.first_assignment_defines_type) return; syntax_tree_node p = ass; - while (!(p is PascalABCCompiler.SyntaxTree.block) && p != null) + while (!(p is PascalABCCompiler.SyntaxTree.block) && p != null) // ищем вверх ближайший блок p = p.Parent; - if (p == null) + if (p == null) // если блока нет, то выходим. Не знаю, почему его может не быть return; - var typ = new same_type_node(ass.from); + var typ = new named_type_reference("string",ass.source_context); // делаем какой-то правильный тип - всё равно при первом присваивании будем его менять var decls = (p as block).defs; var vds = new var_def_statement(ass.to as ident, typ, ass.source_context); decls.Add(vds); 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/TreeConverter/TreeConversion/SyntaxTreeVisitorNodes/Assign.cs b/TreeConverter/TreeConversion/SyntaxTreeVisitorNodes/Assign.cs index 6a716aafe..2603d2de3 100644 --- a/TreeConverter/TreeConversion/SyntaxTreeVisitorNodes/Assign.cs +++ b/TreeConverter/TreeConversion/SyntaxTreeVisitorNodes/Assign.cs @@ -22,6 +22,12 @@ namespace PascalABCCompiler.TreeConverter addressed_expression to; expression_node from; + + // SSM - идея для особого присваивания, по которому находится тип в SymTable + /*var sc = context.CurrentScope; + var ttt = sc.Find("a"); + (ttt[0].sym_info as namespace_variable).type = convert_strong(_assign.from).type;*/ + AssignCheckAndConvert(_assign, out to, out from); @@ -112,6 +118,21 @@ namespace PascalABCCompiler.TreeConverter /// private void AssignCheckAndConvert(assign _assign, out addressed_expression to, out expression_node from) { + // SSM 29/03/24 + var fromAsLambda0 = _assign.from as function_lambda_definition; + expression_node from0 = null; + if (fromAsLambda0 == null) + { + // Перенёс вычисление from в начало - чтобы потом сделать узел, задающий тип при первом присваивании + from0 = convert_strong(_assign.from); + if (_assign.first_assignment_defines_type) // всегда в этом случае должно быть присваивание := а не += и т.д. + { + var sc = context.CurrentScope; + var ttt = sc.Find((_assign.to as ident).name); // всегда в этом случае должно быть простое имя + (ttt[0].sym_info as namespace_variable).type = from0.type; + } + } + internal_is_assign = true; to = convert_address_strong(_assign.to); internal_is_assign = false; @@ -146,7 +167,7 @@ namespace PascalABCCompiler.TreeConverter } else { - from = convert_strong(_assign.from); + from = from0; ProcessAssigntToAutoType(to, ref from); } // end