Fix patterns not working with yields

This commit is contained in:
Alexander Zakharenko 2018-05-17 22:49:07 +03:00
parent 5486f6b6ea
commit 038d6fe839
11 changed files with 516 additions and 263 deletions

View file

@ -1172,6 +1172,11 @@ namespace PascalABCCompiler.SyntaxTree
{ {
DefaultVisit(_recursive_deconstructor_parameter); DefaultVisit(_recursive_deconstructor_parameter);
} }
public virtual void visit(deconstruction_variables_definition _deconstruction_variables_definition)
{
DefaultVisit(_deconstruction_variables_definition);
}
} }

View file

@ -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) public override void visit(expression _expression)
{ {
DefaultVisit(_expression); DefaultVisit(_expression);
@ -3847,8 +3855,8 @@ namespace PascalABCCompiler.SyntaxTree
{ {
DefaultVisit(_desugared_deconstruction); DefaultVisit(_desugared_deconstruction);
pre_do_visit(_desugared_deconstruction); pre_do_visit(_desugared_deconstruction);
for (int i = 0; i < definitions.Count; i++) visit(desugared_deconstruction.variables);
visit(desugared_deconstruction.definitions[i]); visit(desugared_deconstruction.deconstruction_target);
post_do_visit(_desugared_deconstruction); post_do_visit(_desugared_deconstruction);
} }
@ -3868,6 +3876,15 @@ namespace PascalABCCompiler.SyntaxTree
visit(recursive_deconstructor_parameter.pattern); visit(recursive_deconstructor_parameter.pattern);
post_do_visit(_recursive_deconstructor_parameter); 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);
}
} }

View file

@ -486,6 +486,8 @@ namespace PascalABCCompiler.SyntaxTree
return new var_deconstructor_parameter(); return new var_deconstructor_parameter();
case 232: case 232:
return new recursive_deconstructor_parameter(); return new recursive_deconstructor_parameter();
case 233:
return new deconstruction_variables_definition();
} }
return null; return null;
} }
@ -4076,20 +4078,8 @@ namespace PascalABCCompiler.SyntaxTree
public void read_desugared_deconstruction(desugared_deconstruction _desugared_deconstruction) public void read_desugared_deconstruction(desugared_deconstruction _desugared_deconstruction)
{ {
read_statement(_desugared_deconstruction); read_statement(_desugared_deconstruction);
if (br.ReadByte() == 0) _desugared_deconstruction.variables = _read_node() as deconstruction_variables_definition;
{ _desugared_deconstruction.deconstruction_target = _read_node() as expression;
_desugared_deconstruction.definitions = null;
}
else
{
_desugared_deconstruction.definitions = new List<var_def_statement>();
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();
} }
@ -4117,6 +4107,30 @@ namespace PascalABCCompiler.SyntaxTree
_recursive_deconstructor_parameter.pattern = _read_node() as pattern_node; _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<var_def_statement>();
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);
}
}
}
} }

View file

@ -6386,28 +6386,24 @@ namespace PascalABCCompiler.SyntaxTree
public void write_desugared_deconstruction(desugared_deconstruction _desugared_deconstruction) public void write_desugared_deconstruction(desugared_deconstruction _desugared_deconstruction)
{ {
write_statement(_desugared_deconstruction); write_statement(_desugared_deconstruction);
if (_desugared_deconstruction.definitions == null) if (_desugared_deconstruction.variables == null)
{ {
bw.Write((byte)0); bw.Write((byte)0);
} }
else else
{ {
bw.Write((byte)1); bw.Write((byte)1);
bw.Write(_desugared_deconstruction.definitions.Count); _desugared_deconstruction.variables.visit(this);
for(Int32 ssyy_i = 0; ssyy_i < _desugared_deconstruction.definitions.Count; ssyy_i++) }
{ if (_desugared_deconstruction.deconstruction_target == null)
if (_desugared_deconstruction.definitions[ssyy_i] == null) {
{ bw.Write((byte)0);
bw.Write((byte)0); }
} else
else {
{ bw.Write((byte)1);
bw.Write((byte)1); _desugared_deconstruction.deconstruction_target.visit(this);
_desugared_deconstruction.definitions[ssyy_i].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);
}
}
}
}
} }

View file

@ -49078,7 +49078,7 @@ namespace PascalABCCompiler.SyntaxTree
///<summary> ///<summary>
///Представляет объединение объявлений пременных, порожденных деконструкцией. Деконструируемое выражение необходимо хранить для выведения типа на этапе семантики, однако оно не должно входить в обход дерева. ///Представляет объединение объявлений пременных, порожденных деконструкцией. Деконструируемое выражение необходимо хранить для выведения типа на этапе семантики.
///</summary> ///</summary>
[Serializable] [Serializable]
public partial class desugared_deconstruction : statement public partial class desugared_deconstruction : statement
@ -49095,9 +49095,9 @@ namespace PascalABCCompiler.SyntaxTree
///<summary> ///<summary>
///Конструктор с параметрами. ///Конструктор с параметрами.
///</summary> ///</summary>
public desugared_deconstruction(List<var_def_statement> _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; this._deconstruction_target=_deconstruction_target;
FillParentsInDirectChilds(); FillParentsInDirectChilds();
} }
@ -49105,41 +49105,35 @@ namespace PascalABCCompiler.SyntaxTree
///<summary> ///<summary>
///Конструктор с параметрами. ///Конструктор с параметрами.
///</summary> ///</summary>
public desugared_deconstruction(List<var_def_statement> _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; this._deconstruction_target=_deconstruction_target;
source_context = sc; source_context = sc;
FillParentsInDirectChilds(); FillParentsInDirectChilds();
} }
public desugared_deconstruction(var_def_statement elem, SourceContext sc = null) protected deconstruction_variables_definition _variables;
{ protected expression _deconstruction_target;
Add(elem, sc);
FillParentsInDirectChilds();
}
protected List<var_def_statement> _definitions=new List<var_def_statement>();
protected object _deconstruction_target;
///<summary> ///<summary>
///Объявления порожденных переменных ///Объявления порожденных переменных
///</summary> ///</summary>
public List<var_def_statement> definitions public deconstruction_variables_definition variables
{ {
get get
{ {
return _definitions; return _variables;
} }
set set
{ {
_definitions=value; _variables=value;
} }
} }
///<summary> ///<summary>
///Деконструируемое выражение ///Деконструируемое выражение
///</summary> ///</summary>
public object deconstruction_target public expression deconstruction_target
{ {
get 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<var_def_statement> 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<var_def_statement> 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<var_def_statement> 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<var_def_statement> 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<var_def_statement> 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;
}
/// <summary> Создает копию узла </summary> /// <summary> Создает копию узла </summary>
public override syntax_tree_node Clone() public override syntax_tree_node Clone()
{ {
@ -49312,20 +49158,16 @@ namespace PascalABCCompiler.SyntaxTree
copy.attributes = (attribute_list)attributes.Clone(); copy.attributes = (attribute_list)attributes.Clone();
copy.attributes.Parent = copy; copy.attributes.Parent = copy;
} }
if (definitions != null) if (variables != null)
{ {
foreach (var_def_statement elem in definitions) copy.variables = (deconstruction_variables_definition)variables.Clone();
{ copy.variables.Parent = copy;
if (elem != null) }
{ if (deconstruction_target != null)
copy.Add((var_def_statement)elem.Clone()); {
copy.Last().Parent = copy; copy.deconstruction_target = (expression)deconstruction_target.Clone();
} copy.deconstruction_target.Parent = copy;
else
copy.Add(null);
}
} }
copy.deconstruction_target = deconstruction_target;
return copy; return copy;
} }
@ -49340,12 +49182,10 @@ namespace PascalABCCompiler.SyntaxTree
{ {
if (attributes != null) if (attributes != null)
attributes.Parent = this; attributes.Parent = this;
if (definitions != null) if (variables != null)
{ variables.Parent = this;
foreach (var child in definitions) if (deconstruction_target != null)
if (child != null) deconstruction_target.Parent = this;
child.Parent = this;
}
} }
///<summary> Заполняет поля Parent во всем поддереве </summary> ///<summary> Заполняет поля Parent во всем поддереве </summary>
@ -49353,11 +49193,8 @@ namespace PascalABCCompiler.SyntaxTree
{ {
FillParentsInDirectChilds(); FillParentsInDirectChilds();
attributes?.FillParentsInAllChilds(); attributes?.FillParentsInAllChilds();
if (definitions != null) variables?.FillParentsInAllChilds();
{ deconstruction_target?.FillParentsInAllChilds();
foreach (var child in definitions)
child?.FillParentsInAllChilds();
}
} }
///<summary> ///<summary>
@ -49367,7 +49204,7 @@ namespace PascalABCCompiler.SyntaxTree
{ {
get get
{ {
return 0; return 2;
} }
} }
///<summary> ///<summary>
@ -49377,7 +49214,7 @@ namespace PascalABCCompiler.SyntaxTree
{ {
get get
{ {
return 0 + (definitions == null ? 0 : definitions.Count); return 2;
} }
} }
///<summary> ///<summary>
@ -49389,13 +49226,12 @@ namespace PascalABCCompiler.SyntaxTree
{ {
if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1) if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1)
throw new IndexOutOfRangeException(); throw new IndexOutOfRangeException();
Int32 index_counter=ind - 0; switch(ind)
if(definitions != null)
{ {
if(index_counter < definitions.Count) case 0:
{ return variables;
return definitions[index_counter]; case 1:
} return deconstruction_target;
} }
return null; return null;
} }
@ -49403,14 +49239,14 @@ namespace PascalABCCompiler.SyntaxTree
{ {
if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1) if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1)
throw new IndexOutOfRangeException(); throw new IndexOutOfRangeException();
Int32 index_counter=ind - 0; switch(ind)
if(definitions != null)
{ {
if(index_counter < definitions.Count) case 0:
{ variables = (deconstruction_variables_definition)value;
definitions[index_counter]= (var_def_statement)value; break;
return; case 1:
} deconstruction_target = (expression)value;
break;
} }
} }
} }
@ -49752,6 +49588,337 @@ namespace PascalABCCompiler.SyntaxTree
} }
///<summary>
///Список объявлений для deconstructor pattern
///</summary>
[Serializable]
public partial class deconstruction_variables_definition : declaration
{
///<summary>
///Конструктор без параметров.
///</summary>
public deconstruction_variables_definition()
{
}
///<summary>
///Конструктор с параметрами.
///</summary>
public deconstruction_variables_definition(List<var_def_statement> _definitions)
{
this._definitions=_definitions;
FillParentsInDirectChilds();
}
///<summary>
///Конструктор с параметрами.
///</summary>
public deconstruction_variables_definition(List<var_def_statement> _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<var_def_statement> _definitions=new List<var_def_statement>();
///<summary>
///
///</summary>
public List<var_def_statement> 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<var_def_statement> 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<var_def_statement> 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<var_def_statement> 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<var_def_statement> 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<var_def_statement> 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;
}
/// <summary> Создает копию узла </summary>
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;
}
/// <summary> Получает копию данного узла корректного типа </summary>
public new deconstruction_variables_definition TypedClone()
{
return Clone() as deconstruction_variables_definition;
}
///<summary> Заполняет поля Parent в непосредственных дочерних узлах </summary>
public override void FillParentsInDirectChilds()
{
if (attributes != null)
attributes.Parent = this;
if (definitions != null)
{
foreach (var child in definitions)
if (child != null)
child.Parent = this;
}
}
///<summary> Заполняет поля Parent во всем поддереве </summary>
public override void FillParentsInAllChilds()
{
FillParentsInDirectChilds();
attributes?.FillParentsInAllChilds();
if (definitions != null)
{
foreach (var child in definitions)
child?.FillParentsInAllChilds();
}
}
///<summary>
///Свойство для получения количества всех подузлов без элементов поля типа List
///</summary>
public override Int32 subnodes_without_list_elements_count
{
get
{
return 0;
}
}
///<summary>
///Свойство для получения количества всех подузлов. Подузлом также считается каждый элемент поля типа List
///</summary>
public override Int32 subnodes_count
{
get
{
return 0 + (definitions == null ? 0 : definitions.Count);
}
}
///<summary>
///Индексатор для получения всех подузлов
///</summary>
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;
}
}
}
}
///<summary>
///Метод для обхода дерева посетителем
///</summary>
///<param name="visitor">Объект-посетитель.</param>
///<returns>Return value is void</returns>
public override void visit(IVisitor visitor)
{
visitor.visit(this);
}
}
} }

View file

@ -91,17 +91,6 @@ namespace PascalABCCompiler.SyntaxTree
return null; return null;
} }
/// <summary>
/// Переименовывает все идентификаторы с данным значением в поддереве
/// </summary>
/// <param name="from">Исходное значение</param>
/// <param name="to">Новое значение</param>
public void RenameIdentifierInDescendants(string from, string to, bool includingThis = true)
{
foreach (var identifier in DescendantNodes(TraversalType.PostOrder, null, includingThis).OfType<ident>().Where(x => x.name == from))
identifier.name = to;
}
/// <summary> /// <summary>
/// Получает коллекцию предков текущего узла /// Получает коллекцию предков текущего узла
/// </summary> /// </summary>
@ -1762,23 +1751,27 @@ namespace PascalABCCompiler.SyntaxTree
public partial class desugared_deconstruction 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<var_def_statement> variables, expression target, SourceContext context = null)
: this(new deconstruction_variables_definition(variables), target, context)
{ }
public var_statement[] WithTypes(type_definition[] types) public var_statement[] WithTypes(type_definition[] types)
{ {
var_statement[] result = new var_statement[types.Length]; 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]; variables.definitions[i].vars_type = types[i];
result[i] = new var_statement(definitions[i]); result[i] = new var_statement(variables.definitions[i]);
} }
return result; 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 public partial class is_pattern_expr

View file

@ -1402,6 +1402,12 @@ namespace PascalABCCompiler.SyntaxTree
///<param name="_recursive_deconstructor_parameter">Node to visit</param> ///<param name="_recursive_deconstructor_parameter">Node to visit</param>
///<returns> Return value is void </returns> ///<returns> Return value is void </returns>
void visit(recursive_deconstructor_parameter _recursive_deconstructor_parameter); void visit(recursive_deconstructor_parameter _recursive_deconstructor_parameter);
///<summary>
///Method to visit deconstruction_variables_definition.
///</summary>
///<param name="_deconstruction_variables_definition">Node to visit</param>
///<returns> Return value is void </returns>
void visit(deconstruction_variables_definition _deconstruction_variables_definition);
} }

View file

@ -2972,8 +2972,8 @@
</SyntaxNode> </SyntaxNode>
<SyntaxNode Name="desugared_deconstruction" BaseName="statement"> <SyntaxNode Name="desugared_deconstruction" BaseName="statement">
<Fields> <Fields>
<ExtendedField Name="definitions" Type="List&lt;var_def_statement&gt;" CreateVariable="true" DeleteVariable="false" /> <SyntaxField Name="variables" SyntaxType="deconstruction_variables_definition" />
<ExtendedField Name="deconstruction_target" Type="object" CreateVariable="false" DeleteVariable="false" /> <SyntaxField Name="deconstruction_target" SyntaxType="expression" />
</Fields> </Fields>
<Methods /> <Methods />
<Tags> <Tags>
@ -3014,6 +3014,20 @@
</TagIndices> </TagIndices>
</Tags> </Tags>
</SyntaxNode> </SyntaxNode>
<SyntaxNode Name="deconstruction_variables_definition" BaseName="declaration">
<Fields>
<ExtendedField Name="definitions" Type="List&lt;var_def_statement&gt;" CreateVariable="true" DeleteVariable="false" />
</Fields>
<Methods />
<Tags>
<CategoryIndices>
<CategoryIndex>0</CategoryIndex>
</CategoryIndices>
<TagIndices>
<TagIndex>9</TagIndex>
</TagIndices>
</Tags>
</SyntaxNode>
</SyntaxNodes> </SyntaxNodes>
<Settings> <Settings>
<FileName>Tree.cs</FileName> <FileName>Tree.cs</FileName>
@ -3039,7 +3053,7 @@
<Tag Name="Важнейшие" ReferenceCount="207" /> <Tag Name="Важнейшие" ReferenceCount="207" />
<Tag Name="Method_Procedure_Call" ReferenceCount="2" /> <Tag Name="Method_Procedure_Call" ReferenceCount="2" />
<Tag Name="Yield" ReferenceCount="8" /> <Tag Name="Yield" ReferenceCount="8" />
<Tag Name="Patterns" ReferenceCount="11" /> <Tag Name="Patterns" ReferenceCount="12" />
</Tags> </Tags>
</FilterCategory> </FilterCategory>
</TagCategories> </TagCategories>
@ -3062,6 +3076,7 @@
<HelpData Key=".char_num" Value="Номер символа." /> <HelpData Key=".char_num" Value="Номер символа." />
<HelpData Key=".count" Value="" /> <HelpData Key=".count" Value="" />
<HelpData Key=".def" Value="" /> <HelpData Key=".def" Value="" />
<HelpData Key=".definitions" Value="" />
<HelpData Key=".defs" Value="" /> <HelpData Key=".defs" Value="" />
<HelpData Key=".directives" Value="" /> <HelpData Key=".directives" Value="" />
<HelpData Key=".el" Value="" /> <HelpData Key=".el" Value="" />
@ -3341,6 +3356,8 @@
<HelpData Key="declarations.void Add(declaration d, SourceContext sc)" Value="" /> <HelpData Key="declarations.void Add(declaration d, SourceContext sc)" Value="" />
<HelpData Key="declarations_as_statement" Value="" /> <HelpData Key="declarations_as_statement" Value="" />
<HelpData Key="declarations_as_statement.defs" Value="" /> <HelpData Key="declarations_as_statement.defs" Value="" />
<HelpData Key="deconstruction_variables_definition" Value="Список объявлений для deconstructor pattern" />
<HelpData Key="deconstruction_variables_definition.definitions" Value="" />
<HelpData Key="deconstructor_pattern" Value="" /> <HelpData Key="deconstructor_pattern" Value="" />
<HelpData Key="deconstructor_pattern.parameters" Value="Результат деконструирования" /> <HelpData Key="deconstructor_pattern.parameters" Value="Результат деконструирования" />
<HelpData Key="deconstructor_pattern.type" Value="Деконструируемый тип" /> <HelpData Key="deconstructor_pattern.type" Value="Деконструируемый тип" />
@ -3356,12 +3373,13 @@
<HelpData Key="dereference.dereferencing_value" Value="" /> <HelpData Key="dereference.dereferencing_value" Value="" />
<HelpData Key="dereference.override string ToString()" Value="" /> <HelpData Key="dereference.override string ToString()" Value="" />
<HelpData Key="destructor" Value="" /> <HelpData Key="destructor" Value="" />
<HelpData Key="desugared_deconstruction" Value="Представляет объединение объявлений пременных, порожденных деконструкцией. Деконструируемое выражение необходимо хранить для выведения типа на этапе семантики, однако оно не должно входить в обход дерева." /> <HelpData Key="desugared_deconstruction" Value="Представляет объединение объявлений пременных, порожденных деконструкцией. Деконструируемое выражение необходимо хранить для выведения типа на этапе семантики." />
<HelpData Key="desugared_deconstruction.deconstruct_call" Value="Вызов метода Deconstruct" /> <HelpData Key="desugared_deconstruction.deconstruct_call" Value="Вызов метода Deconstruct" />
<HelpData Key="desugared_deconstruction.deconstruction_target" Value="Деконструируемое выражение" /> <HelpData Key="desugared_deconstruction.deconstruction_target" Value="Деконструируемое выражение" />
<HelpData Key="desugared_deconstruction.definitions" Value="Объявления порожденных переменных" /> <HelpData Key="desugared_deconstruction.definitions" Value="Объявления порожденных переменных" />
<HelpData Key="desugared_deconstruction.destruct_call" Value="" /> <HelpData Key="desugared_deconstruction.destruct_call" Value="" />
<HelpData Key="desugared_deconstruction.expressionVariableName" Value="Деконструируемое выражение" /> <HelpData Key="desugared_deconstruction.expressionVariableName" Value="Деконструируемое выражение" />
<HelpData Key="desugared_deconstruction.variables" Value="Объявления порожденных переменных" />
<HelpData Key="diap_expr" Value="" /> <HelpData Key="diap_expr" Value="" />
<HelpData Key="diap_expr." Value="" /> <HelpData Key="diap_expr." Value="" />
<HelpData Key="diap_expr.left" Value="" /> <HelpData Key="diap_expr.left" Value="" />

View file

@ -46,12 +46,15 @@ namespace PascalABCCompiler.SyntaxTreeConverters
PatternsDesugaringVisitor.New.ProcessNode(root); PatternsDesugaringVisitor.New.ProcessNode(root);
new SimplePrettyPrinterVisitor("G:\\Tree.txt").ProcessNode(root);
// Всё, связанное с yield // Всё, связанное с yield
MarkMethodHasYieldAndCheckSomeErrorsVisitor.New.ProcessNode(root); MarkMethodHasYieldAndCheckSomeErrorsVisitor.New.ProcessNode(root);
ProcessYieldCapturedVarsVisitor.New.ProcessNode(root); ProcessYieldCapturedVarsVisitor.New.ProcessNode(root);
new SimplePrettyPrinterVisitor("G:\\Tree.txt").ProcessNode(root);
FillParentNodeVisitor.New.ProcessNode(root);
#if DEBUG #if DEBUG
/*var cv = CollectLightSymInfoVisitor.New; /*var cv = CollectLightSymInfoVisitor.New;

View file

@ -68,7 +68,10 @@ namespace SyntaxVisitors.SugarVisitors
private const string IsTestMethodName = compiler_string_consts.is_test_function_name; private const string IsTestMethodName = compiler_string_consts.is_test_function_name;
private const string GeneratedPatternNamePrefix = "<>pattern"; 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 if_node _previousIf;
private statement desugaredMatchWith; private statement desugaredMatchWith;
@ -123,11 +126,11 @@ namespace SyntaxVisitors.SugarVisitors
AddDesugaredCaseToResult(ifCheck, ifCheck); 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); private bool IsGenerated(string name) => name.StartsWith(GeneratedPatternNamePrefix);
@ -282,8 +285,6 @@ namespace SyntaxVisitors.SugarVisitors
// if e then <then> // if e then <then>
// end // end
//ifNode = ifNode.TypedClone();
// Добавляем, чтобы на конвертировать еще раз, если потребуется // Добавляем, чтобы на конвертировать еще раз, если потребуется
processedIfNodes.Add(ifNode); processedIfNodes.Add(ifNode);

View file

@ -14,7 +14,7 @@ namespace PascalABCCompiler.TreeConverter
public override void visit(desugared_deconstruction deconstruction) public override void visit(desugared_deconstruction deconstruction)
{ {
var invokationTarget = convert_strong(deconstruction.deconstruction_target as expression); 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) if (types == null)
return; return;