diff --git a/Configuration/GlobalAssemblyInfo.cs b/Configuration/GlobalAssemblyInfo.cs
index a8e896030..ab47e90d6 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 = "3281";
+ public const string Revision = "3282";
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 6a48fc8cf..99269cba7 100644
--- a/Configuration/Version.defs
+++ b/Configuration/Version.defs
@@ -1,4 +1,4 @@
-%MINOR%=9
-%REVISION%=3281
%COREVERSION%=0
+%REVISION%=3282
+%MINOR%=9
%MAJOR%=3
diff --git a/Release/pabcversion.txt b/Release/pabcversion.txt
index 75b55d136..50c5d698d 100644
--- a/Release/pabcversion.txt
+++ b/Release/pabcversion.txt
@@ -1 +1 @@
-3.9.0.3281
+3.9.0.3282
diff --git a/ReleaseGenerators/PascalABCNET_version.nsh b/ReleaseGenerators/PascalABCNET_version.nsh
index c02de82f5..82c8ce806 100644
--- a/ReleaseGenerators/PascalABCNET_version.nsh
+++ b/ReleaseGenerators/PascalABCNET_version.nsh
@@ -1 +1 @@
-!define VERSION '3.9.0.3281'
+!define VERSION '3.9.0.3282'
diff --git a/SyntaxTree/tree/Tree.cs b/SyntaxTree/tree/Tree.cs
index 3d3293061..9f55acbb8 100644
--- a/SyntaxTree/tree/Tree.cs
+++ b/SyntaxTree/tree/Tree.cs
@@ -46956,7 +46956,8 @@ namespace PascalABCCompiler.SyntaxTree
///
- ///
+ ///Это внутри begin:var (a,b) := (1,2);
+
///
[Serializable]
public partial class assign_var_tuple : statement
@@ -50962,7 +50963,7 @@ namespace PascalABCCompiler.SyntaxTree
///
- ///
+ ///Это только в секции до begin: var (a,b) := (3,4); begin
///
[Serializable]
public partial class var_tuple_def_statement : var_def_statement
diff --git a/SyntaxTree/tree/tree.xml b/SyntaxTree/tree/tree.xml
index 2d4e83f5a..6fe4b2e0f 100644
--- a/SyntaxTree/tree/tree.xml
+++ b/SyntaxTree/tree/tree.xml
@@ -3520,7 +3520,7 @@
-
+
@@ -4858,7 +4858,7 @@
-
+
diff --git a/SyntaxVisitors/SugarVisitors/AssignTuplesDesugarVisitor.cs b/SyntaxVisitors/SugarVisitors/AssignTuplesDesugarVisitor.cs
index 9b38bb33b..9807b829c 100644
--- a/SyntaxVisitors/SugarVisitors/AssignTuplesDesugarVisitor.cs
+++ b/SyntaxVisitors/SugarVisitors/AssignTuplesDesugarVisitor.cs
@@ -120,6 +120,7 @@ namespace SyntaxVisitors.SugarVisitors
visit(assvartup.expr); // В assvartup.expr могут содержаться лямбды, в которых будут другие assign_var_tuple.
// И вообще другой синтаксический сахар, размещённый в этом визиторе
}
+
public override void visit(var_tuple_def_statement vtd)
{
// Состоит из var_def_statements. Некоторые являются var_tuple_def_statement
diff --git a/SyntaxVisitors/SugarVisitors/TupleVisitor.cs b/SyntaxVisitors/SugarVisitors/TupleVisitor.cs
index ec68ff2c6..a393a6675 100644
--- a/SyntaxVisitors/SugarVisitors/TupleVisitor.cs
+++ b/SyntaxVisitors/SugarVisitors/TupleVisitor.cs
@@ -19,6 +19,13 @@ namespace SyntaxVisitors.SugarVisitors
get { return new TupleVisitor(); }
}
+ private int num = 0;
+ public string UniqueName()
+ {
+ num++;
+ return "#tup_vis"+num.ToString();
+ }
+
public override void visit(read_accessor_name wn)
{
DefaultVisit(wn);
@@ -48,6 +55,8 @@ namespace SyntaxVisitors.SugarVisitors
ProcessNode(ls.to_statement);
}
+ // Здесь раскрываются ситуации когда справа - кортеж с константами: var (a,b) := (1,2) и только это.
+ // Остальное раскрывается в AssignTuplesDesugarVisitor
public override void visit(assign_var_tuple assvartup)
{
if (assvartup.expr is tuple_node tn && tn.el.expressions.All(ex => ex is const_node) && !tn.el.expressions.Any(ex => ex is nil_const))
@@ -94,6 +103,33 @@ namespace SyntaxVisitors.SugarVisitors
}
ReplaceStatementUsingParent(asstup, sl);
}
+ else if (asstup.expr is tuple_node tn1 && !tn1.el.expressions.Any(ex => ex is nil_const))
+ {
+ var n = asstup.vars.variables.Count();
+ if (n > tn1.el.Count)
+ throw new SyntaxVisitorError("TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_TUPLE_ASSIGNMENT", asstup.vars.variables[0]);
+
+ var sl = new List();
+ for (var i = 0; i < n; i++)
+ {
+ var temp_id = new ident(UniqueName(), tn1.el.expressions[i].source_context);
+ var var_def = new var_def_statement(temp_id, tn1.el.expressions[i], tn1.el.expressions[i].source_context);
+ var a = new var_statement(var_def, tn1.el.expressions[i].source_context);
+ sl.Add(a);
+ }
+
+ //for (var i = 0; i < n; i++)
+ for (var i = n-1; i >=0; i--)
+ {
+ var a = new assign(asstup.vars.variables[i],
+ (sl[i] as var_statement).var_def.vars.idents[0],
+ Operators.Assignment,
+ asstup.vars.variables[i].source_context);
+ sl.Add(a);
+ }
+
+ ReplaceStatementUsingParent(asstup, sl);
+ }
else
{
DefaultVisit(asstup);
@@ -111,6 +147,7 @@ namespace SyntaxVisitors.SugarVisitors
}
}
+ // А это по идее до begin - там немного другие узлы и внешний контекст
public override void visit(var_tuple_def_statement vtd)
{
if (vtd.inital_value is tuple_node tn && tn.el.expressions.All(ex => ex is const_node) && !tn.el.expressions.Any(ex => ex is nil_const))