From 038d6fe839a0df0862e91b63350dc6eaaf3a1779 Mon Sep 17 00:00:00 2001 From: Alexander Zakharenko Date: Thu, 17 May 2018 22:49:07 +0300 Subject: [PATCH] Fix patterns not working with yields --- SyntaxTree/tree/AbstractVisitor.cs | 5 + SyntaxTree/tree/HierarchyVisitor.cs | 21 +- SyntaxTree/tree/SyntaxTreeStreamReader.cs | 42 +- SyntaxTree/tree/SyntaxTreeStreamWriter.cs | 59 +- SyntaxTree/tree/Tree.cs | 573 +++++++++++------- SyntaxTree/tree/TreeHelper.cs | 27 +- SyntaxTree/tree/Visitor.cs | 6 + SyntaxTree/tree/tree.xml | 26 +- .../StandardSyntaxConverter.cs | 5 +- .../PatternsDesugaringVisitor.cs | 13 +- .../SyntaxTreeVisitorNodes/Patterns.cs | 2 +- 11 files changed, 516 insertions(+), 263 deletions(-) diff --git a/SyntaxTree/tree/AbstractVisitor.cs b/SyntaxTree/tree/AbstractVisitor.cs index 4874ae8f7..268c67ab1 100644 --- a/SyntaxTree/tree/AbstractVisitor.cs +++ b/SyntaxTree/tree/AbstractVisitor.cs @@ -1172,6 +1172,11 @@ namespace PascalABCCompiler.SyntaxTree { DefaultVisit(_recursive_deconstructor_parameter); } + + public virtual void visit(deconstruction_variables_definition _deconstruction_variables_definition) + { + DefaultVisit(_deconstruction_variables_definition); + } } diff --git a/SyntaxTree/tree/HierarchyVisitor.cs b/SyntaxTree/tree/HierarchyVisitor.cs index 5421e574b..810928b18 100644 --- a/SyntaxTree/tree/HierarchyVisitor.cs +++ b/SyntaxTree/tree/HierarchyVisitor.cs @@ -1869,6 +1869,14 @@ namespace PascalABCCompiler.SyntaxTree { } + public virtual void pre_do_visit(deconstruction_variables_definition _deconstruction_variables_definition) + { + } + + public virtual void post_do_visit(deconstruction_variables_definition _deconstruction_variables_definition) + { + } + public override void visit(expression _expression) { DefaultVisit(_expression); @@ -3847,8 +3855,8 @@ namespace PascalABCCompiler.SyntaxTree { DefaultVisit(_desugared_deconstruction); pre_do_visit(_desugared_deconstruction); - for (int i = 0; i < definitions.Count; i++) - visit(desugared_deconstruction.definitions[i]); + visit(desugared_deconstruction.variables); + visit(desugared_deconstruction.deconstruction_target); post_do_visit(_desugared_deconstruction); } @@ -3868,6 +3876,15 @@ namespace PascalABCCompiler.SyntaxTree visit(recursive_deconstructor_parameter.pattern); post_do_visit(_recursive_deconstructor_parameter); } + + public override void visit(deconstruction_variables_definition _deconstruction_variables_definition) + { + DefaultVisit(_deconstruction_variables_definition); + pre_do_visit(_deconstruction_variables_definition); + for (int i = 0; i < definitions.Count; i++) + visit(deconstruction_variables_definition.definitions[i]); + post_do_visit(_deconstruction_variables_definition); + } } diff --git a/SyntaxTree/tree/SyntaxTreeStreamReader.cs b/SyntaxTree/tree/SyntaxTreeStreamReader.cs index 259355680..0f9c10f65 100644 --- a/SyntaxTree/tree/SyntaxTreeStreamReader.cs +++ b/SyntaxTree/tree/SyntaxTreeStreamReader.cs @@ -486,6 +486,8 @@ namespace PascalABCCompiler.SyntaxTree return new var_deconstructor_parameter(); case 232: return new recursive_deconstructor_parameter(); + case 233: + return new deconstruction_variables_definition(); } return null; } @@ -4076,20 +4078,8 @@ namespace PascalABCCompiler.SyntaxTree public void read_desugared_deconstruction(desugared_deconstruction _desugared_deconstruction) { read_statement(_desugared_deconstruction); - if (br.ReadByte() == 0) - { - _desugared_deconstruction.definitions = null; - } - else - { - _desugared_deconstruction.definitions = new List(); - Int32 ssyy_count = br.ReadInt32(); - for(Int32 ssyy_i = 0; ssyy_i < ssyy_count; ssyy_i++) - { - _desugared_deconstruction.definitions.Add(_read_node() as var_def_statement); - } - } - _desugared_deconstruction.deconstruction_target = (object)br.ReadByte(); + _desugared_deconstruction.variables = _read_node() as deconstruction_variables_definition; + _desugared_deconstruction.deconstruction_target = _read_node() as expression; } @@ -4117,6 +4107,30 @@ namespace PascalABCCompiler.SyntaxTree _recursive_deconstructor_parameter.pattern = _read_node() as pattern_node; } + + public void visit(deconstruction_variables_definition _deconstruction_variables_definition) + { + read_deconstruction_variables_definition(_deconstruction_variables_definition); + } + + public void read_deconstruction_variables_definition(deconstruction_variables_definition _deconstruction_variables_definition) + { + read_declaration(_deconstruction_variables_definition); + if (br.ReadByte() == 0) + { + _deconstruction_variables_definition.definitions = null; + } + else + { + _deconstruction_variables_definition.definitions = new List(); + Int32 ssyy_count = br.ReadInt32(); + for(Int32 ssyy_i = 0; ssyy_i < ssyy_count; ssyy_i++) + { + _deconstruction_variables_definition.definitions.Add(_read_node() as var_def_statement); + } + } + } + } diff --git a/SyntaxTree/tree/SyntaxTreeStreamWriter.cs b/SyntaxTree/tree/SyntaxTreeStreamWriter.cs index f01a887fa..ffaf8632f 100644 --- a/SyntaxTree/tree/SyntaxTreeStreamWriter.cs +++ b/SyntaxTree/tree/SyntaxTreeStreamWriter.cs @@ -6386,28 +6386,24 @@ namespace PascalABCCompiler.SyntaxTree public void write_desugared_deconstruction(desugared_deconstruction _desugared_deconstruction) { write_statement(_desugared_deconstruction); - if (_desugared_deconstruction.definitions == null) + if (_desugared_deconstruction.variables == null) { bw.Write((byte)0); } else { bw.Write((byte)1); - bw.Write(_desugared_deconstruction.definitions.Count); - for(Int32 ssyy_i = 0; ssyy_i < _desugared_deconstruction.definitions.Count; ssyy_i++) - { - if (_desugared_deconstruction.definitions[ssyy_i] == null) - { - bw.Write((byte)0); - } - else - { - bw.Write((byte)1); - _desugared_deconstruction.definitions[ssyy_i].visit(this); - } - } + _desugared_deconstruction.variables.visit(this); + } + if (_desugared_deconstruction.deconstruction_target == null) + { + bw.Write((byte)0); + } + else + { + bw.Write((byte)1); + _desugared_deconstruction.deconstruction_target.visit(this); } - bw.Write((byte)_desugared_deconstruction.deconstruction_target); } @@ -6461,6 +6457,39 @@ namespace PascalABCCompiler.SyntaxTree } } + + public void visit(deconstruction_variables_definition _deconstruction_variables_definition) + { + bw.Write((Int16)233); + write_deconstruction_variables_definition(_deconstruction_variables_definition); + } + + public void write_deconstruction_variables_definition(deconstruction_variables_definition _deconstruction_variables_definition) + { + write_declaration(_deconstruction_variables_definition); + if (_deconstruction_variables_definition.definitions == null) + { + bw.Write((byte)0); + } + else + { + bw.Write((byte)1); + bw.Write(_deconstruction_variables_definition.definitions.Count); + for(Int32 ssyy_i = 0; ssyy_i < _deconstruction_variables_definition.definitions.Count; ssyy_i++) + { + if (_deconstruction_variables_definition.definitions[ssyy_i] == null) + { + bw.Write((byte)0); + } + else + { + bw.Write((byte)1); + _deconstruction_variables_definition.definitions[ssyy_i].visit(this); + } + } + } + } + } diff --git a/SyntaxTree/tree/Tree.cs b/SyntaxTree/tree/Tree.cs index 2436135ae..46a4681ce 100644 --- a/SyntaxTree/tree/Tree.cs +++ b/SyntaxTree/tree/Tree.cs @@ -49078,7 +49078,7 @@ namespace PascalABCCompiler.SyntaxTree /// - ///Представляет объединение объявлений пременных, порожденных деконструкцией. Деконструируемое выражение необходимо хранить для выведения типа на этапе семантики, однако оно не должно входить в обход дерева. + ///Представляет объединение объявлений пременных, порожденных деконструкцией. Деконструируемое выражение необходимо хранить для выведения типа на этапе семантики. /// [Serializable] public partial class desugared_deconstruction : statement @@ -49095,9 +49095,9 @@ namespace PascalABCCompiler.SyntaxTree /// ///Конструктор с параметрами. /// - public desugared_deconstruction(List _definitions,object _deconstruction_target) + public desugared_deconstruction(deconstruction_variables_definition _variables,expression _deconstruction_target) { - this._definitions=_definitions; + this._variables=_variables; this._deconstruction_target=_deconstruction_target; FillParentsInDirectChilds(); } @@ -49105,41 +49105,35 @@ namespace PascalABCCompiler.SyntaxTree /// ///Конструктор с параметрами. /// - public desugared_deconstruction(List _definitions,object _deconstruction_target,SourceContext sc) + public desugared_deconstruction(deconstruction_variables_definition _variables,expression _deconstruction_target,SourceContext sc) { - this._definitions=_definitions; + this._variables=_variables; this._deconstruction_target=_deconstruction_target; source_context = sc; FillParentsInDirectChilds(); } - public desugared_deconstruction(var_def_statement elem, SourceContext sc = null) - { - Add(elem, sc); - FillParentsInDirectChilds(); - } - - protected List _definitions=new List(); - protected object _deconstruction_target; + protected deconstruction_variables_definition _variables; + protected expression _deconstruction_target; /// ///Объявления порожденных переменных /// - public List definitions + public deconstruction_variables_definition variables { get { - return _definitions; + return _variables; } set { - _definitions=value; + _variables=value; } } /// ///Деконструируемое выражение /// - public object deconstruction_target + public expression deconstruction_target { get { @@ -49152,154 +49146,6 @@ namespace PascalABCCompiler.SyntaxTree } - public desugared_deconstruction Add(var_def_statement elem, SourceContext sc = null) - { - definitions.Add(elem); - if (elem != null) - elem.Parent = this; - if (sc != null) - source_context = sc; - return this; - } - - public void AddFirst(var_def_statement el) - { - if (el == null) - throw new ArgumentNullException(nameof(el)); - definitions.Insert(0, el); - FillParentsInDirectChilds(); - } - - public void AddFirst(IEnumerable els) - { - if (els == null) - throw new ArgumentNullException(nameof(els)); - definitions.InsertRange(0, els); - foreach (var el in els) - if (el != null) - el.Parent = this; - } - - public void AddMany(params var_def_statement[] els) - { - if (els == null) - throw new ArgumentNullException(nameof(els)); - definitions.AddRange(els); - foreach (var el in els) - if (el != null) - el.Parent = this; - } - - private int FindIndexInList(var_def_statement el) - { - if (el == null) - throw new ArgumentNullException(nameof(el)); - var ind = definitions.FindIndex(x => x == el); - if (ind == -1) - throw new Exception(string.Format("У списка {0} не найден элемент {1} среди дочерних\n", this, el)); - return ind; - } - - public void InsertAfter(var_def_statement el, var_def_statement newel) - { - if (el == null) - throw new ArgumentNullException(nameof(el)); - if (newel == null) - throw new ArgumentNullException(nameof(newel)); - definitions.Insert(FindIndexInList(el) + 1, newel); - newel.Parent = this; - } - - public void InsertAfter(var_def_statement el, IEnumerable newels) - { - if (el == null) - throw new ArgumentNullException(nameof(el)); - if (newels == null) - throw new ArgumentNullException(nameof(newels)); - definitions.InsertRange(FindIndexInList(el) + 1, newels); - foreach (var newel in newels) - if (newel != null) - newel.Parent = this; - } - - public void InsertBefore(var_def_statement el, var_def_statement newel) - { - if (el == null) - throw new ArgumentNullException(nameof(el)); - if (newel == null) - throw new ArgumentNullException(nameof(newel)); - definitions.Insert(FindIndexInList(el), newel); - newel.Parent = this; - } - - public void InsertBefore(var_def_statement el, IEnumerable newels) - { - if (el == null) - throw new ArgumentNullException(nameof(el)); - if (newels == null) - throw new ArgumentNullException(nameof(newels)); - definitions.InsertRange(FindIndexInList(el), newels); - foreach (var newel in newels) - if (newel != null) - newel.Parent = this; - } - - public bool Remove(var_def_statement el) - { - return definitions.Remove(el); - } - - public void ReplaceInList(var_def_statement el, var_def_statement newel) - { - if (el == null) - throw new ArgumentNullException(nameof(el)); - if (newel == null) - throw new ArgumentNullException(nameof(newel)); - definitions[FindIndexInList(el)] = newel; - newel.Parent = this; - } - - public void ReplaceInList(var_def_statement el, IEnumerable newels) - { - if (el == null) - throw new ArgumentNullException(nameof(el)); - if (newels == null) - throw new ArgumentNullException(nameof(newels)); - var ind = FindIndexInList(el); - definitions.RemoveAt(ind); - definitions.InsertRange(ind, newels); - foreach (var newel in newels) - if (newel != null) - newel.Parent = this; - } - - public int RemoveAll(Predicate match) - { - return definitions.RemoveAll(match); - } - - public var_def_statement Last() - { - if (definitions.Count > 0) - return definitions[definitions.Count - 1]; - throw new InvalidOperationException("Список пуст"); - } - - public int Count - { - get { return definitions.Count; } - } - - public void Insert(int pos, var_def_statement el) - { - if (el == null) - throw new ArgumentNullException(nameof(el)); - definitions.Insert(pos,el); - if (el != null) - el.Parent = this; - } - - /// Создает копию узла public override syntax_tree_node Clone() { @@ -49312,20 +49158,16 @@ namespace PascalABCCompiler.SyntaxTree copy.attributes = (attribute_list)attributes.Clone(); copy.attributes.Parent = copy; } - if (definitions != null) + if (variables != null) { - foreach (var_def_statement elem in definitions) - { - if (elem != null) - { - copy.Add((var_def_statement)elem.Clone()); - copy.Last().Parent = copy; - } - else - copy.Add(null); - } + copy.variables = (deconstruction_variables_definition)variables.Clone(); + copy.variables.Parent = copy; + } + if (deconstruction_target != null) + { + copy.deconstruction_target = (expression)deconstruction_target.Clone(); + copy.deconstruction_target.Parent = copy; } - copy.deconstruction_target = deconstruction_target; return copy; } @@ -49340,12 +49182,10 @@ namespace PascalABCCompiler.SyntaxTree { if (attributes != null) attributes.Parent = this; - if (definitions != null) - { - foreach (var child in definitions) - if (child != null) - child.Parent = this; - } + if (variables != null) + variables.Parent = this; + if (deconstruction_target != null) + deconstruction_target.Parent = this; } /// Заполняет поля Parent во всем поддереве @@ -49353,11 +49193,8 @@ namespace PascalABCCompiler.SyntaxTree { FillParentsInDirectChilds(); attributes?.FillParentsInAllChilds(); - if (definitions != null) - { - foreach (var child in definitions) - child?.FillParentsInAllChilds(); - } + variables?.FillParentsInAllChilds(); + deconstruction_target?.FillParentsInAllChilds(); } /// @@ -49367,7 +49204,7 @@ namespace PascalABCCompiler.SyntaxTree { get { - return 0; + return 2; } } /// @@ -49377,7 +49214,7 @@ namespace PascalABCCompiler.SyntaxTree { get { - return 0 + (definitions == null ? 0 : definitions.Count); + return 2; } } /// @@ -49389,13 +49226,12 @@ namespace PascalABCCompiler.SyntaxTree { if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1) throw new IndexOutOfRangeException(); - Int32 index_counter=ind - 0; - if(definitions != null) + switch(ind) { - if(index_counter < definitions.Count) - { - return definitions[index_counter]; - } + case 0: + return variables; + case 1: + return deconstruction_target; } return null; } @@ -49403,14 +49239,14 @@ namespace PascalABCCompiler.SyntaxTree { if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1) throw new IndexOutOfRangeException(); - Int32 index_counter=ind - 0; - if(definitions != null) + switch(ind) { - if(index_counter < definitions.Count) - { - definitions[index_counter]= (var_def_statement)value; - return; - } + case 0: + variables = (deconstruction_variables_definition)value; + break; + case 1: + deconstruction_target = (expression)value; + break; } } } @@ -49752,6 +49588,337 @@ namespace PascalABCCompiler.SyntaxTree } + /// + ///Список объявлений для deconstructor pattern + /// + [Serializable] + public partial class deconstruction_variables_definition : declaration + { + + /// + ///Конструктор без параметров. + /// + public deconstruction_variables_definition() + { + + } + + /// + ///Конструктор с параметрами. + /// + public deconstruction_variables_definition(List _definitions) + { + this._definitions=_definitions; + FillParentsInDirectChilds(); + } + + /// + ///Конструктор с параметрами. + /// + public deconstruction_variables_definition(List _definitions,SourceContext sc) + { + this._definitions=_definitions; + source_context = sc; + FillParentsInDirectChilds(); + } + public deconstruction_variables_definition(var_def_statement elem, SourceContext sc = null) + { + Add(elem, sc); + FillParentsInDirectChilds(); + } + + protected List _definitions=new List(); + + /// + /// + /// + public List definitions + { + get + { + return _definitions; + } + set + { + _definitions=value; + } + } + + + public deconstruction_variables_definition Add(var_def_statement elem, SourceContext sc = null) + { + definitions.Add(elem); + if (elem != null) + elem.Parent = this; + if (sc != null) + source_context = sc; + return this; + } + + public void AddFirst(var_def_statement el) + { + if (el == null) + throw new ArgumentNullException(nameof(el)); + definitions.Insert(0, el); + FillParentsInDirectChilds(); + } + + public void AddFirst(IEnumerable els) + { + if (els == null) + throw new ArgumentNullException(nameof(els)); + definitions.InsertRange(0, els); + foreach (var el in els) + if (el != null) + el.Parent = this; + } + + public void AddMany(params var_def_statement[] els) + { + if (els == null) + throw new ArgumentNullException(nameof(els)); + definitions.AddRange(els); + foreach (var el in els) + if (el != null) + el.Parent = this; + } + + private int FindIndexInList(var_def_statement el) + { + if (el == null) + throw new ArgumentNullException(nameof(el)); + var ind = definitions.FindIndex(x => x == el); + if (ind == -1) + throw new Exception(string.Format("У списка {0} не найден элемент {1} среди дочерних\n", this, el)); + return ind; + } + + public void InsertAfter(var_def_statement el, var_def_statement newel) + { + if (el == null) + throw new ArgumentNullException(nameof(el)); + if (newel == null) + throw new ArgumentNullException(nameof(newel)); + definitions.Insert(FindIndexInList(el) + 1, newel); + newel.Parent = this; + } + + public void InsertAfter(var_def_statement el, IEnumerable newels) + { + if (el == null) + throw new ArgumentNullException(nameof(el)); + if (newels == null) + throw new ArgumentNullException(nameof(newels)); + definitions.InsertRange(FindIndexInList(el) + 1, newels); + foreach (var newel in newels) + if (newel != null) + newel.Parent = this; + } + + public void InsertBefore(var_def_statement el, var_def_statement newel) + { + if (el == null) + throw new ArgumentNullException(nameof(el)); + if (newel == null) + throw new ArgumentNullException(nameof(newel)); + definitions.Insert(FindIndexInList(el), newel); + newel.Parent = this; + } + + public void InsertBefore(var_def_statement el, IEnumerable newels) + { + if (el == null) + throw new ArgumentNullException(nameof(el)); + if (newels == null) + throw new ArgumentNullException(nameof(newels)); + definitions.InsertRange(FindIndexInList(el), newels); + foreach (var newel in newels) + if (newel != null) + newel.Parent = this; + } + + public bool Remove(var_def_statement el) + { + return definitions.Remove(el); + } + + public void ReplaceInList(var_def_statement el, var_def_statement newel) + { + if (el == null) + throw new ArgumentNullException(nameof(el)); + if (newel == null) + throw new ArgumentNullException(nameof(newel)); + definitions[FindIndexInList(el)] = newel; + newel.Parent = this; + } + + public void ReplaceInList(var_def_statement el, IEnumerable newels) + { + if (el == null) + throw new ArgumentNullException(nameof(el)); + if (newels == null) + throw new ArgumentNullException(nameof(newels)); + var ind = FindIndexInList(el); + definitions.RemoveAt(ind); + definitions.InsertRange(ind, newels); + foreach (var newel in newels) + if (newel != null) + newel.Parent = this; + } + + public int RemoveAll(Predicate match) + { + return definitions.RemoveAll(match); + } + + public var_def_statement Last() + { + if (definitions.Count > 0) + return definitions[definitions.Count - 1]; + throw new InvalidOperationException("Список пуст"); + } + + public int Count + { + get { return definitions.Count; } + } + + public void Insert(int pos, var_def_statement el) + { + if (el == null) + throw new ArgumentNullException(nameof(el)); + definitions.Insert(pos,el); + if (el != null) + el.Parent = this; + } + + + /// Создает копию узла + public override syntax_tree_node Clone() + { + deconstruction_variables_definition copy = new deconstruction_variables_definition(); + copy.Parent = this.Parent; + if (source_context != null) + copy.source_context = new SourceContext(source_context); + if (attributes != null) + { + copy.attributes = (attribute_list)attributes.Clone(); + copy.attributes.Parent = copy; + } + if (definitions != null) + { + foreach (var_def_statement elem in definitions) + { + if (elem != null) + { + copy.Add((var_def_statement)elem.Clone()); + copy.Last().Parent = copy; + } + else + copy.Add(null); + } + } + return copy; + } + + /// Получает копию данного узла корректного типа + public new deconstruction_variables_definition TypedClone() + { + return Clone() as deconstruction_variables_definition; + } + + /// Заполняет поля Parent в непосредственных дочерних узлах + public override void FillParentsInDirectChilds() + { + if (attributes != null) + attributes.Parent = this; + if (definitions != null) + { + foreach (var child in definitions) + if (child != null) + child.Parent = this; + } + } + + /// Заполняет поля Parent во всем поддереве + public override void FillParentsInAllChilds() + { + FillParentsInDirectChilds(); + attributes?.FillParentsInAllChilds(); + if (definitions != null) + { + foreach (var child in definitions) + child?.FillParentsInAllChilds(); + } + } + + /// + ///Свойство для получения количества всех подузлов без элементов поля типа List + /// + public override Int32 subnodes_without_list_elements_count + { + get + { + return 0; + } + } + /// + ///Свойство для получения количества всех подузлов. Подузлом также считается каждый элемент поля типа List + /// + public override Int32 subnodes_count + { + get + { + return 0 + (definitions == null ? 0 : definitions.Count); + } + } + /// + ///Индексатор для получения всех подузлов + /// + public override syntax_tree_node this[Int32 ind] + { + get + { + if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1) + throw new IndexOutOfRangeException(); + Int32 index_counter=ind - 0; + if(definitions != null) + { + if(index_counter < definitions.Count) + { + return definitions[index_counter]; + } + } + return null; + } + set + { + if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1) + throw new IndexOutOfRangeException(); + Int32 index_counter=ind - 0; + if(definitions != null) + { + if(index_counter < definitions.Count) + { + definitions[index_counter]= (var_def_statement)value; + return; + } + } + } + } + /// + ///Метод для обхода дерева посетителем + /// + ///Объект-посетитель. + ///Return value is void + public override void visit(IVisitor visitor) + { + visitor.visit(this); + } + + } + + } diff --git a/SyntaxTree/tree/TreeHelper.cs b/SyntaxTree/tree/TreeHelper.cs index 248453f39..999b404c2 100644 --- a/SyntaxTree/tree/TreeHelper.cs +++ b/SyntaxTree/tree/TreeHelper.cs @@ -91,17 +91,6 @@ namespace PascalABCCompiler.SyntaxTree return null; } - /// - /// Переименовывает все идентификаторы с данным значением в поддереве - /// - /// Исходное значение - /// Новое значение - public void RenameIdentifierInDescendants(string from, string to, bool includingThis = true) - { - foreach (var identifier in DescendantNodes(TraversalType.PostOrder, null, includingThis).OfType().Where(x => x.name == from)) - identifier.name = to; - } - /// /// Получает коллекцию предков текущего узла /// @@ -1762,23 +1751,27 @@ namespace PascalABCCompiler.SyntaxTree public partial class desugared_deconstruction { - public bool HasAllExplicitTypes => definitions.All(x => x.vars_type != null); + public bool HasAllExplicitTypes => variables.definitions.All(x => x.vars_type != null); + + public desugared_deconstruction(List variables, expression target, SourceContext context = null) + : this(new deconstruction_variables_definition(variables), target, context) + { } public var_statement[] WithTypes(type_definition[] types) { var_statement[] result = new var_statement[types.Length]; - Debug.Assert(types.Length == definitions.Count, "Inconsistent types count"); + Debug.Assert(types.Length == variables.definitions.Count, "Inconsistent types count"); - for (int i = 0; i < definitions.Count; i++) + for (int i = 0; i < variables.definitions.Count; i++) { - definitions[i].vars_type = types[i]; - result[i] = new var_statement(definitions[i]); + variables.definitions[i].vars_type = types[i]; + result[i] = new var_statement(variables.definitions[i]); } return result; } - public override string ToString() => $"var {string.Join(", ", definitions)}"; + public override string ToString() => $"var {string.Join(", ", variables.definitions)}"; } public partial class is_pattern_expr diff --git a/SyntaxTree/tree/Visitor.cs b/SyntaxTree/tree/Visitor.cs index 82fa2fafe..3c9a9fca4 100644 --- a/SyntaxTree/tree/Visitor.cs +++ b/SyntaxTree/tree/Visitor.cs @@ -1402,6 +1402,12 @@ namespace PascalABCCompiler.SyntaxTree ///Node to visit /// Return value is void void visit(recursive_deconstructor_parameter _recursive_deconstructor_parameter); + /// + ///Method to visit deconstruction_variables_definition. + /// + ///Node to visit + /// Return value is void + void visit(deconstruction_variables_definition _deconstruction_variables_definition); } diff --git a/SyntaxTree/tree/tree.xml b/SyntaxTree/tree/tree.xml index 27ac59c2c..f25615203 100644 --- a/SyntaxTree/tree/tree.xml +++ b/SyntaxTree/tree/tree.xml @@ -2972,8 +2972,8 @@ - - + + @@ -3014,6 +3014,20 @@ + + + + + + + + 0 + + + 9 + + + Tree.cs @@ -3039,7 +3053,7 @@ - + @@ -3062,6 +3076,7 @@ + @@ -3341,6 +3356,8 @@ + + @@ -3356,12 +3373,13 @@ - + + diff --git a/SyntaxTreeConverters/StandardSyntaxConverter.cs b/SyntaxTreeConverters/StandardSyntaxConverter.cs index 2413b0d51..47c751e38 100644 --- a/SyntaxTreeConverters/StandardSyntaxConverter.cs +++ b/SyntaxTreeConverters/StandardSyntaxConverter.cs @@ -46,12 +46,15 @@ namespace PascalABCCompiler.SyntaxTreeConverters PatternsDesugaringVisitor.New.ProcessNode(root); - new SimplePrettyPrinterVisitor("G:\\Tree.txt").ProcessNode(root); + // Всё, связанное с yield MarkMethodHasYieldAndCheckSomeErrorsVisitor.New.ProcessNode(root); ProcessYieldCapturedVarsVisitor.New.ProcessNode(root); + new SimplePrettyPrinterVisitor("G:\\Tree.txt").ProcessNode(root); + FillParentNodeVisitor.New.ProcessNode(root); + #if DEBUG /*var cv = CollectLightSymInfoVisitor.New; diff --git a/SyntaxVisitors/SugarVisitors/PatternsDesugaringVisitor.cs b/SyntaxVisitors/SugarVisitors/PatternsDesugaringVisitor.cs index fd166370c..2548aa2d4 100644 --- a/SyntaxVisitors/SugarVisitors/PatternsDesugaringVisitor.cs +++ b/SyntaxVisitors/SugarVisitors/PatternsDesugaringVisitor.cs @@ -68,7 +68,10 @@ namespace SyntaxVisitors.SugarVisitors private const string IsTestMethodName = compiler_string_consts.is_test_function_name; private const string GeneratedPatternNamePrefix = "<>pattern"; - private int _variableCounter = 0; + private int generalVariableCounter = 0; + private int successVariableCounter = 0; + private int labelVariableCounter = 0; + private if_node _previousIf; private statement desugaredMatchWith; @@ -123,11 +126,11 @@ namespace SyntaxVisitors.SugarVisitors AddDesugaredCaseToResult(ifCheck, ifCheck); } - private ident NewGeneralName() => new ident(GeneratedPatternNamePrefix + "GenVar" + _variableCounter++); + private ident NewGeneralName() => new ident(GeneratedPatternNamePrefix + "GenVar" + generalVariableCounter++); - private ident NewSuccessName() => new ident(GeneratedPatternNamePrefix + "Success" + _variableCounter++); + private ident NewSuccessName() => new ident(GeneratedPatternNamePrefix + "Success" + generalVariableCounter++); - private ident NewEndIfName() => new ident(GeneratedPatternNamePrefix + "EndIf" + _variableCounter++); + private ident NewEndIfName() => new ident(GeneratedPatternNamePrefix + "EndIf" + generalVariableCounter++); private bool IsGenerated(string name) => name.StartsWith(GeneratedPatternNamePrefix); @@ -282,8 +285,6 @@ namespace SyntaxVisitors.SugarVisitors // if e then // end - //ifNode = ifNode.TypedClone(); - // Добавляем, чтобы на конвертировать еще раз, если потребуется processedIfNodes.Add(ifNode); diff --git a/TreeConverter/TreeConversion/SyntaxTreeVisitorNodes/Patterns.cs b/TreeConverter/TreeConversion/SyntaxTreeVisitorNodes/Patterns.cs index b7902bd3b..6e7e54384 100644 --- a/TreeConverter/TreeConversion/SyntaxTreeVisitorNodes/Patterns.cs +++ b/TreeConverter/TreeConversion/SyntaxTreeVisitorNodes/Patterns.cs @@ -14,7 +14,7 @@ namespace PascalABCCompiler.TreeConverter public override void visit(desugared_deconstruction deconstruction) { var invokationTarget = convert_strong(deconstruction.deconstruction_target as expression); - var types = InferAndCheckPatternVariableTypes(deconstruction.definitions, invokationTarget, deconstruction); + var types = InferAndCheckPatternVariableTypes(deconstruction.variables.definitions, invokationTarget, deconstruction); if (types == null) return;