From 4bf9c36d4987e04bd44aadee5680c636f123b772 Mon Sep 17 00:00:00 2001 From: Mikhalkovich Stanislav Date: Tue, 2 Jan 2024 14:43:48 +0300 Subject: [PATCH] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D0=B8=20(var=20b=20:=3D=201)=20=D0=BC=D0=B5?= =?UTF-8?q?=D1=82=D0=BE=D0=B4=D0=BE=D0=BC=20=D1=81=D0=B8=D0=BD=D1=82=D0=B0?= =?UTF-8?q?=D0=BA=D1=81=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=BE=D0=B3=D0=BE=20?= =?UTF-8?q?=D1=81=D0=B0=D1=85=D0=B0=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Configuration/GlobalAssemblyInfo.cs | 2 +- Configuration/Version.defs | 4 +- .../PascalABCParserNewSaushkin/ABCPascal.cs | 2 +- .../PascalABCParserNewSaushkin/ABCPascal.y | 4 +- .../ABCPascalYacc.cs | 2284 ++++++++--------- Release/pabcversion.txt | 2 +- ReleaseGenerators/PascalABCNET_version.nsh | 2 +- SyntaxTree/tree/TreeHelper.cs | 5 + .../StandardSyntaxConverter.cs | 5 +- .../SugarVisitors/LetExprVisitor.cs | 50 + SyntaxVisitors/SyntaxVisitors.csproj | 1 + TestSuite/let_ex1.pas | 14 + .../TreeConversion/syntax_tree_visitor.cs | 7 - 13 files changed, 1223 insertions(+), 1159 deletions(-) create mode 100644 SyntaxVisitors/SugarVisitors/LetExprVisitor.cs create mode 100644 TestSuite/let_ex1.pas diff --git a/Configuration/GlobalAssemblyInfo.cs b/Configuration/GlobalAssemblyInfo.cs index 825e804e1..75c3ed468 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 = "3408"; + public const string Revision = "3409"; 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 a4d90cf9c..3b1937f62 100644 --- a/Configuration/Version.defs +++ b/Configuration/Version.defs @@ -1,4 +1,4 @@ -%COREVERSION%=0 -%REVISION%=3408 %MINOR%=9 +%REVISION%=3409 +%COREVERSION%=0 %MAJOR%=3 diff --git a/Parsers/PascalABCParserNewSaushkin/ABCPascal.cs b/Parsers/PascalABCParserNewSaushkin/ABCPascal.cs index 122cbc8b0..86295e2d0 100644 --- a/Parsers/PascalABCParserNewSaushkin/ABCPascal.cs +++ b/Parsers/PascalABCParserNewSaushkin/ABCPascal.cs @@ -2,7 +2,7 @@ // This CSharp output file generated by Gardens Point LEX // Version: 1.1.3.301 // Machine: DESKTOP-G8V08V4 -// DateTime: 31.12.2023 18:49:08 +// DateTime: 02.01.2024 14:42:04 // UserName: ????????? // GPLEX input file // GPLEX frame file diff --git a/Parsers/PascalABCParserNewSaushkin/ABCPascal.y b/Parsers/PascalABCParserNewSaushkin/ABCPascal.y index b66173aba..1580e1010 100644 --- a/Parsers/PascalABCParserNewSaushkin/ABCPascal.y +++ b/Parsers/PascalABCParserNewSaushkin/ABCPascal.y @@ -4213,8 +4213,6 @@ factor { $$ = $1; } | tuple { $$ = $1; } - | tkRoundOpen tkVar identifier tkAssign expr_dq tkRoundClose - { $$ = new let_var_expr($3,$5,@$); } ; literal_or_number @@ -4249,6 +4247,8 @@ var_reference { $$ = $1; } | var_question_point { $$ = $1; } + | tkRoundOpen tkVar identifier tkAssign expr_dq tkRoundClose + { $$ = new let_var_expr($3,$5,@$); } ; var_address diff --git a/Parsers/PascalABCParserNewSaushkin/ABCPascalYacc.cs b/Parsers/PascalABCParserNewSaushkin/ABCPascalYacc.cs index d57e2ea17..71e3064d8 100644 --- a/Parsers/PascalABCParserNewSaushkin/ABCPascalYacc.cs +++ b/Parsers/PascalABCParserNewSaushkin/ABCPascalYacc.cs @@ -2,7 +2,7 @@ // GPPG version 1.3.6 // Machine: DESKTOP-G8V08V4 -// DateTime: 31.12.2023 18:49:09 +// DateTime: 02.01.2024 14:42:05 // UserName: ????????? // Input file @@ -78,7 +78,7 @@ public partial class GPPGParser: ShiftReduceParser aliasses; #pragma warning restore 649 private static Rule[] rules = new Rule[1030]; - private static State[] states = new State[1715]; + private static State[] states = new State[1712]; private static string[] nonTerms = new string[] { "parse_goal", "unit_key_word", "class_or_static", "assignment", "optional_array_initializer", "attribute_declarations", "ot_visibility_specifier", "one_attribute", "attribute_variable", @@ -175,7 +175,7 @@ public partial class GPPGParser: ShiftReduceParser tuple { CurrentSemanticValue.ex = ValueStack[ValueStack.Depth-1].ex; } break; - case 774: // factor -> tkRoundOpen, tkVar, identifier, tkAssign, expr_dq, tkRoundClose -{ CurrentSemanticValue.ex = new let_var_expr(ValueStack[ValueStack.Depth-4].id,ValueStack[ValueStack.Depth-2].ex,CurrentLocationSpan); } - break; - case 775: // literal_or_number -> literal + case 774: // literal_or_number -> literal { CurrentSemanticValue.ex = ValueStack[ValueStack.Depth-1].ex; } break; - case 776: // literal_or_number -> unsigned_number + case 775: // literal_or_number -> unsigned_number { CurrentSemanticValue.ex = ValueStack[ValueStack.Depth-1].ex; } break; - case 777: // var_question_point -> variable, tkQuestionPoint, variable + case 776: // var_question_point -> variable, tkQuestionPoint, variable { CurrentSemanticValue.ex = new dot_question_node(ValueStack[ValueStack.Depth-3].ex as addressed_value,ValueStack[ValueStack.Depth-1].ex as addressed_value,CurrentLocationSpan); } break; - case 778: // var_question_point -> variable, tkQuestionPoint, var_question_point + case 777: // var_question_point -> variable, tkQuestionPoint, var_question_point { CurrentSemanticValue.ex = new dot_question_node(ValueStack[ValueStack.Depth-3].ex as addressed_value,ValueStack[ValueStack.Depth-1].ex as addressed_value,CurrentLocationSpan); } break; - case 779: // var_reference -> var_address, variable + case 778: // var_reference -> var_address, variable { CurrentSemanticValue.ex = NewVarReference(ValueStack[ValueStack.Depth-2].stn as get_address, ValueStack[ValueStack.Depth-1].ex as addressed_value, CurrentLocationSpan); } break; - case 780: // var_reference -> variable + case 779: // var_reference -> variable { CurrentSemanticValue.ex = ValueStack[ValueStack.Depth-1].ex; } break; - case 781: // var_reference -> var_question_point + case 780: // var_reference -> var_question_point { CurrentSemanticValue.ex = ValueStack[ValueStack.Depth-1].ex; } break; + case 781: // var_reference -> tkRoundOpen, tkVar, identifier, tkAssign, expr_dq, + // tkRoundClose +{ CurrentSemanticValue.ex = new let_var_expr(ValueStack[ValueStack.Depth-4].id,ValueStack[ValueStack.Depth-2].ex,CurrentLocationSpan); } + break; case 782: // var_address -> tkAddressOf { CurrentSemanticValue.stn = NewVarAddress(CurrentLocationSpan); diff --git a/Release/pabcversion.txt b/Release/pabcversion.txt index 8643732d8..748939411 100644 --- a/Release/pabcversion.txt +++ b/Release/pabcversion.txt @@ -1 +1 @@ -3.9.0.3408 +3.9.0.3409 diff --git a/ReleaseGenerators/PascalABCNET_version.nsh b/ReleaseGenerators/PascalABCNET_version.nsh index 49f2a6b71..043825af9 100644 --- a/ReleaseGenerators/PascalABCNET_version.nsh +++ b/ReleaseGenerators/PascalABCNET_version.nsh @@ -1 +1 @@ -!define VERSION '3.9.0.3408' +!define VERSION '3.9.0.3409' diff --git a/SyntaxTree/tree/TreeHelper.cs b/SyntaxTree/tree/TreeHelper.cs index 46facebd7..5cbf2a74d 100644 --- a/SyntaxTree/tree/TreeHelper.cs +++ b/SyntaxTree/tree/TreeHelper.cs @@ -2106,4 +2106,9 @@ namespace PascalABCCompiler.SyntaxTree public class semantic_check_delegates_pointers_in_cached_function // класс - маркер семантической проверки { } + + public partial class let_var_expr + { + public bool visit_var = true; + } } diff --git a/SyntaxTreeConverters/StandardSyntaxConverter.cs b/SyntaxTreeConverters/StandardSyntaxConverter.cs index fad7953bb..011649493 100644 --- a/SyntaxTreeConverters/StandardSyntaxConverter.cs +++ b/SyntaxTreeConverters/StandardSyntaxConverter.cs @@ -21,11 +21,14 @@ namespace PascalABCCompiler.SyntaxTreeConverters // FillParentNodeVisitor расположен в SyntaxTree/tree как базовый визитор, отвечающий за построение дерева //FillParentNodeVisitor.New.ProcessNode(root); // почему-то перепрошивает не всё. А следующий вызов - всё root.FillParentsInAllChilds(); - + #if DEBUG // var stat = new ABCStatisticsVisitor(); // stat.ProcessNode(root); #endif + // SSM 02.01.24 + LetExprVisitor.New.ProcessNode(root); + // new range - до всего! До выноса выражения с лямбдой из foreach. 11.07 добавил поиск yields и присваивание pd.HasYield NewRangeDesugarAndFindHasYieldVisitor.New.ProcessNode(root); diff --git a/SyntaxVisitors/SugarVisitors/LetExprVisitor.cs b/SyntaxVisitors/SugarVisitors/LetExprVisitor.cs new file mode 100644 index 000000000..adab53646 --- /dev/null +++ b/SyntaxVisitors/SugarVisitors/LetExprVisitor.cs @@ -0,0 +1,50 @@ +// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using PascalABCCompiler.SyntaxTree; + +namespace SyntaxVisitors.SugarVisitors +{ + /// + /// А здесь не только замена кортежа - здесь оптимизация (a,b) := (1,2) и var (a,b) := (1,2) + /// + public class LetExprVisitor : BaseChangeVisitor + { + public static LetExprVisitor New + { + get { return new LetExprVisitor(); } + } + + private int num = 0; + public string UniqueName() + { + num++; + return "#let_expr_vis"+num.ToString(); + } + + public override void visit(let_var_expr let_ex) + { + // Сгенерировать var_def_statement + var vds = new var_statement(let_ex.id, let_ex.ex, let_ex.source_context); + Replace(let_ex, let_ex.id); + // Подняться до statement + syntax_tree_node p = let_ex; + while (p != null && !(p is statement)) + p = p.Parent; + if (p == null) + new SyntaxVisitorError("LET_EXPR_CANNOT_BE_IN_THIS_CONTEXT", let_ex); + var stat = p as statement; + var sl = new List(); + + sl.Add(vds); + sl.Add(stat); + ReplaceStatementUsingParent(stat, sl); + ProcessNode(vds); + ProcessNode(stat); + } + } +} diff --git a/SyntaxVisitors/SyntaxVisitors.csproj b/SyntaxVisitors/SyntaxVisitors.csproj index 11c0a3bd4..1e0e8e522 100644 --- a/SyntaxVisitors/SyntaxVisitors.csproj +++ b/SyntaxVisitors/SyntaxVisitors.csproj @@ -51,6 +51,7 @@ + diff --git a/TestSuite/let_ex1.pas b/TestSuite/let_ex1.pas new file mode 100644 index 000000000..c5a05d73c --- /dev/null +++ b/TestSuite/let_ex1.pas @@ -0,0 +1,14 @@ +## +var c := (var a := (var b := 5 + 1) + 2); +Assert(a = 8); +Assert(b = 6); +Assert(c = 8); +Print(a,b,c); +var lst := |(var yyy := 2),yyy+1|; +Print(lst); +Assert(lst.SequenceEqual(Arr(2,3))); +var a1 := (var b1 := 5) ** 2; +var a2 := Sqrt((var b2 := 5)); +var res := Arr(1,2,3).Sum(x -> begin var d := (var b := 1); Result := d; end); +res.Print; +Assert(res = 3); diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index 9820df968..611c945a5 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -19800,13 +19800,6 @@ namespace PascalABCCompiler.TreeConverter ret.reset(); // SSM 19.01.17 не возвращать семантическое значение т.к. ничего не нужно добавлять в текущий список операторов!! } - public override void visit(SyntaxTree.let_var_expr node) - { - var vs = new SyntaxTree.var_statement(node.id, node.ex); - visit(vs); - return_value((statement_node)convert_strong(node.ex)); - } - public override void visit(SyntaxTree.expression_as_statement node) { return_value((statement_node)convert_strong(node.expr));