From 85181251c65daa5be014d7184f0b117adae55f99 Mon Sep 17 00:00:00 2001 From: Mikhalkovich Stanislav Date: Tue, 14 Jul 2020 13:05:02 +0300 Subject: [PATCH] fix #2282 --- Configuration/GlobalAssemblyInfo.cs | 2 +- Configuration/Version.defs | 4 +- Release/pabcversion.txt | 2 +- ReleaseGenerators/PascalABCNET_version.nsh | 2 +- .../StandardSyntaxConverter.cs | 1 + .../ExtendedIsDesugaringVisitor.cs | 2 +- .../PatternsDesugaringVisitor.cs | 76 +++++++++++++++++-- SyntaxVisitors/SyntaxVisitors.csproj | 1 + TestSuite/isVar0.pas | 11 +++ TestSuite/isvar2.pas | 6 -- 10 files changed, 87 insertions(+), 20 deletions(-) create mode 100644 TestSuite/isVar0.pas diff --git a/Configuration/GlobalAssemblyInfo.cs b/Configuration/GlobalAssemblyInfo.cs index 2acb271fe..a0e817c2b 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 = "2577"; + public const string Revision = "2584"; 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 1b1a9e1a4..daaea613f 100644 --- a/Configuration/Version.defs +++ b/Configuration/Version.defs @@ -1,4 +1,4 @@ -%MINOR%=6 -%REVISION%=2577 %COREVERSION%=3 +%REVISION%=2584 +%MINOR%=6 %MAJOR%=3 diff --git a/Release/pabcversion.txt b/Release/pabcversion.txt index 5d287fa04..281f713fd 100644 --- a/Release/pabcversion.txt +++ b/Release/pabcversion.txt @@ -1 +1 @@ -3.6.3.2577 +3.6.3.2584 diff --git a/ReleaseGenerators/PascalABCNET_version.nsh b/ReleaseGenerators/PascalABCNET_version.nsh index 69a46e0a8..d1fcd2f6f 100644 --- a/ReleaseGenerators/PascalABCNET_version.nsh +++ b/ReleaseGenerators/PascalABCNET_version.nsh @@ -1 +1 @@ -!define VERSION '3.6.3.2577' +!define VERSION '3.6.3.2584' diff --git a/SyntaxTreeConverters/StandardSyntaxConverter.cs b/SyntaxTreeConverters/StandardSyntaxConverter.cs index ce270598f..d9b886219 100644 --- a/SyntaxTreeConverters/StandardSyntaxConverter.cs +++ b/SyntaxTreeConverters/StandardSyntaxConverter.cs @@ -8,6 +8,7 @@ using PascalABCCompiler.SyntaxTree; using SyntaxVisitors; using SyntaxVisitors.SugarVisitors; using SyntaxVisitors.CheckingVisitors; +using SyntaxVisitors.PatternsVisitors; namespace PascalABCCompiler.SyntaxTreeConverters { diff --git a/SyntaxVisitors/PatternsVisitors/ExtendedIsDesugaringVisitor.cs b/SyntaxVisitors/PatternsVisitors/ExtendedIsDesugaringVisitor.cs index 461ba280e..d41ea8f9f 100644 --- a/SyntaxVisitors/PatternsVisitors/ExtendedIsDesugaringVisitor.cs +++ b/SyntaxVisitors/PatternsVisitors/ExtendedIsDesugaringVisitor.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; -namespace SyntaxVisitors.SugarVisitors +namespace SyntaxVisitors.PatternsVisitors { public class ExtendedIsDesugaringVisitor : BaseChangeVisitor { diff --git a/SyntaxVisitors/PatternsVisitors/PatternsDesugaringVisitor.cs b/SyntaxVisitors/PatternsVisitors/PatternsDesugaringVisitor.cs index 4c1137aef..f48de1063 100644 --- a/SyntaxVisitors/PatternsVisitors/PatternsDesugaringVisitor.cs +++ b/SyntaxVisitors/PatternsVisitors/PatternsDesugaringVisitor.cs @@ -7,7 +7,7 @@ using PascalABCCompiler.SyntaxTree; using PascalABCCompiler.TreeConversion; using PascalABCCompiler.TreeConverter; -namespace SyntaxVisitors.SugarVisitors +namespace SyntaxVisitors.PatternsVisitors { // Patterns @@ -217,6 +217,23 @@ namespace SyntaxVisitors.SugarVisitors return "$RenIsVarYield" + num + "$" + name; } + public override void visit(procedure_definition pd) + { + //ReplaceNamesInIsVarVisitor.New.ProcessNode(pd); + base.visit(pd); + } + + public class StrBool + { + public string name; + public bool needtorename; + public StrBool(string name, bool b = false) + { + this.name = name; + this.needtorename = b; + } + } + public override void visit(is_pattern_expr isPatternExpr) { if (GetLocation(isPatternExpr) == PatternLocation.Unknown) @@ -224,11 +241,12 @@ namespace SyntaxVisitors.SugarVisitors Debug.Assert(GetAscendant(isPatternExpr) != null, "Couldn't find statement list in upper nodes"); - syntax_tree_node stn = isPatternExpr; - while (stn != null && !(stn is procedure_definition) && !(stn is function_lambda_definition)) - stn = stn.Parent; - if (stn is procedure_definition pd && pd.has_yield) // SSM 11/07/20 Надо сделать обход с переименованием!!! Сейчас and не работает в yield + ... is A(var a1) - { + //syntax_tree_node stn = isPatternExpr; + //while (stn != null && !(stn is procedure_definition) && !(stn is function_lambda_definition)) + // stn = stn.Parent; + //if (stn is procedure_definition pd && pd.has_yield) // SSM 11/07/20 Надо сделать обход с переименованием!!! Сейчас and не работает в yield + ... is A(var a1) + //{ + var dict = new Dictionary(StringComparer.InvariantCultureIgnoreCase); // bool - надо ли начинать renaming var l = new List(); var pp = isPatternExpr.right?.parameters; if (pp != null) @@ -241,12 +259,54 @@ namespace SyntaxVisitors.SugarVisitors var idNew = vdp.identifier.TypedClone(); idNew.name = GenerateNewName(idNew.name); var vs = new var_statement(idClone, idNew, idClone.source_context); - vdp.identifier.name = idNew.name; + // проверять, что имя не начинается с $ и если начинается, то ошибка - уже переименовывали такое же! + if (vdp.identifier.name.StartsWith("$")) + throw new SyntaxVisitorError("Повторное объявление", vdp.identifier.source_context); + dict.Add(vdp.identifier.name, new StrBool(idNew.name,false)); + //vdp.identifier.name = idNew.name; // в следующем цикле переименую l.Add(vs); } } } + // подниматься пока выражение + syntax_tree_node ex = isPatternExpr; + syntax_tree_node ex1 = ex; + while (ex is expression) + { + ex1 = ex; + ex = ex.Parent; + } + ex = ex1; // саммое внешнее выражение. В нём и переименовать! + var nams = ex.DescendantNodes().Where(stn => stn is ident).Cast(); + foreach (var n in nams) + { + // надо как-то пробросить до первой is_var + if (dict.ContainsKey(n.name)) + { + var isvar = GetAscendant(n); + if (isvar != null) + { + dict[n.name].needtorename = true; // всё - можно переименовывать далее + n.name = dict[n.name].name; // переименовываем в is_var + continue; + } + if (!dict[n.name].needtorename) // если еще не дошли до is_var, то это какая-то внешняя и не переименовываем + continue; + if (n.Parent is dot_node dn && dn.left == n) // т.е. не переименовываем только если ident - в правой части dot_node + { + // переименовываем + n.name = dict[n.name].name; + } + else + { + // переименовываем + n.name = dict[n.name].name; + } + } + } + + var stat = GetAscendant(isPatternExpr); if (stat is if_node ifn) { @@ -265,7 +325,7 @@ namespace SyntaxVisitors.SugarVisitors var stl = stat.Parent as statement_list; stl.ReplaceInList(stat, l); } - } + //} //ReplaceStatement(stat, l); // тут нельзя. diff --git a/SyntaxVisitors/SyntaxVisitors.csproj b/SyntaxVisitors/SyntaxVisitors.csproj index 57aab7143..9643374d9 100644 --- a/SyntaxVisitors/SyntaxVisitors.csproj +++ b/SyntaxVisitors/SyntaxVisitors.csproj @@ -52,6 +52,7 @@ + diff --git a/TestSuite/isVar0.pas b/TestSuite/isVar0.pas new file mode 100644 index 000000000..34c448f35 --- /dev/null +++ b/TestSuite/isVar0.pas @@ -0,0 +1,11 @@ +var a := 666; + +procedure p; +begin + var b := (a = 1) or (a = 3) or ('abc' is string(var a)) and (a = 'abc'); + Assert(b); +end; + +begin + p; +end. \ No newline at end of file diff --git a/TestSuite/isvar2.pas b/TestSuite/isvar2.pas index 4808ebbc9..ff5e082b9 100644 --- a/TestSuite/isvar2.pas +++ b/TestSuite/isvar2.pas @@ -1,15 +1,9 @@ function f1(o: object): sequence of object; begin - - //var c := o is object(var a); if o is object(var a) then begin - // var b := a; - // Writeln(a); // object yield a; Assert(a <> nil); // nil - // Writeln(b); // object - // b := b; end; end;