Yield tree conversion projects added

This commit is contained in:
Oleg Batashov 2016-05-19 02:14:06 +03:00
parent c2387fc548
commit 4050d31097
134 changed files with 6605 additions and 8 deletions

View file

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25123.0
# Visual Studio 2013
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "VisualPascalABCNET", "VisualPascalABCNET", "{26843C5D-9D7E-4C2C-AC14-2D227FA5592E}"
EndProject
@ -95,6 +95,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SyntaxTreeConverters", "SyntaxTreeConverters\SyntaxTreeConverters.csproj", "{F10A5330-DCF4-4533-877C-7B1B1BE23884}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YieldHelpers", "Yield\YieldHelpers\YieldHelpers.csproj", "{CE5C55C2-A11C-4E94-A9FA-3FC6CA3E4C09}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SyntaxVisitors", "Yield\SyntaxVisitors\SyntaxVisitors.csproj", "{A9AB4282-83B4-41A7-86C3-E5BF6A45E7E2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YieldConversionSyntax", "Yield\YieldConversionSyntax\YieldConversionSyntax.csproj", "{276EE073-60F6-46D2-8811-1B8026BCAADA}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -417,6 +423,36 @@ Global
{F10A5330-DCF4-4533-877C-7B1B1BE23884}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{F10A5330-DCF4-4533-877C-7B1B1BE23884}.Release|x86.ActiveCfg = Release|Any CPU
{F10A5330-DCF4-4533-877C-7B1B1BE23884}.Release|x86.Build.0 = Release|Any CPU
{CE5C55C2-A11C-4E94-A9FA-3FC6CA3E4C09}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CE5C55C2-A11C-4E94-A9FA-3FC6CA3E4C09}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CE5C55C2-A11C-4E94-A9FA-3FC6CA3E4C09}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{CE5C55C2-A11C-4E94-A9FA-3FC6CA3E4C09}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{CE5C55C2-A11C-4E94-A9FA-3FC6CA3E4C09}.Debug|x86.ActiveCfg = Debug|Any CPU
{CE5C55C2-A11C-4E94-A9FA-3FC6CA3E4C09}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CE5C55C2-A11C-4E94-A9FA-3FC6CA3E4C09}.Release|Any CPU.Build.0 = Release|Any CPU
{CE5C55C2-A11C-4E94-A9FA-3FC6CA3E4C09}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{CE5C55C2-A11C-4E94-A9FA-3FC6CA3E4C09}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{CE5C55C2-A11C-4E94-A9FA-3FC6CA3E4C09}.Release|x86.ActiveCfg = Release|Any CPU
{A9AB4282-83B4-41A7-86C3-E5BF6A45E7E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A9AB4282-83B4-41A7-86C3-E5BF6A45E7E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A9AB4282-83B4-41A7-86C3-E5BF6A45E7E2}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{A9AB4282-83B4-41A7-86C3-E5BF6A45E7E2}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{A9AB4282-83B4-41A7-86C3-E5BF6A45E7E2}.Debug|x86.ActiveCfg = Debug|Any CPU
{A9AB4282-83B4-41A7-86C3-E5BF6A45E7E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A9AB4282-83B4-41A7-86C3-E5BF6A45E7E2}.Release|Any CPU.Build.0 = Release|Any CPU
{A9AB4282-83B4-41A7-86C3-E5BF6A45E7E2}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{A9AB4282-83B4-41A7-86C3-E5BF6A45E7E2}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{A9AB4282-83B4-41A7-86C3-E5BF6A45E7E2}.Release|x86.ActiveCfg = Release|Any CPU
{276EE073-60F6-46D2-8811-1B8026BCAADA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{276EE073-60F6-46D2-8811-1B8026BCAADA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{276EE073-60F6-46D2-8811-1B8026BCAADA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{276EE073-60F6-46D2-8811-1B8026BCAADA}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{276EE073-60F6-46D2-8811-1B8026BCAADA}.Debug|x86.ActiveCfg = Debug|Any CPU
{276EE073-60F6-46D2-8811-1B8026BCAADA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{276EE073-60F6-46D2-8811-1B8026BCAADA}.Release|Any CPU.Build.0 = Release|Any CPU
{276EE073-60F6-46D2-8811-1B8026BCAADA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{276EE073-60F6-46D2-8811-1B8026BCAADA}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{276EE073-60F6-46D2-8811-1B8026BCAADA}.Release|x86.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -425,6 +461,7 @@ Global
{CFC683F8-0165-4A9F-9C3F-BB8C5BAB507F} = {26843C5D-9D7E-4C2C-AC14-2D227FA5592E}
{BC35F816-54EE-47E0-89FC-1C66EAC155A9} = {26843C5D-9D7E-4C2C-AC14-2D227FA5592E}
{EC68A3D8-6D63-4A79-ABA6-BF8E9D7756D7} = {26843C5D-9D7E-4C2C-AC14-2D227FA5592E}
{A5A3667E-8A3B-4569-BA0E-AD49E12D07E7} = {26843C5D-9D7E-4C2C-AC14-2D227FA5592E}
{DBE875B5-6187-45D8-8B75-2E43CC513A60} = {EC68A3D8-6D63-4A79-ABA6-BF8E9D7756D7}
{43879684-ADBE-470A-AAC6-2ACA36603971} = {EC68A3D8-6D63-4A79-ABA6-BF8E9D7756D7}
{3F74B986-7711-42B1-93D7-51952A71FF2E} = {EC68A3D8-6D63-4A79-ABA6-BF8E9D7756D7}
@ -444,17 +481,19 @@ Global
{10679470-FE1B-4193-A203-D940CF0AEA54} = {F8CE2712-826B-450B-A72F-D32D80C99858}
{1AB15F6E-C22E-499A-A7ED-54BA7DE5CFA6} = {F8CE2712-826B-450B-A72F-D32D80C99858}
{BB6973BA-B3A2-4B31-A986-7CB008F22C4F} = {F8CE2712-826B-450B-A72F-D32D80C99858}
{1D51D03C-FB74-4AB2-84B4-09EB077BEAFE} = {BB6973BA-B3A2-4B31-A986-7CB008F22C4F}
{94EED2FF-0641-4562-8167-CBC280A733AF} = {F8CE2712-826B-450B-A72F-D32D80C99858}
{146083AD-6684-4EBC-A539-AAD749A16364} = {F8CE2712-826B-450B-A72F-D32D80C99858}
{F10A5330-DCF4-4533-877C-7B1B1BE23884} = {F8CE2712-826B-450B-A72F-D32D80C99858}
{CE5C55C2-A11C-4E94-A9FA-3FC6CA3E4C09} = {F8CE2712-826B-450B-A72F-D32D80C99858}
{A9AB4282-83B4-41A7-86C3-E5BF6A45E7E2} = {F8CE2712-826B-450B-A72F-D32D80C99858}
{276EE073-60F6-46D2-8811-1B8026BCAADA} = {F8CE2712-826B-450B-A72F-D32D80C99858}
{1D51D03C-FB74-4AB2-84B4-09EB077BEAFE} = {BB6973BA-B3A2-4B31-A986-7CB008F22C4F}
{1443F539-DCC7-4491-B4FD-B716C739DB3C} = {BB6973BA-B3A2-4B31-A986-7CB008F22C4F}
{C2CAC65A-B2AE-4CCC-B067-E6B8E75DF73A} = {94EED2FF-0641-4562-8167-CBC280A733AF}
{613E0DDA-AA8A-437C-AC45-507B47429FF9} = {94EED2FF-0641-4562-8167-CBC280A733AF}
{A5A3667E-8A3B-4569-BA0E-AD49E12D07E7} = {26843C5D-9D7E-4C2C-AC14-2D227FA5592E}
{2748AD25-9C63-4E12-877B-4DCE96FBED54} = {A5A3667E-8A3B-4569-BA0E-AD49E12D07E7}
{35CEF10F-2D4C-45F2-9DD1-161E0FEC583C} = {A5A3667E-8A3B-4569-BA0E-AD49E12D07E7}
{7E4A7172-7FF5-48D0-B719-7CD959DD1AC9} = {A5A3667E-8A3B-4569-BA0E-AD49E12D07E7}
{857CA1A3-FC88-4BE0-AB6A-D1EE772AB288} = {A5A3667E-8A3B-4569-BA0E-AD49E12D07E7}
{146083AD-6684-4EBC-A539-AAD749A16364} = {F8CE2712-826B-450B-A72F-D32D80C99858}
{1443F539-DCC7-4491-B4FD-B716C739DB3C} = {BB6973BA-B3A2-4B31-A986-7CB008F22C4F}
{F10A5330-DCF4-4533-877C-7B1B1BE23884} = {F8CE2712-826B-450B-A72F-D32D80C99858}
EndGlobalSection
EndGlobal

View file

@ -1067,6 +1067,26 @@ namespace PascalABCCompiler.SyntaxTree
{
DefaultVisit(_no_type);
}
public virtual void visit(yield_unknown_ident _yield_unknown_ident)
{
DefaultVisit(_yield_unknown_ident);
}
public virtual void visit(yield_unknown_expression_type _yield_unknown_expression_type)
{
DefaultVisit(_yield_unknown_expression_type);
}
public virtual void visit(yield_var_def_statement_with_unknown_type _yield_var_def_statement_with_unknown_type)
{
DefaultVisit(_yield_var_def_statement_with_unknown_type);
}
public virtual void visit(yield_variable_definitions_with_unknown_type _yield_variable_definitions_with_unknown_type)
{
DefaultVisit(_yield_variable_definitions_with_unknown_type);
}
}

View file

@ -1701,6 +1701,38 @@ namespace PascalABCCompiler.SyntaxTree
{
}
public virtual void pre_do_visit(yield_unknown_ident _yield_unknown_ident)
{
}
public virtual void post_do_visit(yield_unknown_ident _yield_unknown_ident)
{
}
public virtual void pre_do_visit(yield_unknown_expression_type _yield_unknown_expression_type)
{
}
public virtual void post_do_visit(yield_unknown_expression_type _yield_unknown_expression_type)
{
}
public virtual void pre_do_visit(yield_var_def_statement_with_unknown_type _yield_var_def_statement_with_unknown_type)
{
}
public virtual void post_do_visit(yield_var_def_statement_with_unknown_type _yield_var_def_statement_with_unknown_type)
{
}
public virtual void pre_do_visit(yield_variable_definitions_with_unknown_type _yield_variable_definitions_with_unknown_type)
{
}
public virtual void post_do_visit(yield_variable_definitions_with_unknown_type _yield_variable_definitions_with_unknown_type)
{
}
public override void visit(syntax_tree_node _syntax_tree_node)
{
DefaultVisit(_syntax_tree_node);
@ -3523,6 +3555,39 @@ namespace PascalABCCompiler.SyntaxTree
pre_do_visit(_no_type);
post_do_visit(_no_type);
}
public override void visit(yield_unknown_ident _yield_unknown_ident)
{
DefaultVisit(_yield_unknown_ident);
pre_do_visit(_yield_unknown_ident);
visit(yield_unknown_ident.UnknownID);
visit(yield_unknown_ident.ClassName);
post_do_visit(_yield_unknown_ident);
}
public override void visit(yield_unknown_expression_type _yield_unknown_expression_type)
{
DefaultVisit(_yield_unknown_expression_type);
pre_do_visit(_yield_unknown_expression_type);
visit(yield_unknown_expression_type.Vds);
post_do_visit(_yield_unknown_expression_type);
}
public override void visit(yield_var_def_statement_with_unknown_type _yield_var_def_statement_with_unknown_type)
{
DefaultVisit(_yield_var_def_statement_with_unknown_type);
pre_do_visit(_yield_var_def_statement_with_unknown_type);
visit(yield_var_def_statement_with_unknown_type.vars);
post_do_visit(_yield_var_def_statement_with_unknown_type);
}
public override void visit(yield_variable_definitions_with_unknown_type _yield_variable_definitions_with_unknown_type)
{
DefaultVisit(_yield_variable_definitions_with_unknown_type);
pre_do_visit(_yield_variable_definitions_with_unknown_type);
visit(yield_variable_definitions_with_unknown_type.vars);
post_do_visit(_yield_variable_definitions_with_unknown_type);
}
}

View file

@ -115,6 +115,18 @@ namespace PascalABCCompiler.SyntaxTree
return cd;
}
// frninja 23/04/16 - для шаблонных классов в yield
public static class_definition BuildClassDefinition(named_type_reference_list parents, ident_list template_args, params class_members[] cms)
{
var cb = new class_body();
foreach (var cm in cms)
cb.Add(cm);
var cd = new class_definition(parents, cb, class_keyword.Class, template_args, null, class_attribute.None, false, null);
return cd;
}
// end frninja
// names и types передаю во внешний мир на предмет анализа того, что они не указатели. Снаружи они инициализируются пустыми списками
public static void AddMembersForAutoClass(class_definition cd, ref List<ident> names, ref List<type_definition> types) // SSM 24.03.14
{

View file

@ -444,6 +444,14 @@ namespace PascalABCCompiler.SyntaxTree
return new slice_expr();
case 211:
return new no_type();
case 212:
return new yield_unknown_ident();
case 213:
return new yield_unknown_expression_type();
case 214:
return new yield_var_def_statement_with_unknown_type();
case 215:
return new yield_variable_definitions_with_unknown_type();
}
return null;
}
@ -3765,6 +3773,55 @@ namespace PascalABCCompiler.SyntaxTree
read_type_definition(_no_type);
}
public void visit(yield_unknown_ident _yield_unknown_ident)
{
read_yield_unknown_ident(_yield_unknown_ident);
}
public void read_yield_unknown_ident(yield_unknown_ident _yield_unknown_ident)
{
read_ident(_yield_unknown_ident);
_yield_unknown_ident.UnknownID = _read_node() as ident;
_yield_unknown_ident.ClassName = _read_node() as ident;
}
public void visit(yield_unknown_expression_type _yield_unknown_expression_type)
{
read_yield_unknown_expression_type(_yield_unknown_expression_type);
}
public void read_yield_unknown_expression_type(yield_unknown_expression_type _yield_unknown_expression_type)
{
read_type_definition(_yield_unknown_expression_type);
_yield_unknown_expression_type.Vds = _read_node() as var_def_statement;
}
public void visit(yield_var_def_statement_with_unknown_type _yield_var_def_statement_with_unknown_type)
{
read_yield_var_def_statement_with_unknown_type(_yield_var_def_statement_with_unknown_type);
}
public void read_yield_var_def_statement_with_unknown_type(yield_var_def_statement_with_unknown_type _yield_var_def_statement_with_unknown_type)
{
read_statement(_yield_var_def_statement_with_unknown_type);
_yield_var_def_statement_with_unknown_type.vars = _read_node() as var_def_statement;
}
public void visit(yield_variable_definitions_with_unknown_type _yield_variable_definitions_with_unknown_type)
{
read_yield_variable_definitions_with_unknown_type(_yield_variable_definitions_with_unknown_type);
}
public void read_yield_variable_definitions_with_unknown_type(yield_variable_definitions_with_unknown_type _yield_variable_definitions_with_unknown_type)
{
read_declaration(_yield_variable_definitions_with_unknown_type);
_yield_variable_definitions_with_unknown_type.vars = _read_node() as variable_definitions;
}
}

View file

@ -5922,6 +5922,99 @@ namespace PascalABCCompiler.SyntaxTree
write_type_definition(_no_type);
}
public void visit(yield_unknown_ident _yield_unknown_ident)
{
bw.Write((Int16)212);
write_yield_unknown_ident(_yield_unknown_ident);
}
public void write_yield_unknown_ident(yield_unknown_ident _yield_unknown_ident)
{
write_ident(_yield_unknown_ident);
if (_yield_unknown_ident.UnknownID == null)
{
bw.Write((byte)0);
}
else
{
bw.Write((byte)1);
_yield_unknown_ident.UnknownID.visit(this);
}
if (_yield_unknown_ident.ClassName == null)
{
bw.Write((byte)0);
}
else
{
bw.Write((byte)1);
_yield_unknown_ident.ClassName.visit(this);
}
}
public void visit(yield_unknown_expression_type _yield_unknown_expression_type)
{
bw.Write((Int16)213);
write_yield_unknown_expression_type(_yield_unknown_expression_type);
}
public void write_yield_unknown_expression_type(yield_unknown_expression_type _yield_unknown_expression_type)
{
write_type_definition(_yield_unknown_expression_type);
if (_yield_unknown_expression_type.Vds == null)
{
bw.Write((byte)0);
}
else
{
bw.Write((byte)1);
_yield_unknown_expression_type.Vds.visit(this);
}
}
public void visit(yield_var_def_statement_with_unknown_type _yield_var_def_statement_with_unknown_type)
{
bw.Write((Int16)214);
write_yield_var_def_statement_with_unknown_type(_yield_var_def_statement_with_unknown_type);
}
public void write_yield_var_def_statement_with_unknown_type(yield_var_def_statement_with_unknown_type _yield_var_def_statement_with_unknown_type)
{
write_statement(_yield_var_def_statement_with_unknown_type);
if (_yield_var_def_statement_with_unknown_type.vars == null)
{
bw.Write((byte)0);
}
else
{
bw.Write((byte)1);
_yield_var_def_statement_with_unknown_type.vars.visit(this);
}
}
public void visit(yield_variable_definitions_with_unknown_type _yield_variable_definitions_with_unknown_type)
{
bw.Write((Int16)215);
write_yield_variable_definitions_with_unknown_type(_yield_variable_definitions_with_unknown_type);
}
public void write_yield_variable_definitions_with_unknown_type(yield_variable_definitions_with_unknown_type _yield_variable_definitions_with_unknown_type)
{
write_declaration(_yield_variable_definitions_with_unknown_type);
if (_yield_variable_definitions_with_unknown_type.vars == null)
{
bw.Write((byte)0);
}
else
{
bw.Write((byte)1);
_yield_variable_definitions_with_unknown_type.vars.visit(this);
}
}
}

View file

@ -31312,6 +31312,518 @@ namespace PascalABCCompiler.SyntaxTree
}
///<summary>
///Неопознанный идентификатор. Откладывает определение необходимости захвата имени как поля класса до этапа семантики.
///</summary>
[Serializable]
public partial class yield_unknown_ident : ident
{
///<summary>
///Конструктор без параметров.
///</summary>
public yield_unknown_ident()
{
}
///<summary>
///Конструктор с параметрами.
///</summary>
public yield_unknown_ident(ident _UnknownID,ident _ClassName)
{
this._UnknownID=_UnknownID;
this._ClassName=_ClassName;
}
///<summary>
///Конструктор с параметрами.
///</summary>
public yield_unknown_ident(ident _UnknownID,ident _ClassName,SourceContext sc)
{
this._UnknownID=_UnknownID;
this._ClassName=_ClassName;
source_context = sc;
}
///<summary>
///Конструктор с параметрами.
///</summary>
public yield_unknown_ident(string _name,ident _UnknownID,ident _ClassName)
{
this._name=_name;
this._UnknownID=_UnknownID;
this._ClassName=_ClassName;
}
///<summary>
///Конструктор с параметрами.
///</summary>
public yield_unknown_ident(string _name,ident _UnknownID,ident _ClassName,SourceContext sc)
{
this._name=_name;
this._UnknownID=_UnknownID;
this._ClassName=_ClassName;
source_context = sc;
}
protected ident _UnknownID;
protected ident _ClassName;
///<summary>
///
///</summary>
public ident UnknownID
{
get
{
return _UnknownID;
}
set
{
_UnknownID=value;
}
}
///<summary>
///
///</summary>
public ident ClassName
{
get
{
return _ClassName;
}
set
{
_ClassName=value;
}
}
///<summary>
///Свойство для получения количества всех подузлов без элементов поля типа List
///</summary>
public override Int32 subnodes_without_list_elements_count
{
get
{
return 2;
}
}
///<summary>
///Свойство для получения количества всех подузлов. Подузлом также считается каждый элемент поля типа List
///</summary>
public override Int32 subnodes_count
{
get
{
return 2;
}
}
///<summary>
///Индексатор для получения всех подузлов
///</summary>
public override syntax_tree_node this[Int32 ind]
{
get
{
if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1)
throw new IndexOutOfRangeException();
switch(ind)
{
case 0:
return UnknownID;
case 1:
return ClassName;
}
return null;
}
set
{
if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1)
throw new IndexOutOfRangeException();
switch(ind)
{
case 0:
UnknownID = (ident)value;
break;
case 1:
ClassName = (ident)value;
break;
}
}
}
///<summary>
///Метод для обхода дерева посетителем
///</summary>
///<param name="visitor">Объект-посетитель.</param>
///<returns>Return value is void</returns>
public override void visit(IVisitor visitor)
{
visitor.visit(this);
}
}
///<summary>
///Узел для вычисления типа выражения используемого в теле функции-итератора (с yield)
///</summary>
[Serializable]
public partial class yield_unknown_expression_type : type_definition
{
///<summary>
///Конструктор без параметров.
///</summary>
public yield_unknown_expression_type()
{
}
///<summary>
///Конструктор с параметрами.
///</summary>
public yield_unknown_expression_type(var_def_statement _Vds)
{
this._Vds=_Vds;
}
///<summary>
///Конструктор с параметрами.
///</summary>
public yield_unknown_expression_type(var_def_statement _Vds,SourceContext sc)
{
this._Vds=_Vds;
source_context = sc;
}
///<summary>
///Конструктор с параметрами.
///</summary>
public yield_unknown_expression_type(type_definition_attr_list _attr_list,var_def_statement _Vds)
{
this._attr_list=_attr_list;
this._Vds=_Vds;
}
///<summary>
///Конструктор с параметрами.
///</summary>
public yield_unknown_expression_type(type_definition_attr_list _attr_list,var_def_statement _Vds,SourceContext sc)
{
this._attr_list=_attr_list;
this._Vds=_Vds;
source_context = sc;
}
protected var_def_statement _Vds;
///<summary>
///
///</summary>
public var_def_statement Vds
{
get
{
return _Vds;
}
set
{
_Vds=value;
}
}
///<summary>
///Свойство для получения количества всех подузлов без элементов поля типа List
///</summary>
public override Int32 subnodes_without_list_elements_count
{
get
{
return 2;
}
}
///<summary>
///Свойство для получения количества всех подузлов. Подузлом также считается каждый элемент поля типа List
///</summary>
public override Int32 subnodes_count
{
get
{
return 2;
}
}
///<summary>
///Индексатор для получения всех подузлов
///</summary>
public override syntax_tree_node this[Int32 ind]
{
get
{
if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1)
throw new IndexOutOfRangeException();
switch(ind)
{
case 0:
return attr_list;
case 1:
return Vds;
}
return null;
}
set
{
if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1)
throw new IndexOutOfRangeException();
switch(ind)
{
case 0:
attr_list = (type_definition_attr_list)value;
break;
case 1:
Vds = (var_def_statement)value;
break;
}
}
}
///<summary>
///Метод для обхода дерева посетителем
///</summary>
///<param name="visitor">Объект-посетитель.</param>
///<returns>Return value is void</returns>
public override void visit(IVisitor visitor)
{
visitor.visit(this);
}
}
///<summary>
///Узел-обертка для yield для определения типов локальных переменных в var_def_statement
///</summary>
[Serializable]
public partial class yield_var_def_statement_with_unknown_type : statement
{
///<summary>
///Конструктор без параметров.
///</summary>
public yield_var_def_statement_with_unknown_type()
{
}
///<summary>
///Конструктор с параметрами.
///</summary>
public yield_var_def_statement_with_unknown_type(var_def_statement _vars)
{
this._vars=_vars;
}
///<summary>
///Конструктор с параметрами.
///</summary>
public yield_var_def_statement_with_unknown_type(var_def_statement _vars,SourceContext sc)
{
this._vars=_vars;
source_context = sc;
}
protected var_def_statement _vars;
///<summary>
///
///</summary>
public var_def_statement vars
{
get
{
return _vars;
}
set
{
_vars=value;
}
}
///<summary>
///Свойство для получения количества всех подузлов без элементов поля типа List
///</summary>
public override Int32 subnodes_without_list_elements_count
{
get
{
return 1;
}
}
///<summary>
///Свойство для получения количества всех подузлов. Подузлом также считается каждый элемент поля типа List
///</summary>
public override Int32 subnodes_count
{
get
{
return 1;
}
}
///<summary>
///Индексатор для получения всех подузлов
///</summary>
public override syntax_tree_node this[Int32 ind]
{
get
{
if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1)
throw new IndexOutOfRangeException();
switch(ind)
{
case 0:
return vars;
}
return null;
}
set
{
if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1)
throw new IndexOutOfRangeException();
switch(ind)
{
case 0:
vars = (var_def_statement)value;
break;
}
}
}
///<summary>
///Метод для обхода дерева посетителем
///</summary>
///<param name="visitor">Объект-посетитель.</param>
///<returns>Return value is void</returns>
public override void visit(IVisitor visitor)
{
visitor.visit(this);
}
}
///<summary>
///Узел-обертка для yield для определения типов локальных переменных в variable_definitions
///</summary>
[Serializable]
public partial class yield_variable_definitions_with_unknown_type : declaration
{
///<summary>
///Конструктор без параметров.
///</summary>
public yield_variable_definitions_with_unknown_type()
{
}
///<summary>
///Конструктор с параметрами.
///</summary>
public yield_variable_definitions_with_unknown_type(variable_definitions _vars)
{
this._vars=_vars;
}
///<summary>
///Конструктор с параметрами.
///</summary>
public yield_variable_definitions_with_unknown_type(variable_definitions _vars,SourceContext sc)
{
this._vars=_vars;
source_context = sc;
}
protected variable_definitions _vars;
///<summary>
///
///</summary>
public variable_definitions vars
{
get
{
return _vars;
}
set
{
_vars=value;
}
}
///<summary>
///Свойство для получения количества всех подузлов без элементов поля типа List
///</summary>
public override Int32 subnodes_without_list_elements_count
{
get
{
return 1;
}
}
///<summary>
///Свойство для получения количества всех подузлов. Подузлом также считается каждый элемент поля типа List
///</summary>
public override Int32 subnodes_count
{
get
{
return 1;
}
}
///<summary>
///Индексатор для получения всех подузлов
///</summary>
public override syntax_tree_node this[Int32 ind]
{
get
{
if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1)
throw new IndexOutOfRangeException();
switch(ind)
{
case 0:
return vars;
}
return null;
}
set
{
if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1)
throw new IndexOutOfRangeException();
switch(ind)
{
case 0:
vars = (variable_definitions)value;
break;
}
}
}
///<summary>
///Метод для обхода дерева посетителем
///</summary>
///<param name="visitor">Объект-посетитель.</param>
///<returns>Return value is void</returns>
public override void visit(IVisitor visitor)
{
visitor.visit(this);
}
}
}

View file

@ -1214,6 +1214,55 @@ namespace PascalABCCompiler.SyntaxTree
}
// frninja 12/05/16 - хелпер для yield. Хранит типы локальных переменных метода-итератора
[Serializable]
public class yield_locals_type_map_helper
{
public Dictionary<var_def_statement, semantic_type_node> vars_type_map { get; private set; }
public yield_locals_type_map_helper()
{
vars_type_map = new Dictionary<var_def_statement, semantic_type_node>();
}
}
// end frninja
// frninja 12/05/16 - хелперы для yield
public partial class yield_unknown_expression_type : type_definition
{
public yield_locals_type_map_helper MapHelper { get; private set; }
public yield_unknown_expression_type(var_def_statement vds, yield_locals_type_map_helper map_helper)
{
this.Vds = vds;
this.MapHelper = map_helper;
}
}
public partial class yield_var_def_statement_with_unknown_type : statement
{
public yield_locals_type_map_helper map_helper { get; private set; }
public yield_var_def_statement_with_unknown_type(var_def_statement vds, yield_locals_type_map_helper map_helper)
{
this.vars = vds;
this.map_helper = map_helper;
}
}
public partial class yield_variable_definitions_with_unknown_type : declaration
{
public yield_locals_type_map_helper map_helper { get; private set; }
public yield_variable_definitions_with_unknown_type(variable_definitions vd, yield_locals_type_map_helper map_helper)
{
this.vars = vd;
this.map_helper = map_helper;
}
}
// end frninja
}

View file

@ -1276,6 +1276,30 @@ namespace PascalABCCompiler.SyntaxTree
///<param name="_no_type">Node to visit</param>
///<returns> Return value is void </returns>
void visit(no_type _no_type);
///<summary>
///Method to visit yield_unknown_ident.
///</summary>
///<param name="_yield_unknown_ident">Node to visit</param>
///<returns> Return value is void </returns>
void visit(yield_unknown_ident _yield_unknown_ident);
///<summary>
///Method to visit yield_unknown_expression_type.
///</summary>
///<param name="_yield_unknown_expression_type">Node to visit</param>
///<returns> Return value is void </returns>
void visit(yield_unknown_expression_type _yield_unknown_expression_type);
///<summary>
///Method to visit yield_var_def_statement_with_unknown_type.
///</summary>
///<param name="_yield_var_def_statement_with_unknown_type">Node to visit</param>
///<returns> Return value is void </returns>
void visit(yield_var_def_statement_with_unknown_type _yield_var_def_statement_with_unknown_type);
///<summary>
///Method to visit yield_variable_definitions_with_unknown_type.
///</summary>
///<param name="_yield_variable_definitions_with_unknown_type">Node to visit</param>
///<returns> Return value is void </returns>
void visit(yield_variable_definitions_with_unknown_type _yield_variable_definitions_with_unknown_type);
}

Binary file not shown.

View file

@ -4649,6 +4649,15 @@ namespace PascalABCCompiler.TreeConverter
internal void visit_method_call(SyntaxTree.method_call _method_call)
{
// frninja 01/03/16 - for iterator capturing (yield)
if (_method_call.dereferencing_value is yield_unknown_ident)
{
var nodeToVisit = new method_call(ProcessUnknownIdent(_method_call.dereferencing_value as yield_unknown_ident), _method_call.parameters);
visit(nodeToVisit);
return;
}
// end frninja
//lroman
if (_method_call.dereferencing_value is closure_substituting_node)
{
@ -9634,6 +9643,16 @@ namespace PascalABCCompiler.TreeConverter
hard_node_test_and_visit(_program_module.program_block);
context.check_labels(context.converted_namespace.labels);
// frninja 28/04/16 - режем мусорные методы хелперы yield
{
var toRemove = cnsn.functions.Where(m => m.name.StartsWith(YieldHelpers.YieldConsts.YieldHelperMethodPrefix)).ToArray();
foreach (var m in toRemove)
{
cnsn.functions.remove(m);
}
}
// end frninja
common_namespace_function_node main_function = new common_namespace_function_node(compiler_string_consts.temp_main_function_name,
null, null, cnsn, null);
main_function.function_code = context.code;
@ -10323,6 +10342,17 @@ namespace PascalABCCompiler.TreeConverter
CheckWaitedRefTypes(ctn);
is_direct_type_decl = true;
hard_node_test_and_visit(_type_declaration.type_def);
// frninja 28/04/16 - режем мусорные методы хелперы yield
{
var toRemove = ctn.methods.Where(m => m.name.StartsWith(YieldHelpers.YieldConsts.YieldHelperMethodPrefix)).ToArray();
foreach (var m in toRemove)
{
ctn.methods.remove(m);
}
}
// end frninja
is_direct_type_decl = false;
if (_type_declaration.attributes != null)
{
@ -18723,6 +18753,111 @@ namespace PascalABCCompiler.TreeConverter
visit(mc);
}
// frninja 04/03/16 - для yield
private bool CheckUnknownIdentNeedsClassCapture(SyntaxTree.yield_unknown_ident _unk)
{
string Consts__Self = YieldHelpers.YieldConsts.Self;
// Find semantic class containing iterator (yield-method) with unknown ident
var iteratorContainingClass = context._ctn.fields.Where(f => f.name == Consts__Self).First().type;
//var iteratorContainingClass = context._cmn.types.Where(t => t.name == _unk.ClassName.name).First();
if (iteratorContainingClass != null)
{
// Search for unknown ident in class
var found = iteratorContainingClass.find(_unk.UnknownID.name);
if ((object)found != null)
{
// class_field - поле класса
// common_method_node - метод класса
// common_property_node - свойство класса
// че там с .NET как базовым?
// compiled_function_node - метод базового .NET класса
// compiled_property_node - свойство базового .NET класса
// че с классом из другого модуля?
// то же что и с классом из этого же
if (found.sym_info is class_field
|| found.sym_info is common_method_node
|| found.sym_info is common_property_node
|| found.sym_info is compiled_function_node
|| found.sym_info is compiled_property_node)
{
if (found.access_level != access_level.al_private)
{
return true;
}
}
// common_namespace_function_node - глобальный метод
}
}
return false;
}
private dot_node CaptureUnknownIdent(yield_unknown_ident unk)
{
string Consts__Self = YieldHelpers.YieldConsts.Self;
return new dot_node(new dot_node(new ident("self"), new ident(Consts__Self)), unk.UnknownID);
}
private SyntaxTree.addressed_value_funcname ProcessUnknownIdent(yield_unknown_ident unk)
{
if (CheckUnknownIdentNeedsClassCapture(unk))
{
return CaptureUnknownIdent(unk);
}
else
{
return unk.UnknownID;
}
}
// frninja - захват полей класса для yield
public override void visit(SyntaxTree.yield_unknown_ident _unk)
{
ProcessUnknownIdent(_unk).visit(this);
}
public override void visit(SyntaxTree.yield_unknown_expression_type _unk_expr)
{
_unk_expr.MapHelper.vars_type_map[_unk_expr.Vds].visit(this);
}
// frninja - заполнение хелпера типов локальных переменных для yield
public override void visit(SyntaxTree.yield_var_def_statement_with_unknown_type _vars)
{
if ((object)_vars.vars.vars_type != null)
return;
var t = convert_strong(_vars.vars.inital_value);
_vars.map_helper.vars_type_map[_vars.vars] = new SyntaxTree.semantic_type_node(t.type);
// Visit stored vars
_vars.vars.visit(this);
}
// frninja - заполнение хелпера типов локальных переменных для yield// frninja - заполнение хелпера типов локальных переменных для yield
public override void visit(SyntaxTree.yield_variable_definitions_with_unknown_type _vars)
{
foreach (var vd in _vars.vars.list)
{
if ((object)vd.vars_type != null)
continue;
var t = convert_strong(vd.inital_value);
_vars.map_helper.vars_type_map[vd] = new SyntaxTree.semantic_type_node(t.type);
}
// Visit stored vars
_vars.vars.visit(this);
}
// end frninja
/*public SyntaxTree.question_colon_expression ConvertToQCE(dot_question_node dqn)
{
// Неверно работает. Пока не используется. Доделать

View file

@ -258,6 +258,10 @@
<Compile Include="OpenMP\VarFinderSyntaxVisitor.cs" />
<Compile Include="TreeRealization\generics.cs" />
<Compile Include="TreeRealization\labels.cs" />
<ProjectReference Include="..\Yield\YieldHelpers\YieldHelpers.csproj">
<Project>{ce5c55c2-a11c-4e94-a9fa-3fc6ca3e4c09}</Project>
<Name>YieldHelpers</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">

View file

@ -791,6 +791,10 @@
<Project>{1C9C945A-586D-42A2-A06B-65D84FA7FF78}</Project>
<Name>TreeConverter</Name>
</ProjectReference>
<ProjectReference Include="..\Yield\SyntaxVisitors\SyntaxVisitors.csproj">
<Project>{a9ab4282-83b4-41a7-86c3-e5bf6a45e7e2}</Project>
<Name>SyntaxVisitors</Name>
</ProjectReference>
<ProjectReference Include="FormsDesignerBinding\Dependecies\src\Main\Base\Project\ICSharpCode.SharpDevelop.csproj">
<Project>{2748AD25-9C63-4E12-877B-4DCE96FBED54}</Project>
<Name>ICSharpCode.SharpDevelop</Name>

167
Yield/ParsePABC1/.gitignore vendored Normal file
View file

@ -0,0 +1,167 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
.vs/
# Build results
[Bb]inaries/
[Dd]ebug/
[Rr]elease/
x64/
[Bb]in/
[Oo]bj/
# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
!packages/*/build/
# NuGet restore semaphore
build/ToolsetPackages/toolsetpackages.semaphore
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
UnitTestResults.html
# NuGet V3 artifacts
*-packages.config
*.nuget.props
*.nuget.targets
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.wrn
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.scc
# Visual Studio cache files
*.sln.ide/
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.Publish.xml
# NuGet Packages Directory
packages/
# Windows Azure Build Output
csx
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.[Pp]ublish.xml
*.pfx
*.publishsettings
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
App_Data/*.mdf
App_Data/*.ldf
#LightSwitch generated files
GeneratedArtifacts/
_Pvt_Extensions/
ModelManifest.xml
# =========================
# Windows detritus
# =========================
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Mac desktop service store files
.DS_Store

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>

View file

@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PascalABCCompiler.Errors;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
using PascalABCCompiler.ParserTools;
using SyntaxVisitors;
namespace ParsePABC1
{
class Program
{
// PascalABCSaushkinParser reference needed!!! DO NOT REMOVE!!!
static syntax_tree_node ParseFile(string fname)
{
Compiler c = new Compiler();
// c.SyntaxTreeChanger = new YieldDesugarSyntaxTreeConverter();
var opts = new CompilerOptions(fname, CompilerOptions.OutputType.ConsoleApplicaton);
var res = c.Compile(opts);
var err = new List<Error>();
var txt = System.IO.File.ReadAllText(fname);
var cu = c.ParsersController.Compile(fname, txt, err, PascalABCCompiler.Parsers.ParseMode.Normal);
if (cu == null)
{
Console.WriteLine("Не распарсилось");
}
return cu;
}
static void Main(string[] args)
{
var cu = ParseFile(@"C:\Users\Oleg\Documents\Visual Studio 2015\Projects\C#\Compilers\PascalABC.NET_Diplom\Yield\tests\template\yieldSimpleTemplateWithField.pas");
if (cu == null)
return;
var yieldVis = new ProcessYieldCapturedVarsVisitor();
cu.visit(yieldVis);
cu.visit(new SimplePrettyPrinterVisitor());
Console.ReadKey();
}
}
}

View file

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// Управление общими сведениями о сборке осуществляется с помощью
// набора атрибутов. Измените значения этих атрибутов, чтобы изменить сведения,
// связанные со сборкой.
[assembly: AssemblyTitle("ParsePABC")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Hewlett-Packard")]
[assembly: AssemblyProduct("ParsePABC")]
[assembly: AssemblyCopyright("Copyright © Hewlett-Packard 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Параметр ComVisible со значением FALSE делает типы в сборке невидимыми
// для COM-компонентов. Если требуется обратиться к типу в этой сборке через
// COM, задайте атрибуту ComVisible значение TRUE для этого типа.
[assembly: ComVisible(false)]
// Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM
[assembly: Guid("d1b107ed-e2bb-4d21-98d0-a2f99c08d2b0")]
// Сведения о версии сборки состоят из следующих четырех значений:
//
// Основной номер версии
// Дополнительный номер версии
// Номер сборки
// Редакция
//
// Можно задать все значения или принять номера сборки и редакции по умолчанию
// используя "*", как показано ниже:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View file

@ -0,0 +1,111 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{D1B107ED-E2BB-4D21-98D0-A2F99C08D2B0}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ParsePABC</RootNamespace>
<AssemblyName>ParsePABC</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="ICSharpCode.NRefactory, Version=4.2.1.8805, Culture=neutral, PublicKeyToken=efe927acf176eea2, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\pascalabcnet\_ParsePABC1\dlls\ICSharpCode.NRefactory.dll</HintPath>
</Reference>
<Reference Include="Localization, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\pascalabcnet\_ParsePABC1\dlls\Localization.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ProgramOld.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\CompilerTools\CompilerTools.csproj">
<Project>{a25d26fb-3043-4bcf-833e-e3f4c3be795e}</Project>
<Name>CompilerTools</Name>
</ProjectReference>
<ProjectReference Include="..\..\Compiler\Compiler.csproj">
<Project>{1e42361a-eda3-4872-88af-a3aaf600d36d}</Project>
<Name>Compiler</Name>
</ProjectReference>
<ProjectReference Include="..\..\Errors\Errors.csproj">
<Project>{44a01f9e-dce7-470c-aae5-c3de0ccbee3b}</Project>
<Name>Errors</Name>
</ProjectReference>
<ProjectReference Include="..\..\Parsers\PascalABCParserNewSaushkin\PascalABCSaushkinParser.csproj">
<Project>{1443f539-dcc7-4491-b4fd-b716c739db3c}</Project>
<Name>PascalABCSaushkinParser</Name>
</ProjectReference>
<ProjectReference Include="..\..\ParserTools\ParserTools.csproj">
<Project>{af2efd7b-69dd-4b43-af65-b59b29349c23}</Project>
<Name>ParserTools</Name>
</ProjectReference>
<ProjectReference Include="..\..\SyntaxTreeConverters\SyntaxTreeConverters.csproj">
<Project>{f10a5330-dcf4-4533-877c-7b1b1be23884}</Project>
<Name>SyntaxTreeConverters</Name>
</ProjectReference>
<ProjectReference Include="..\..\SyntaxTree\SyntaxTree.csproj">
<Project>{c2cac65a-b2ae-4ccc-b067-e6b8e75df73a}</Project>
<Name>SyntaxTree</Name>
</ProjectReference>
<ProjectReference Include="..\SyntaxVisitors\SyntaxVisitors.csproj">
<Project>{a9ab4282-83b4-41a7-86c3-e5bf6a45e7e2}</Project>
<Name>SyntaxVisitors</Name>
</ProjectReference>
<ProjectReference Include="..\YieldConversionSyntax\YieldConversionSyntax.csproj">
<Project>{276ee073-60f6-46d2-8811-1b8026bcaada}</Project>
<Name>YieldConversionSyntax</Name>
</ProjectReference>
<ProjectReference Include="..\YieldHelpers\YieldHelpers.csproj">
<Project>{ce5c55c2-a11c-4e94-a9fa-3fc6ca3e4c09}</Project>
<Name>YieldHelpers</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

167
Yield/SyntaxVisitors/.gitignore vendored Normal file
View file

@ -0,0 +1,167 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
.vs/
# Build results
[Bb]inaries/
[Dd]ebug/
[Rr]elease/
x64/
[Bb]in/
[Oo]bj/
# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
!packages/*/build/
# NuGet restore semaphore
build/ToolsetPackages/toolsetpackages.semaphore
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
UnitTestResults.html
# NuGet V3 artifacts
*-packages.config
*.nuget.props
*.nuget.targets
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.wrn
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.scc
# Visual Studio cache files
*.sln.ide/
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.Publish.xml
# NuGet Packages Directory
packages/
# Windows Azure Build Output
csx
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.[Pp]ublish.xml
*.pfx
*.publishsettings
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
App_Data/*.mdf
App_Data/*.ldf
#LightSwitch generated files
GeneratedArtifacts/
_Pvt_Extensions/
ModelManifest.xml
# =========================
# Windows detritus
# =========================
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Mac desktop service store files
.DS_Store

View file

@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
namespace SyntaxVisitors
{
public class AllVarsInProcYields : CollectUpperNamespacesVisitor
{
public FindMainIdentsVisitor mids = new FindMainIdentsVisitor();
public Dictionary<procedure_definition, ISet<string>> d = new Dictionary<procedure_definition, ISet<string>>();
public int countNodesVisited;
public AllVarsInProcYields()
{
PrintInfo = false;
}
public override void Enter(syntax_tree_node st)
{
base.Enter(st);
countNodesVisited++;
if (st is procedure_definition)
{
// пока вложенные процедуры не анализируются, хотя надо
mids.vars.Clear();
}
// сокращение обходимых узлов. Как сделать фильтр по тем узлам, которые необходимо обходить? Например, все операторы (без выражений и описаний), все описания (без операторов)
if (st is assign || st is var_def_statement || st is procedure_call || st is procedure_header || st is expression)
{
visitNode = false;
}
}
public override void Exit(syntax_tree_node st)
{
if (st is procedure_definition)
{
if (mids.vars.Count>0)
{
d[st as procedure_definition] = new HashSet<string>(mids.vars);
}
var fld = new FindLocalDefsVisitor();
st.visit(fld);
fld.Print();
var t = fld.ids.Intersect(mids.vars); // идентификаторы, захваченные из локального контекста
}
base.Exit(st);
}
public override void visit(yield_node yn)
{
yn.visit(mids);
// mids.vars - надо установить, какие из них - локальные, какие - из этого класса, какие - являются параметрами функции, а какие - глобальные (все остальные)
// те, которые являются параметрами, надо скопировать в локальные переменные и переименовать использование везде по ходу данной функции
// самое сложное - переменные-поля этого класса - они требуют в создаваемом классе, реализующем итератор, хранить Self текущего класса и добавлять это Self везде по ходу алгоритма
// вначале будем считать, что переменные-поля этого класса и переменные-параметры не захватываются yield
//base.visit(yn);
}
public void PrintDict()
{
foreach (var a in d)
{
Console.Write("{0}: {1} ", a.Key.proc_header.name.meth_name, a.Value.Count);
foreach (var v in a.Value)
Console.Write("{0}, ", v);
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("countNodesVisited={0}", countNodesVisited);
}
}
}
}

View file

@ -0,0 +1,102 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
namespace SyntaxVisitors
{
public class BaseChangeVisitor : CollectUpperNodesVisitor
{
private bool _rootAdded = false;
public override void DefaultVisit(syntax_tree_node n)
{
// frninja 07/12/15
if (!_rootAdded)
{
_rootAdded = true;
ProcessNode(n);
}
// Элементы списков - с конца в начало чтобы можно было эти элементы изменять по ходу (удалять/вставлять/заменять один несколькими)
var Сount = n.subnodes_count;
var СountWithoutListElements = n.subnodes_without_list_elements_count;
for (var i = 0; i < СountWithoutListElements; i++)
ProcessNode(n[i]);
for (var i = Сount - 1; i >= СountWithoutListElements; i--) // в обратном порядке
ProcessNode(n[i]);
}
public void Replace(syntax_tree_node from, syntax_tree_node to)
{
var upper = UpperNode();
if (upper == null)
throw new Exception("У корневого элемента нельзя получить UpperNode");
upper.Replace(from, to);
}
public T UpperNodeAs<T>(int up = 1) where T : syntax_tree_node
{
var stl = UpperNode(up) as T;
if (stl == null)
throw new Exception("Элемент вложен не в " + typeof(T));
return stl;
}
public T UpperTo<T>() where T : syntax_tree_node
{
syntax_tree_node upperNode = null;
int up = 1;
do
{
upperNode = UpperNode(up);
++up;
}
while ((object)upperNode != null && !(upperNode is T));
return (object)upperNode != null ? upperNode as T : null;
}
public bool DeleteInIdentList(ident id)
{
var idl = UpperNodeAs<ident_list>();
return idl.Remove(id);
}
public bool DeleteInStatementList(statement st)
{
var stl = UpperNodeAs<statement_list>();
return stl.Remove(st);
}
public static IEnumerable<statement> SeqStatements(params statement[] seq)
{
var l = new List<statement>();
foreach (var st in seq)
if (st is statement_list)
l.AddRange((st as statement_list).list);
else l.Add(st);
return l;
}
public void ReplaceStatement(statement from, statement to)
{
var stl = UpperNodeAs<statement_list>();
stl.Replace(from, to);
}
public void ReplaceStatement(statement from, IEnumerable<statement> to)
{
var stl = UpperNodeAs<statement_list>();
stl.Replace(from, to);
}
}
}

View file

@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
namespace SyntaxVisitors
{
public class BaseEnterExitVisitor : WalkingVisitorNew
{
public BaseEnterExitVisitor()
{
OnEnter = Enter;
OnLeave = Exit;
}
public virtual void Enter(syntax_tree_node st)
{
}
public virtual void Exit(syntax_tree_node st)
{
}
}
}

View file

@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
namespace SyntaxVisitors
{
public class CollectUpperNamespacesVisitor : CollectUpperNodesVisitor
{
protected List<declaration> list = new List<declaration>();
public bool PrintInfo = true;
public override void Enter(syntax_tree_node st)
{
base.Enter(st);
if (st is procedure_definition || st is class_definition)
{
list.Add(st as declaration);
if (PrintInfo)
Console.Write("+: "+st.GetType().Name);
}
}
public override void Exit(syntax_tree_node st)
{
if (st is procedure_definition || st is class_definition)
{
if (PrintInfo)
Console.WriteLine("-: " + st.GetType().Name);
list.RemoveAt(list.Count - 1);
}
base.Exit(st);
}
public override void visit(procedure_definition p)
{
if (PrintInfo)
Console.WriteLine(" " + p.proc_header.name.meth_name);
var ld = new FindLocalDefsVisitor();
p.visit(ld);
base.visit(p);
}
public override void visit(class_definition cl)
{
type_declarations tds = UpperNode(2) as type_declarations;
if (PrintInfo)
{
var f = tds.types_decl.Find(td => td.type_def == cl);
Console.WriteLine(" " + f.type_name);
}
base.visit(cl);
}
}
}

View file

@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
namespace SyntaxVisitors
{
public class CollectUpperNodesVisitor : BaseEnterExitVisitor
{
protected List<syntax_tree_node> listNodes = new List<syntax_tree_node>();
public syntax_tree_node CurrentNode
{
get
{
return listNodes[listNodes.Count - 1];
}
}
public syntax_tree_node UpperNode(int up = 1)
{
if (listNodes.Count - 1 - up < 0)
return null;
return listNodes[listNodes.Count - 1 - up];
}
public override void Enter(syntax_tree_node st)
{
listNodes.Add(st);
}
public override void Exit(syntax_tree_node st)
{
listNodes.RemoveAt(listNodes.Count - 1);
}
}
}

View file

@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
namespace SyntaxVisitors
{
public class HasStatementVisitor<T> : WalkingVisitorNew
where T : statement
{
private bool foundT = false;
public static bool Has(syntax_tree_node node)
{
HasStatementVisitor<T> vis = new HasStatementVisitor<T>();
vis.ProcessNode(node);
return vis.foundT;
}
public override void DefaultVisit(syntax_tree_node node)
{
if (node is T)
foundT = true;
else
base.DefaultVisit(node);
}
}
}

View file

@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
namespace SyntaxVisitors
{
public class FindLocalDefsVisitor : WalkingVisitorNew // Запускать только для подпрограмм
{
public ISet<string> ids = new HashSet<string>();
private bool indef = false;
public override void visit(ident id)
{
if (indef)
ids.Add(id.name);
}
public override void visit(var_def_statement defs)
{
indef = true;
ProcessNode(defs.vars); // исключаем типы - просматриваем только имена переменных
indef = false;
}
public void Print()
{
foreach (var x in ids)
Console.Write(x + ", ");
Console.WriteLine();
}
}
public class FindMainIdentsVisitor : WalkingVisitorNew // в выражении yield это надо будет.
{
public HashSet<string> vars = new HashSet<string>();
public override void visit(ident id)
{
vars.Add(id.name);
}
public override void visit(dot_node dn)
{
ProcessNode(dn.left);
if (dn.right.GetType() != typeof(ident))
ProcessNode(dn.right);
}
}
}

View file

@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PascalABCCompiler.Errors;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
namespace SyntaxVisitors
{
public class ChangeWhileVisitor : BaseChangeVisitor
{
int lbnum = 0;
public static ChangeWhileVisitor New
{
get { return new ChangeWhileVisitor(); }
}
public string newLabelName()
{
lbnum++;
return "lb#" + lbnum.ToString();
}
public override void visit(while_node wn)
{
ProcessNode(wn.statements);
var gt1 = new goto_statement(newLabelName());
var gt2 = new goto_statement(newLabelName());
var gt3 = new goto_statement(newLabelName());
var if0 = new if_node(wn.expr, gt1, null);
var lb3 = new labeled_statement(gt3.label, if0);
var lb1 = new labeled_statement(gt1.label, wn.statements);
var lb2 = new labeled_statement(gt2.label, new empty_statement());
var stl = new statement_list(lb3, gt2, lb1, gt3, lb2);
Replace(wn, stl);
// в declarations ближайшего блока добавить описание labels
block bl = listNodes.FindLast(x => x is block) as block;
var ld = new label_definitions(gt1.label, gt2.label, gt3.label);
bl.defs.Add(ld);
}
}
}

View file

@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SyntaxVisitors
{
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
/// <summary>
/// Reference Article http://www.codeproject.com/KB/tips/SerializedObjectCloner.aspx
/// Provides a method for performing a deep copy of an object.
/// Binary Serialization is used to perform the copy.
/// </summary>
public static class ObjectCopier
{
/// <summary>
/// Perform a deep Copy of the object.
/// </summary>
/// <typeparam className="T">The type of object being copied.</typeparam>
/// <param className="source">The object instance to copy.</param>
/// <returns>The copied object.</returns>
public static T Clone<T>(T source)
{
if (!typeof(T).IsSerializable)
{
throw new ArgumentException("The type must be serializable.", "source");
}
// Don't serialize a null object, simply return the default for that object
if (Object.ReferenceEquals(source, null))
{
return default(T);
}
IFormatter formatter = new BinaryFormatter();
Stream stream = new MemoryStream();
using (stream)
{
formatter.Serialize(stream, source);
stream.Seek(0, SeekOrigin.Begin);
return (T)formatter.Deserialize(stream);
}
}
}
}

View file

@ -0,0 +1,120 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
namespace SyntaxVisitors
{
public class CalcConstExprs : BaseChangeVisitor // вычисление целых и вещественных константных выражений на этапе парсинга
{
public override void Exit(syntax_tree_node st)
{
bracket_expr bre = st as bracket_expr;
if (bre != null)
{
if (bre.expr is int32_const)
Replace(st, bre.expr);
}
bin_expr vs = st as bin_expr;
if (vs != null)
{
if (vs.left is int32_const && vs.right is int32_const)
{
var a = vs.left as int32_const;
var b = vs.right as int32_const;
var op = vs.operation_type;
syntax_tree_node res;
switch (op)
{
case Operators.Plus:
res = new int32_const(a.val + b.val);
break;
case Operators.Minus:
res = new int32_const(a.val - b.val);
break;
case Operators.Multiplication:
res = new int32_const(a.val * b.val);
break;
case Operators.Division:
res = new double_const((double)a.val / b.val);
break;
case Operators.Greater:
res = new bool_const(a.val > b.val);
break;
case Operators.Less:
res = new bool_const(a.val < b.val);
break;
case Operators.GreaterEqual:
res = new bool_const(a.val >= b.val);
break;
case Operators.LessEqual:
res = new bool_const(a.val <= b.val);
break;
default:
res = vs;
break;
}
Replace(vs, res);
}
if (vs.left is int32_const && vs.right is double_const || vs.right is int32_const && vs.left is double_const || vs.left is double_const && vs.right is double_const)
{
double x,y;
if (vs.left is int32_const)
x = (vs.left as int32_const).val;
else
x = (vs.left as double_const).val;
if (vs.right is int32_const)
y = (vs.right as int32_const).val;
else
y = (vs.right as double_const).val;
var op = vs.operation_type;
syntax_tree_node res;
switch (op)
{
case Operators.Plus:
res = new double_const(x + y);
break;
case Operators.Minus:
res = new double_const(x - y);
break;
case Operators.Multiplication:
res = new double_const(x * y);
break;
case Operators.Division:
res = new double_const(x / y);
break;
case Operators.Greater:
res = new bool_const(x > y);
break;
case Operators.Less:
res = new bool_const(x < y);
break;
case Operators.GreaterEqual:
res = new bool_const(x >= y);
break;
case Operators.LessEqual:
res = new bool_const(x <= y);
break;
default:
res = vs;
break;
}
Replace(vs, res);
}
}
base.Exit(st); // это обязательно!
}
}
}

View file

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// Управление общими сведениями о сборке осуществляется с помощью
// набора атрибутов. Измените значения этих атрибутов, чтобы изменить сведения,
// связанные со сборкой.
[assembly: AssemblyTitle("SyntaxVisitors")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Hewlett-Packard")]
[assembly: AssemblyProduct("SyntaxVisitors")]
[assembly: AssemblyCopyright("Copyright © Hewlett-Packard 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Параметр ComVisible со значением FALSE делает типы в сборке невидимыми
// для COM-компонентов. Если требуется обратиться к типу в этой сборке через
// COM, задайте атрибуту ComVisible значение TRUE для этого типа.
[assembly: ComVisible(false)]
// Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM
[assembly: Guid("a9ab4282-83b4-41a7-86c3-e5bf6a45e7e2")]
// Сведения о версии сборки состоят из следующих четырех значений:
//
// Основной номер версии
// Дополнительный номер версии
// Номер сборки
// Редакция
//
// Можно задать все значения или принять номера сборки и редакции по умолчанию
// используя "*", как показано ниже:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View file

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{A9AB4282-83B4-41A7-86C3-E5BF6A45E7E2}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>SyntaxVisitors</RootNamespace>
<AssemblyName>SyntaxVisitors</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<StartupObject />
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="AllVarsInProcYieldsProba.cs" />
<Compile Include="BaseVisitors\BaseChangeVisitor.cs" />
<Compile Include="BaseVisitors\BaseEnterExitVisitor.cs" />
<Compile Include="BaseVisitors\CollectNamespaces.cs" />
<Compile Include="BaseVisitors\CollectUpperNodesVisitor.cs" />
<Compile Include="BaseVisitors\HasStatementVisitor.cs" />
<Compile Include="BaseVisitors\SmallHelperVisitors.cs" />
<Compile Include="ChangeWhileVisitor.cs" />
<Compile Include="ObjectCopier.cs" />
<Compile Include="Optimization\CalcConstExprs.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="UniversalVisitors\CountNodesVisitor.cs" />
<Compile Include="UniversalVisitors\DeleteRedundantBeginEnds.cs" />
<Compile Include="UniversalVisitors\SimplePrettyPrinterVisitor.cs" />
<Compile Include="YieldVisitors\CheckVariablesRedefenitionVisitor.cs" />
<Compile Include="YieldVisitors\CollectClassMethodsVisitor.cs" />
<Compile Include="YieldVisitors\CollectClassPropertiesVisitor.cs" />
<Compile Include="YieldVisitors\CollectUnitGlobalsVisitor.cs" />
<Compile Include="YieldVisitors\DeleteAllLocalDefs.cs" />
<Compile Include="YieldVisitors\DeleteLocalDefs.cs" />
<Compile Include="YieldVisitors\CollectClassFieldsVisitor.cs" />
<Compile Include="YieldVisitors\LoweringVisitor.cs" />
<Compile Include="YieldVisitors\LocalVariablesTypeDetectorHelperVisior.cs" />
<Compile Include="YieldVisitors\MarkMethodHasYieldVisitor.cs" />
<Compile Include="YieldVisitors\ProcessYieldsCapturedVars.cs" />
<Compile Include="YieldVisitors\RenameSameBlockLocalVarsVisitor.cs" />
<Compile Include="YieldVisitors\ReplaceCapturedVariablesVisitor.cs" />
<Compile Include="YieldVisitors\ReplaceFormalParametersRefsVisitor.cs" />
<Compile Include="YieldVisitors\ReplaceForVariableVisitor.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Compiler\Compiler.csproj">
<Project>{1e42361a-eda3-4872-88af-a3aaf600d36d}</Project>
<Name>Compiler</Name>
</ProjectReference>
<ProjectReference Include="..\..\Errors\Errors.csproj">
<Project>{44a01f9e-dce7-470c-aae5-c3de0ccbee3b}</Project>
<Name>Errors</Name>
</ProjectReference>
<ProjectReference Include="..\..\ParserTools\ParserTools.csproj">
<Project>{af2efd7b-69dd-4b43-af65-b59b29349c23}</Project>
<Name>ParserTools</Name>
</ProjectReference>
<ProjectReference Include="..\..\SyntaxTree\SyntaxTree.csproj">
<Project>{c2cac65a-b2ae-4ccc-b067-e6b8e75df73a}</Project>
<Name>SyntaxTree</Name>
</ProjectReference>
<ProjectReference Include="..\YieldHelpers\YieldHelpers.csproj">
<Project>{ce5c55c2-a11c-4e94-a9fa-3fc6ca3e4c09}</Project>
<Name>YieldHelpers</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View file

@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
namespace SyntaxVisitors
{
public class CountNodesVisitor : BaseEnterExitVisitor
{
public Dictionary<System.Type, int> d = new Dictionary<System.Type, int>();
public int exprcount,statcount;
public override void Enter(syntax_tree_node st)
{
if (d.ContainsKey(st.GetType()))
d[st.GetType()] += 1;
else d[st.GetType()] = 1;
if (st is expression)
exprcount++;
if (st is statement)
statcount++;
}
public void PrintSortedByValue()
{
var q = d.Select(x => new { x.Key, x.Value }).OrderByDescending(y => y.Value);
foreach (var a in q)
Console.WriteLine("{0}: {1} ", a.Key.Name, a.Value);
Console.WriteLine();
Console.WriteLine("Expressions Count: {0}", exprcount);
Console.WriteLine("Statements Count: {0}", statcount);
}
public void Print()
{
foreach (var a in d)
Console.WriteLine("{0}: {1} ", a.Key.Name, a.Value);
}
}
}

View file

@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PascalABCCompiler.Errors;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
namespace SyntaxVisitors
{
public class DeleteRedundantBeginEnds : BaseChangeVisitor
{
public override void Exit(syntax_tree_node st)
{
var stl = st as statement_list;
if (stl != null && UpperNode() is statement_list)
ReplaceStatement(stl, stl.subnodes);
var lst = st as labeled_statement;
if (lst != null)
{
var sttl = lst.to_statement as statement_list;
if (sttl != null)
{
sttl.subnodes[0] = new labeled_statement(lst.label_name, sttl.subnodes[0]); // а если [0] элемента вообще нет?
ReplaceStatement(lst,sttl.subnodes);
}
}
base.Exit(st);
}
}
}

View file

@ -0,0 +1,209 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PascalABCCompiler.Errors;
using PascalABCCompiler.PCU;
using PascalABCCompiler.SemanticTreeConverters;
using System.CodeDom.Compiler;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
namespace SyntaxVisitors
{
public class SimplePrettyPrinterVisitor : WalkingVisitorNew
{
int off = 0;
bool printNodeType = false;
public static SimplePrettyPrinterVisitor New
{
get { return new SimplePrettyPrinterVisitor(); }
}
public SimplePrettyPrinterVisitor()
{
OnEnter = Enter;
OnLeave = Exit;
}
public void Println(string s)
{
Console.Write(new string(' ', off));
Console.WriteLine(s);
}
public void Print(string s)
{
Console.Write(new string(' ', off));
Console.Write(s);
}
public void PrintNoOffset(string s)
{
Console.Write(s);
}
public void PrintlnNoOffset(string s)
{
Console.WriteLine(s);
}
public void PrintlnNode(syntax_tree_node st)
{
if (printNodeType)
Console.Write(st.GetType().Name + ": ");
Console.WriteLine(new string(' ', off)+st);
}
public virtual void Enter(syntax_tree_node st)
{
if (st is statement_list)
{
Println("begin");
off += 2;
}
else if (st is type_declarations) // надо в visit и самому всё обрабатывать
{
var tds = st is type_declarations;
Println("type ");
off += 2;
}
else if (st is case_variant)
{
var td = st as case_variant;
Println(td.conditions.ToString()+": ");
off += 2;
//ProcessNode(td.type_def);
//visitNode = false;
}
else if (st is type_declaration)
{
var td = st as type_declaration;
Print(td.type_name + " = ");
ProcessNode(td.type_def);
visitNode = false;
}
else if (st is class_definition)
{
var cd = st as class_definition;
PrintNoOffset("class");
if (cd.class_parents != null && cd.class_parents.types.Count > 0)
{
PrintlnNoOffset("(" + cd.class_parents.ToString() + ")");
}
else
PrintlnNoOffset("");
off += 2;
ProcessNode(cd.body);
visitNode = false;
}
else if (st is access_modifer_node)
{
var am = st as access_modifer_node;
Println(am.access_level.ToString());
}
else if (st is variable_definitions)
{
var vds = st as variable_definitions;
Println("var");
off += 2;
}
else if (st is var_def_statement)
{
var vds = st as var_def_statement;
Println(vds.ToString());
}
else if (st is empty_statement || st is declarations || st is block || st is class_body || st is class_members || st is case_variants || st is program_module)
{
}
else if (st is if_node)
{
var ifn = st as if_node;
Println("if " + ifn.condition.ToString() + " then");
off += 2;
ProcessNode(ifn.then_body);
if (ifn.else_body == null)
{
visitNode = false;
return;
}
off -= 2;
Println("else ");
off += 2;
ProcessNode(ifn.else_body);
visitNode = false;
}
else if (st is while_node)
{
var wn = st as while_node;
Println("while " + wn.expr.ToString() + " do");
off += 2;
}
else if (st is case_node)
{
var cn = st as case_node;
Println("case " + cn.param.ToString() + " of");
off += 2;
}
else if (st is labeled_statement)
{
var lst = st as labeled_statement;
Println(lst.label_name.name + ": ");
ProcessNode(lst.to_statement);
visitNode = false;
}
else if (st is var_statement || st is procedure_header)
{
Println(st.ToString());
visitNode = false;
}
else if (st is procedure_definition)
{
Println("");
}
else if (st is statement || st is variable_definitions || st is label_definitions)
{
PrintlnNode(st);
if (st is labeled_statement)
visitNode = false;
}
else if (st is token_info)
{
var s = st.ToString();
if (s == "begin" || s == "end")
return;
PrintlnNode(st);
}
else
{
var q = st.GetType().GetMethod("ToString", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly);
if (q == null)
Println(st.GetType().Name);
}
}
public virtual void Exit(syntax_tree_node st)
{
if (st is statement_list)
{
off -= 2;
Println("end");
}
else if (st is while_node || st is if_node || st is type_declarations || st is variable_definitions || st is case_variant)
{
off -= 2;
}
else if (st is class_definition || st is case_node)
{
off -= 2;
Println("end;");
}
}
}
}

View file

@ -0,0 +1,140 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
namespace SyntaxVisitors
{
public class CheckVariablesRedefenitionVisitor : WalkingVisitorNew
{
private ISet<string> UpperBlockNames { get; set; }
// Map :: CurrentLevel -> { BlockNames }
private List<ISet<string>> BlockNamesStack { get; set; }
private int CurrentLevel = -1;
public CheckVariablesRedefenitionVisitor(ISet<string> upperBlockNames)
{
//this.UpperBlockNames = upperBlockNames;
this.UpperBlockNames = new HashSet<string>();
this.BlockNamesStack = new List<ISet<string>>(10);
}
public override void visit(formal_parameters fp)
{
foreach (var id in fp.params_list.SelectMany(tp => tp.idents.idents))
{
CheckVariableAlreadyDefined(id);
UpperBlockNames.Add(id.name);
}
}
public override void visit(variable_definitions vd)
{
foreach (var id in vd.var_definitions.SelectMany(vds => vds.vars.idents))
{
CheckVariableAlreadyDefined(id);
UpperBlockNames.Add(id.name);
}
base.visit(vd);
}
/*
* // Scope Level 0
* begin
* var x = value; // Name in Scope Level 0
* // Scope Level 1
* begin
* var x = value; // Name in Scope Level 1 <-- REDEFENITION ERROR, x defined at Level 0
*
* var y = value;
* var y = value2; // Name in Scope Level 1 <-- REDEFINITION ERROR, y defined at Level 1
*
* // Scope Level 2
* begin
* var z = y; // Name in Scope Level 2
* end
* // Scope Level 2
* begin
* var z = value; // Name in Scope Level 2
* end
* end
*
* end
*/
public override void visit(statement_list stlist)
{
++CurrentLevel;
if (BlockNamesStack.Count <= CurrentLevel)
{
// Создаем множество имен для текущего уровня вложенности мини-пространства имен
BlockNamesStack.Add(new HashSet<string>());
}
base.visit(stlist);
//for (var i = 0; i < stlist.list.Count; ++i)
// ProcessNode(stlist.list[i]);
BlockNamesStack.RemoveAt(BlockNamesStack.Count - 1);
--CurrentLevel;
}
public override void visit(var_statement vs)
{
foreach (var id in vs.var_def.vars.idents)
{
// Проверяем есть ли такое имя выше?
CheckVariableAlreadyDefined(id);
BlockNamesStack[CurrentLevel].Add(id.name);
}
base.visit(vs);
}
public override void visit(for_node fn)
{
if (fn.create_loop_variable)
{
CheckVariableAlreadyDefined(fn.loop_variable);
}
base.visit(fn);
}
private bool IsVariableAlreadyDefined(string name)
{
if (UpperBlockNames.Contains(name))
return true;
for (int i = 0; i <= CurrentLevel; ++i)
{
if (BlockNamesStack[i].Contains(name))
return true;
}
return false;
}
private void CheckVariableAlreadyDefined(ident id)
{
string name = id.name;
if (IsVariableAlreadyDefined(name))
{
throw new PascalABCCompiler.Errors.SyntaxError(string.Format("Var {0} is already defined", name), "", id.source_context, id);
}
}
}
}

View file

@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
namespace SyntaxVisitors
{
public class CollectClassFieldsVisitor : CollectUpperNodesVisitor
{
private ident _className;
public ISet<ident> CollectedFields { get; private set; }
public CollectClassFieldsVisitor(ident className)
{
CollectedFields = new HashSet<ident>();
_className = className;
}
public override void visit(class_definition cd)
{
type_declaration td = UpperNode(1) as type_declaration;
if ((object)td == null)
{
// Something went wrong
return;
}
if (td.type_name.name != _className.name)
{
// Not the class we search for
// Yoda
return;
}
var fields = cd.body.class_def_blocks.SelectMany(cm => cm.members.Where(decl => decl is var_def_statement)
.Select(decl1 => (decl1 as var_def_statement).vars.idents)
.SelectMany(ids => ids.Select(id => id)));
CollectedFields.UnionWith(fields);
/*foreach (var defs in cd.body.class_def_blocks)
{
// Class members
foreach (var decl in defs.members)
{
// Declaration: fields + procedure defs + headers + etc
// Need vars
if (decl is var_def_statement)
{
var vars = (decl as var_def_statement).vars;
// Fields
foreach (var field in vars.idents)
{
CollectedFields.Add(field);
}
}
}
}*/
}
}
}

View file

@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
namespace SyntaxVisitors
{
public class CollectClassMethodsVisitor : CollectUpperNodesVisitor
{
private ident _className;
public ISet<ident> CollectedMethods { get; private set; }
public CollectClassMethodsVisitor(ident className)
{
CollectedMethods = new HashSet<ident>();
_className = className;
}
public override void visit(class_definition cd)
{
type_declaration td = UpperNode(1) as type_declaration;
if ((object)td == null)
{
// Something went wrong
return;
}
if (td.type_name.name != _className.name)
{
// Not the class we search for
// Yoda
return;
}
var methods = cd.body.class_def_blocks.SelectMany(cm => cm.members.Select(decl1 =>
{
if (decl1 is procedure_header)
return (decl1 as procedure_header).name.meth_name;
else if (decl1 is procedure_definition)
return (decl1 as procedure_definition).proc_header.name.meth_name;
return null;
}).Where(name => (object)name != null));
CollectedMethods.UnionWith(methods);
}
}
}

View file

@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
namespace SyntaxVisitors
{
public class CollectClassPropertiesVisitor : CollectUpperNodesVisitor
{
private ident _className;
public ISet<ident> CollectedProperties { get; private set; }
public CollectClassPropertiesVisitor(ident className)
{
CollectedProperties = new HashSet<ident>();
_className = className;
}
public override void visit(class_definition cd)
{
type_declaration td = UpperNode(1) as type_declaration;
if ((object)td == null)
{
// Something went wrong
return;
}
if (td.type_name.name != _className.name)
{
// Not the class we search for
// Yoda
return;
}
var properties = cd.body.class_def_blocks.SelectMany(cm => cm.members.Select(decl => decl as simple_property)
.Where(name => (object)name != null)
.Select(sp => sp.property_name));
CollectedProperties.UnionWith(properties);
}
}
}

View file

@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
namespace SyntaxVisitors
{
public class CollectUnitGlobalsVisitor : CollectUpperNodesVisitor
{
public ISet<ident> CollectedGlobals { get; private set; }
public CollectUnitGlobalsVisitor()
{
CollectedGlobals = new HashSet<ident>();
}
/*public override void visit(interface_node node)
{
var globals = node.interface_definitions.defs
.Select(def => def as variable_definitions)
.Where(varDefsObj => (object)varDefsObj != null)
.SelectMany(varDefs => varDefs.var_definitions)
.SelectMany(v => v.vars.idents);
CollectedGlobals.UnionWith(globals);
}*/
public override void visit(declarations node)
{
var globals = node.defs
.Select(def => def as variable_definitions)
.Where(varDefsObj => (object)varDefsObj != null)
.SelectMany(varDefs => varDefs.var_definitions)
.SelectMany(v => v.vars.idents);
CollectedGlobals.UnionWith(globals);
}
}
}

View file

@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
namespace SyntaxVisitors
{
public class DeleteAllLocalDefs : BaseChangeVisitor
{
private List<var_def_statement> LocalDeletedVD = new List<var_def_statement>(); // все локальные описания
private List<var_def_statement> LocalDeletedVS = new List<var_def_statement>(); // var_statement's, потом объединим с LocalDeletedVD для верного порядка
public ISet<string> LocalDeletedDefsNames = new HashSet<string>(); // их имена - для быстрого поиска
public ISet<ident> CollectedLocals = new HashSet<ident>();
public IEnumerable<var_def_statement> LocalDeletedDefs
{
get
{
return new List<var_def_statement>(LocalDeletedVD.Union(LocalDeletedVS));
}
}
public DeleteAllLocalDefs() // надо запускать этот визитор начиная с корня подпрограммы
{
}
public override void visit(var_statement vs) // локальные описания внутри процедуры
{
LocalDeletedVS.Insert(0, vs.var_def);
//DeleteInStatementList(vs);
// frninja 02/03/16 - fix capturing unknown idents -> replace delete with assign
if ((object)vs.var_def.inital_value == null)
{
DeleteInStatementList(vs);
}
else
{
ReplaceStatement(vs, SeqStatements(vs.var_def.vars.idents.Select(id => new assign(id, vs.var_def.inital_value)).ToArray()));
}
LocalDeletedDefsNames.UnionWith(vs.var_def.vars.idents.Select(id => id.name));
CollectedLocals.UnionWith(vs.var_def.vars.idents);
}
public override void visit(variable_definitions vd)
{
foreach (var v in vd.list)
{
LocalDeletedVD.Insert(0, v); //.Add(v);
LocalDeletedDefsNames.UnionWith(v.vars.idents.Select(id => id.name));
}
var d = UpperNodeAs<declarations>();
d.defs.Remove(vd); // может ли остаться список declarations пустым?
// frninja 03/03/16 - переносим объявления переменных c initial_value в тело метода для дальнейшей обработки
var methodBody = UpperTo<block>().program_code;
methodBody.list.InsertRange(0, vd.list
.Where(vds => (object)vds.inital_value != null)
.SelectMany(vdsInit => vdsInit.vars.list.Select(id => new assign(id, vdsInit.inital_value))));
// еще - не заходить в лямбды
}
}
}

View file

@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
namespace SyntaxVisitors
{
public class DeleteLocalDefs : BaseChangeVisitor
{
public List<var_def_statement> LocalDeletedIds = new List<var_def_statement>();
public List<var_def_statement> BlockDeletedIds = new List<var_def_statement>();
public HashSet<string> idsToDelete;
public HashSet<string> deletedIdsToDeleteInLocalScope = new HashSet<string>(); // одно множество и на Local и на Block
public DeleteLocalDefs(HashSet<string> ids) // надо запускать этот визитор начиная с корня подпрограммы
{
idsToDelete = ids;
}
public override void visit(var_statement vs)
{
var idents = vs.var_def.vars.idents;
var IdentsToDeleteInVarDef = idents.FindAll(id => idsToDelete.Contains(id.name)); // найти в операторе все идентификаторы для удаления
if (IdentsToDeleteInVarDef.Count != 0)
{
deletedIdsToDeleteInLocalScope.UnionWith(IdentsToDeleteInVarDef.Select(id => id.name)); // добавить те идентификаторы, которые мы удаляем из данного описания
LocalDeletedIds.Add(new var_def_statement(new ident_list(IdentsToDeleteInVarDef), vs.var_def.vars_type, vs.var_def.inital_value)); // добавить описание из удаленных в данном разделе описаний идентификаторов
idents.RemoveAll(id => idsToDelete.Contains(id.name)); // удалить в операторе все идентификаторы для удаления
idsToDelete.ExceptWith(deletedIdsToDeleteInLocalScope);
if (idents.Count == 0) // то и весь var_statement надо убить
this.DeleteInStatementList(vs);
}
// Здесь мы не обрабатываем вложенный var_def_statement, поэтому когда мы будем обрабатывать его в другом visit, то это будут переменные до beginа подпрограммы или основной программы
}
public override void visit(var_def_statement vd)
{
var idents = vd.vars.idents;
var IdentsToDeleteInVarDef = idents.FindAll(id => idsToDelete.Contains(id.name)); // найти в операторе все идентификаторы для удаления
if (IdentsToDeleteInVarDef.Count != 0)
{
deletedIdsToDeleteInLocalScope.UnionWith(IdentsToDeleteInVarDef.Select(id => id.name)); // добавить те идентификаторы, которые мы удаляем из данного описания
BlockDeletedIds.Add(new var_def_statement(new ident_list(IdentsToDeleteInVarDef), vd.vars_type, vd.inital_value)); // добавить описание из удаленных в данном разделе описаний идентификаторов
idents.RemoveAll(id => idsToDelete.Contains(id.name)); // удалить в операторе все идентификаторы для удаления
if (idents.Count == 0)
{
// Выше - variable_definitions, еще выше - declarations
var uvdsl = UpperNodeAs<variable_definitions>();
uvdsl.var_definitions.Remove(vd);
if (uvdsl.var_definitions.Count == 0)
{
var d = UpperNodeAs<declarations>(2);
d.defs.Remove(uvdsl);
}
}
}
}
public void AfterProcTraverse()
{
idsToDelete.ExceptWith(deletedIdsToDeleteInLocalScope); // исключаем из множества удаляемых идентификаторов те, которые мы нашли и удалили в секции var_statement. Это надо делать не для каждого описания, а в конце подпрограммы после удаления из всех секций var_statement
}
}
}

View file

@ -0,0 +1,148 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
namespace SyntaxVisitors
{
public class JustTestVisitor : BaseChangeVisitor
{
private void CollectFormalParams(procedure_definition pd, ISet<var_def_statement> collectedFormalParams)
{
if ((object)pd.proc_header.parameters != null)
collectedFormalParams.UnionWith(pd.proc_header.parameters.params_list.Select(tp => new var_def_statement(tp.idents, tp.vars_type)));
}
private void CollectFormalParamsNames(procedure_definition pd, ISet<string> collectedFormalParamsNames)
{
if ((object)pd.proc_header.parameters != null)
collectedFormalParamsNames.UnionWith(pd.proc_header.parameters.params_list.SelectMany(tp => tp.idents.idents).Select(id => id.name));
}
private void CollectClassFieldsNames(procedure_definition pd, ISet<string> collectedFields, out bool isInClassMethod)
{
isInClassMethod = false;
ident className = null;
if ((object)pd.proc_header.name.class_name != null)
{
// Объявление вне класса его метода
className = pd.proc_header.name.class_name;
}
else
{
// Объявление функции в классе?
var classDef = UpperNode(3) as class_definition;
if ((object)(UpperNode(3) as class_definition) != null)
{
var td = UpperNode(4) as type_declaration;
if ((object)td != null)
{
className = td.type_name;
}
}
}
if ((object)className != null)
{
isInClassMethod = true;
CollectClassFieldsVisitor fieldsVis = new CollectClassFieldsVisitor(className);
var cu = UpperTo<compilation_unit>();
if ((object)cu != null)
{
cu.visit(fieldsVis);
// Collect
collectedFields.UnionWith(fieldsVis.CollectedFields.Select(id => id.name));
}
}
}
private void CollectUnitGlobalsNames(procedure_definition pd, ISet<string> collectedUnitGlobalsName)
{
var cu = UpperTo<compilation_unit>();
if ((object)cu != null)
{
var ugVis = new CollectUnitGlobalsVisitor();
cu.visit(ugVis);
// Collect
collectedUnitGlobalsName.UnionWith(ugVis.CollectedGlobals.Select(id => id.name));
}
}
private void CreateCapturedLocalsNamesMap(ISet<string> localsNames, IDictionary<string, string> capturedLocalsNamesMap)
{
foreach (var localName in localsNames)
{
capturedLocalsNamesMap.Add(localName, CapturedNamesHelper.MakeCapturedLocalName(localName));
}
}
private void CreateCapturedFormalParamsNamesMap(ISet<string> formalParamsNames, IDictionary<string, string> captueedFormalParamsNamesMap)
{
foreach (var formalParamName in formalParamsNames)
{
captueedFormalParamsNamesMap.Add(formalParamName, CapturedNamesHelper.MakeCapturedFormalParameterName(formalParamName));
}
}
public override void visit(procedure_definition pd)
{
// frninja
// Classification
ISet<string> CollectedLocalsNames = new HashSet<string>();
ISet<string> CollectedFormalParamsNames = new HashSet<string>();
ISet<string> CollectedClassFieldsNames = new HashSet<string>();
ISet<string> CollectedUnitGlobalsNames = new HashSet<string>();
ISet<var_def_statement> CollectedLocals = new HashSet<var_def_statement>();
ISet<var_def_statement> CollectedFormalParams = new HashSet<var_def_statement>();
// Map from ident idName -> captured ident idName
IDictionary<string, string> CapturedLocalsNamesMap = new Dictionary<string, string>();
IDictionary<string, string> CapturedFormalParamsNamesMap = new Dictionary<string, string>();
var dld = new DeleteAllLocalDefs(); // mids.vars - все захваченные переменные
pd.visit(dld); // Удалить в локальных и блочных описаниях этой процедуры все переменные и вынести их в отдельный список var_def_statement
// frninja 08/12/15
bool isInClassMethod;
// Collect locals
CollectedLocals.UnionWith(dld.LocalDeletedDefs);
CollectedLocalsNames.UnionWith(dld.LocalDeletedDefs.SelectMany(vds => vds.vars.idents).Select(id => id.name));
// Collect formal params
CollectFormalParams(pd, CollectedFormalParams);
CollectFormalParamsNames(pd, CollectedFormalParamsNames);
// Collect class fields
CollectClassFieldsNames(pd, CollectedClassFieldsNames, out isInClassMethod);
// Collect unit globals
CollectUnitGlobalsNames(pd, CollectedUnitGlobalsNames);
// Create maps :: idName -> captureName
CreateCapturedLocalsNamesMap(CollectedLocalsNames, CapturedLocalsNamesMap);
CreateCapturedFormalParamsNamesMap(CollectedFormalParamsNames, CapturedFormalParamsNamesMap);
// AHAHA test!
ReplaceCapturedVariablesVisitor rcapVis = new ReplaceCapturedVariablesVisitor(
CollectedLocalsNames,
CollectedFormalParamsNames,
CollectedClassFieldsNames,
new HashSet<string>(),
new HashSet<string>(),
CollectedUnitGlobalsNames,
CapturedLocalsNamesMap,
CapturedFormalParamsNamesMap,
isInClassMethod
);
// Replace
(pd.proc_body as block).program_code.visit(rcapVis);
}
}
}

View file

@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
namespace SyntaxVisitors
{
public class LocalVariablesTypeDetectorHelperVisior : BaseChangeVisitor
{
public List<var_def_statement> LocalDeletedDefs = new List<var_def_statement>(); // все локальные описания
public List<var_def_statement> LocalDeletedVS = new List<var_def_statement>(); // var_statement's, потом объединим с LocalDeletedVD для верного порядка
public yield_locals_type_map_helper VarTypeMap { get; private set; }
public LocalVariablesTypeDetectorHelperVisior(yield_locals_type_map_helper varTypeMap)
{
this.VarTypeMap = varTypeMap;
}
public override void visit(yield_variable_definitions_with_unknown_type yvds)
{
// Empty
}
public override void visit(var_statement vs) // локальные описания внутри процедуры
{
LocalDeletedVS.Insert(0, vs.var_def);
ReplaceStatement(vs, new yield_var_def_statement_with_unknown_type(vs.var_def, this.VarTypeMap));
}
public override void visit(variable_definitions vd)
{
foreach (var v in vd.list)
{
LocalDeletedDefs.Insert(0, v);
}
Replace(vd, new yield_variable_definitions_with_unknown_type(vd, VarTypeMap));
// еще - не заходить в лямбды
}
}
}

View file

@ -0,0 +1,204 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PascalABCCompiler.Errors;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
namespace SyntaxVisitors
{
public class VarNames
{
public string VarName { get; set; }
public string VarEndName { get; set; }
public VarNames()
{
}
public VarNames(string varName, string varEndName)
{
VarName = varName;
VarEndName = varEndName;
}
}
public class LoweringVisitor : BaseChangeVisitor
{
public static LoweringVisitor New
{
get { return new LoweringVisitor(); }
}
private int _varnum = 0;
private string newVarName()
{
_varnum++;
return "<>varLV" + _varnum.ToString();
}
private VarNames NewVarNames(ident name)
{
_varnum++;
return new VarNames()
{
VarName = "$" + name.name + _varnum,
VarEndName = "<>varLV" + _varnum
};
}
public static void Accept(procedure_definition pd)
{
New.ProcessNode(pd);
}
public override void Enter(syntax_tree_node st)
{
base.Enter(st);
if (!(st is procedure_definition || st is block || st is statement_list || st is case_node || st is for_node || st is foreach_stmt || st is if_node || st is repeat_node || st is while_node || st is with_statement || st is try_stmt || st is lock_stmt))
{
//visitNode = false;
}
}
public override void visit(if_node ifn)
{
ProcessNode(ifn.then_body);
ProcessNode(ifn.else_body);
var b = HasStatementVisitor<yield_node>.Has(ifn);
if (!b)
return;
var gtAfter = goto_statement.New;
var lbAfter = new labeled_statement(gtAfter.label);
if ((object)ifn.else_body == null)
{
var if0 = new if_node(un_expr.Not(ifn.condition), gtAfter);
//Replace(ifn, SeqStatements(if0, ifn.then_body, lbAfter));
ReplaceStatement(ifn, SeqStatements(if0, ifn.then_body, lbAfter));
// в declarations ближайшего блока добавить описание labels
block bl = listNodes.FindLast(x => x is block) as block;
bl.defs.Add(new label_definitions(gtAfter.label));
}
else
{
var gtAlt = goto_statement.New;
var lbAlt = new labeled_statement(gtAlt.label, ifn.else_body);
var if0 = new if_node(un_expr.Not(ifn.condition), gtAlt);
ReplaceStatement(ifn, SeqStatements(if0, ifn.then_body, gtAfter, lbAlt, lbAfter));
// в declarations ближайшего блока добавить описание labels
block bl = listNodes.FindLast(x => x is block) as block;
bl.defs.Add(new label_definitions(gtAfter.label, gtAlt.label));
}
}
public override void visit(repeat_node rn)
{
ProcessNode(rn.statements);
var b = HasStatementVisitor<yield_node>.Has(rn);
if (!b)
return;
var gtContinue = goto_statement.New;
var gtBreak = goto_statement.New;
var lbContinue = new labeled_statement(gtContinue.label, rn.statements);
var lbBreak = new labeled_statement(gtBreak.label);
var if0 = new if_node(un_expr.Not(rn.expr), gtContinue);
ReplaceStatement(rn, SeqStatements(lbContinue, if0, lbBreak));
// в declarations ближайшего блока добавить описание labels
block bl = listNodes.FindLast(x => x is block) as block;
bl.defs.Add(new label_definitions(gtContinue.label, gtBreak.label));
}
public override void visit(while_node wn)
{
ProcessNode(wn.statements);
var b = HasStatementVisitor<yield_node>.Has(wn);
if (!b)
return;
var gt1 = goto_statement.New;
var gt2 = goto_statement.New;
var if0 = new if_node(un_expr.Not(wn.expr), gt1);
var lb2 = new labeled_statement(gt2.label, if0); // continue
var lb1 = new labeled_statement(gt1.label); // break
ReplaceStatement(wn, SeqStatements(lb2, wn.statements, gt2, lb1));
// в declarations ближайшего блока добавить описание labels
block bl = listNodes.FindLast(x => x is block) as block;
bl.defs.Add(new label_definitions(gt1.label, gt2.label));
}
public override void visit(for_node fn)
{
ProcessNode(fn.statements);
var b = HasStatementVisitor<yield_node>.Has(fn);
if (!b)
return;
var gt1 = goto_statement.New;
var gt2 = goto_statement.New;
var newNames = this.NewVarNames(fn.loop_variable);
var newLoopVar = fn.create_loop_variable ? new ident(newNames.VarName) : fn.loop_variable;
// Нужно заменить fn.loop_variable -> newLoopVar в теле цикла
var replacerVis = new ReplaceForVariableVisitor(fn.loop_variable, newLoopVar);
fn.visit(replacerVis);
fn.loop_variable = newLoopVar;
var endtemp = new ident(newNames.VarEndName); //new ident(newVarName());
//var ass1 = new var_statement(fn.loop_variable, fn.type_name, fn.initial_value);
var ass1 = new var_statement(fn.loop_variable, fn.type_name, fn.initial_value);
//var ass2 = new var_statement(endtemp, fn.type_name, fn.finish_value);
var if0 = new if_node((fn.cycle_type == for_cycle_type.to) ?
bin_expr.Greater(fn.loop_variable, fn.finish_value) :
bin_expr.Less(fn.loop_variable, fn.finish_value), gt1);
var lb2 = new labeled_statement(gt2.label, if0);
var lb1 = new labeled_statement(gt1.label);
var Inc = new procedure_call(new method_call((fn.cycle_type == for_cycle_type.to) ?
new ident("Inc") :
new ident("Dec"), new expression_list(fn.loop_variable)));
ReplaceStatement(fn, SeqStatements(ass1, /*ass2,*/ lb2, fn.statements, Inc, gt2, lb1));
// в declarations ближайшего блока добавить описание labels
block bl = listNodes.FindLast(x => x is block) as block;
bl.defs.Add(new label_definitions(gt1.label, gt2.label));
}
}
}

View file

@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
using PascalABCCompiler.Errors;
namespace SyntaxVisitors
{
public class MarkMethodHasYieldVisitor : WalkingVisitorNew
{
private bool HasYields = false;
private procedure_definition CurrentMethod = null;
public override void visit(procedure_definition pd)
{
this.CurrentMethod = pd;
base.visit(pd);
pd.has_yield = HasYields;
this.CurrentMethod = null;
}
public override void visit(yield_node yn)
{
var pd = CurrentMethod;
var fh = (pd.proc_header as function_header);
if (fh == null)
throw new SyntaxError("Only functions can contain yields", "", pd.proc_header.source_context, pd.proc_header);
var seqt = fh.return_type as sequence_type;
if (seqt == null)
throw new SyntaxError("Functions with yields must return sequences", "", fh.return_type.source_context, fh.return_type);
var pars = fh.parameters;
if (pars != null)
foreach (var ps in pars.params_list)
{
if (ps.param_kind != parametr_kind.none)
throw new SyntaxError("Parameters of functions with yields must not have 'var', 'const' or 'params' modifier", "", pars.source_context, pars);
if (ps.inital_value != null)
throw new SyntaxError("Parameters of functions with yields must not have initial values", "", pars.source_context, pars);
}
HasYields = true;
}
}
}

View file

@ -0,0 +1,884 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
using PascalABCCompiler.ParserTools;
using PascalABCCompiler.Errors;
using PascalABCCompiler.YieldHelpers;
namespace SyntaxVisitors
{
public static class CapturedNamesHelper
{
public static int CurrentLocalVariableNum = 0;
public static string MakeCapturedFormalParameterName(string formalParamName)
{
return string.Format("<>{0}__{1}", YieldConsts.ReservedNum.MethodFormalParam, formalParamName);
}
public static string MakeCapturedLocalName(string localName)
{
return string.Format("<{0}>{1}__{2}", localName, YieldConsts.ReservedNum.MethodLocalVariable, ++CurrentLocalVariableNum);
}
}
public class ProcessYieldCapturedVarsVisitor : BaseChangeVisitor
{
int clnum = 0;
public string NewYieldClassName()
{
clnum++;
return "clyield#" + clnum.ToString();
}
public FindMainIdentsVisitor mids; // захваченные переменные процедуры по всем её yield
public int countNodesVisited;
public bool hasYields = false;
public static ProcessYieldCapturedVarsVisitor New
{
get { return new ProcessYieldCapturedVarsVisitor(); }
}
public ProcessYieldCapturedVarsVisitor()
{
//PrintInfo = false;
}
public override void Enter(syntax_tree_node st)
{
base.Enter(st);
countNodesVisited++;
// сокращение обходимых узлов. Как сделать фильтр по тем узлам, которые необходимо обходить? Например, все операторы (без выражений и описаний), все описания (без операторов)
if (st is assign || st is var_def_statement || st is procedure_call || st is procedure_header || st is expression)
{
visitNode = false; // фильтр - куда не заходить
}
}
/*public override void visit(class_members cm)
{
foreach (var decl in cm.members)
{
if (decl is procedure_header || decl is procedure_definition)
decl.visit(this);
}
base.visit(cm);
}*/
type_declarations GenClassesForYield(procedure_definition pd,
IEnumerable<var_def_statement> fields, // локальные переменные
IDictionary<string, string> localsMap, // отображение для захваченных имен локальных переменных
IDictionary<string, string> formalParamsMap, // отображение для захваченных имен формальных параметров
IDictionary<var_def_statement, var_def_statement> localsCloneMap, // отображение для оберток локальных переменных
yield_locals_type_map_helper localTypeMapHelper) // вспомогательный узел для типов локальных переменных
{
var fh = (pd.proc_header as function_header);
if (fh == null)
throw new SyntaxError("Only functions can contain yields", "", pd.proc_header.source_context, pd.proc_header);
var seqt = fh.return_type as sequence_type;
if (seqt == null)
throw new SyntaxError("Functions with yields must return sequences", "", fh.return_type.source_context, fh.return_type);
// Теперь на месте функции генерируем класс
// Захваченные локальные переменные
var cm = class_members.Public;
var capturedFields = fields.Select(vds =>
{
ident_list ids = new ident_list(vds.vars.idents.Select(id => new ident(localsMap[id.name])).ToArray());
if (vds.vars_type == null) //&& vds.inital_value != null)
{
if (vds.inital_value != null)
{
//return new var_def_statement(ids, new yield_unknown_expression_type(localsCloneMap[vds], varsTypeDetectorHelper), null);
return new var_def_statement(ids, new yield_unknown_expression_type(localsCloneMap[vds], localTypeMapHelper), null);
}
else
{
throw new Exception("Variable defenition without type and value!");
}
}
else
{
return new var_def_statement(ids, vds.vars_type, null);
}
//return new var_def_statement(ids, vds.vars_type, vds.inital_value);
});
foreach (var m in capturedFields)
cm.Add(m);
// Параметры функции
List<ident> lid = new List<ident>();
var pars = fh.parameters;
if (pars != null)
foreach (var ps in pars.params_list)
{
if (ps.param_kind != parametr_kind.none)
throw new SyntaxError("Parameters of functions with yields must not have 'var', 'const' or 'params' modifier", "", pars.source_context, pars);
if (ps.inital_value != null)
throw new SyntaxError("Parameters of functions with yields must not have initial values", "", pars.source_context, pars);
//var_def_statement vds = new var_def_statement(ps.idents, ps.vars_type);
ident_list ids = new ident_list(ps.idents.list.Select(id => new ident(formalParamsMap[id.name])).ToArray());
var_def_statement vds = new var_def_statement(ids, ps.vars_type);
cm.Add(vds); // все параметры функции делаем полями класса
//lid.AddRange(vds.vars.idents);
lid.AddRange(ps.idents.list);
}
var stels = seqt.elements_type;
var iteratorClassName = GetClassName(pd);
// frninja 08/18/15 - Для захвата self
if (iteratorClassName != null)
{
// frninja 20/04/16 - поддержка шаблонных классов
var iteratorClassRef = CreateClassReference(iteratorClassName);
cm.Add(new var_def_statement(YieldConsts.Self, iteratorClassRef));
}
// Системные поля и методы для реализации интерфейса IEnumerable
cm.Add(new var_def_statement(YieldConsts.State, "integer"),
new var_def_statement(YieldConsts.Current, stels),
procedure_definition.EmptyDefaultConstructor,
new procedure_definition("Reset"),
new procedure_definition("MoveNext", "boolean", pd.proc_body),
new procedure_definition("System.Collections.IEnumerator.get_Current", "object", new assign("Result", YieldConsts.Current)),
new procedure_definition("System.Collections.IEnumerable.GetEnumerator", "System.Collections.IEnumerator", new assign("Result", "Self"))
);
// frninja 20/04/16 - поддержка шаблонных классов
var yieldClassName = NewYieldClassName();
var yieldClassHelperName = yieldClassName + "Helper";
var className = this.CreateHelperClassName(yieldClassName, iteratorClassName, pd);
var classNameHelper = this.CreateHelperClassName(yieldClassHelperName, iteratorClassName, pd);
var interfaces = new named_type_reference_list("System.Collections.IEnumerator", "System.Collections.IEnumerable");
// frninja 24/04/16 - поддержка шаблонных классов
//var td = new type_declaration(classNameHelper, this.CreateHelperClassDefinition(classNameHelper, pd, interfaces, cm));
//SyntaxTreeBuilder.BuildClassDefinition(interfaces, cm));
// Изменение тела процедуры
// frninja 20/04/16 - поддержка шаблонных классов
var stl = new statement_list(new var_statement("res", new new_expr(this.CreateClassReference(className), new expression_list())));
//stl.AddMany(lid.Select(id => new assign(new dot_node("res", id), id)));
stl.AddMany(lid.Select(id => new assign(new dot_node("res", new ident(formalParamsMap[id.name])), id)));
// frninja 08/12/15 - захват self
if (iteratorClassName != null)
{
stl.Add(new assign(new dot_node("res", YieldConsts.Self), new ident("self")));
}
stl.Add(new assign("Result", "res"));
// New body
pd.proc_body = new block(stl);
if (iteratorClassName != null)
{
var cd = UpperTo<class_definition>();
if (cd != null)
{
// Если метод описан в классе
// frninja 10/12/15 - заменить на function_header и перенести описание тела в declarations
Replace(pd, fh);
var decls = UpperTo<declarations>();
if (decls != null)
{
// frninja 12/05/16 - забыли копировать return
function_header nfh = ObjectCopier.Clone(fh);
//function_header nfh = new function_header();
//nfh.name = new method_name(fh.name.meth_name.name);
// Set className
nfh.name.class_name = iteratorClassName;
//nfh.parameters = fh.parameters;
//nfh.proc_attributes = fh.proc_attributes;
//nfh.return_type = fh.return_type;
procedure_definition npd = new procedure_definition(nfh, new block(stl));
// Update header
//pd.proc_header.className.class_name = GetClassName(pd);
// Add to decls
decls.Add(npd);
}
}
}
// Второй класс
var tpl = new template_param_list(stels);
var IEnumeratorT = new template_type_reference("System.Collections.Generic.IEnumerator", tpl);
var cm1 = cm.Add( //class_members.Public.Add(
//procedure_definition.EmptyDefaultConstructor,
new procedure_definition(new function_header("get_Current", stels), new assign("Result", YieldConsts.Current)),
new procedure_definition(new function_header("GetEnumerator", IEnumeratorT), new assign("Result", "Self")),
new procedure_definition("Dispose")
);
// frninja 20/04/16 - поддержка шаблонных классов
var interfaces1 = new named_type_reference_list(/*this.CreateClassReference(classNameHelper) as named_type_reference*/);
var IEnumerableT = new template_type_reference("System.Collections.Generic.IEnumerable", tpl);
interfaces1.Add(IEnumerableT).Add(IEnumeratorT);
// frninja 24/04/16 - поддержка шаблонных классов
var td1 = new type_declaration(className, this.CreateHelperClassDefinition(className, pd, interfaces1, cm1));
//SyntaxTreeBuilder.BuildClassDefinition(interfaces1, cm1));
var cct = new type_declarations(/*td*/);
cct.Add(td1);
return cct;
}
private void CollectFormalParams(procedure_definition pd, ISet<var_def_statement> collectedFormalParams)
{
if (pd.proc_header.parameters != null)
collectedFormalParams.UnionWith(pd.proc_header.parameters.params_list.Select(tp => new var_def_statement(tp.idents, tp.vars_type)));
}
private void CollectFormalParamsNames(procedure_definition pd, ISet<string> collectedFormalParamsNames)
{
if (pd.proc_header.parameters != null)
collectedFormalParamsNames.UnionWith(pd.proc_header.parameters.params_list.SelectMany(tp => tp.idents.idents).Select(id => id.name));
}
/// <summary>
/// Создает обращение к имени класса по имени класса
/// </summary>
/// <param name="className">Имя класса</param>
/// <returns></returns>
private type_definition CreateClassReference(ident className)
{
if (className is template_type_name)
{
return new template_type_reference(
new named_type_reference(className),
new template_param_list(string.Join(",", (className as template_type_name).template_args.idents.Select(id => id.name)))
);
}
return new named_type_reference(className);
}
/// <summary>
/// Создает имя вспомогательного класса
/// </summary>
/// <param name="helperName">Имя вспомогательного класса</param>
/// <param name="className">Имя класса</param>
/// <returns></returns>
private ident CreateHelperClassName(string helperName, ident className, procedure_definition pd)
{
if (className is template_type_name)
{
return new template_type_name(helperName, (className as template_type_name).template_args);
}
else if (pd.proc_header.template_args != null)
{
return new template_type_name(helperName, pd.proc_header.template_args);
}
return new ident(helperName);
}
private class_definition CreateHelperClassDefinition(ident className, procedure_definition pd, named_type_reference_list parents, params class_members[] cms)
{
if (className is template_type_name)
{
return SyntaxTreeBuilder.BuildClassDefinition(parents, (className as template_type_name).template_args , cms);
}
else if (pd.proc_header.template_args != null)
{
return SyntaxTreeBuilder.BuildClassDefinition(parents, pd.proc_header.template_args, cms);
}
return SyntaxTreeBuilder.BuildClassDefinition(parents, cms);
}
/// <summary>
/// Получает имя класса, в котором описан метод-итератор
/// </summary>
/// <param name="pd"></param>
/// <returns></returns>
private ident GetClassName(procedure_definition pd)
{
if (pd.proc_header.name.class_name != null)
{
// Объявление вне класса его метода
return pd.proc_header.name.class_name;
}
else
{
// Объявление функции в классе?
var classDef = UpperNode(3) as class_definition;
if ((UpperNode(3) as class_definition) != null)
{
var td = UpperNode(4) as type_declaration;
if (td != null)
{
return td.type_name;
}
}
}
return null;
}
/// <summary>
/// Определяет описан ли метод-итератор в некотором классе
/// </summary>
/// <param name="pd"></param>
/// <returns></returns>
private bool IsClassMethod(procedure_definition pd)
{
return GetClassName(pd) != null;
}
private void CollectClassFieldsNames(procedure_definition pd, ISet<string> collectedFields)
{
ident className = GetClassName(pd);
if (className != null)
{
CollectClassFieldsVisitor fieldsVis = new CollectClassFieldsVisitor(className);
var cu = UpperTo<compilation_unit>();
if (cu != null)
{
cu.visit(fieldsVis);
// Collect
collectedFields.UnionWith(fieldsVis.CollectedFields.Select(id => id.name));
}
}
}
private void CollectClassMethodsNames(procedure_definition pd, ISet<string> collectedMethods)
{
ident className = GetClassName(pd);
if (className != null)
{
CollectClassMethodsVisitor methodsVis = new CollectClassMethodsVisitor(className);
var cu = UpperTo<compilation_unit>();
if (cu != null)
{
cu.visit(methodsVis);
// Collect
collectedMethods.UnionWith(methodsVis.CollectedMethods.Select(id => id.name));
}
}
}
private void CollectClassPropertiesNames(procedure_definition pd, ISet<string> collectedProperties)
{
ident className = GetClassName(pd);
if (className != null)
{
CollectClassPropertiesVisitor propertiesVis = new CollectClassPropertiesVisitor(className);
var cu = UpperTo<compilation_unit>();
if (cu != null)
{
cu.visit(propertiesVis);
// Collect
collectedProperties.UnionWith(propertiesVis.CollectedProperties.Select(id => id.name));
}
}
}
private void CollectUnitGlobalsNames(procedure_definition pd, ISet<string> collectedUnitGlobalsName)
{
var cu = UpperTo<compilation_unit>();
if (cu != null)
{
var ugVis = new CollectUnitGlobalsVisitor();
cu.visit(ugVis);
// Collect
collectedUnitGlobalsName.UnionWith(ugVis.CollectedGlobals.Select(id => id.name));
}
}
private void CreateCapturedLocalsNamesMap(ISet<string> localsNames, IDictionary<string, string> capturedLocalsNamesMap)
{
foreach (var localName in localsNames)
{
capturedLocalsNamesMap.Add(localName, CapturedNamesHelper.MakeCapturedLocalName(localName));
}
}
private void CreateCapturedFormalParamsNamesMap(ISet<string> formalParamsNames, IDictionary<string, string> captueedFormalParamsNamesMap)
{
foreach (var formalParamName in formalParamsNames)
{
captueedFormalParamsNamesMap.Add(formalParamName, CapturedNamesHelper.MakeCapturedFormalParameterName(formalParamName));
}
}
/// <summary>
/// Обработка локальных переменных метода и их типов для корректного захвата
/// </summary>
/// <param className="pd">Объявление метода</param>
/// <returns>Коллекция посещенных локальных переменных</returns>
private void CreateLocalVariablesTypeProxies(procedure_definition pd, out IEnumerable<var_def_statement> localsClonesCollection, out yield_locals_type_map_helper localsTypeMapHelper)
{
// Выполняем определение типов локальных переменных с автовыводом типов
// Клонируем исходный метод для вставки оберток-хелперов для локальных переменных и дальнейшей обработки на семантике
var pdCloned = ObjectCopier.Clone(pd);
pdCloned.has_yield = false;
// Заменяем локальные переменные с неизвестным типом на обертки-хелперы (откладываем до семантики)
localsTypeMapHelper = new yield_locals_type_map_helper();
LocalVariablesTypeDetectorHelperVisior localsTypeDetectorHelperVisitor = new LocalVariablesTypeDetectorHelperVisior(localsTypeMapHelper);
pdCloned.visit(localsTypeDetectorHelperVisitor);
// frninja 16/03/16 - строим список локальных переменных в правильном порядке
localsTypeDetectorHelperVisitor.LocalDeletedDefs.AddRange(localsTypeDetectorHelperVisitor.LocalDeletedVS);
localsTypeDetectorHelperVisitor.LocalDeletedVS.Clear();
localsClonesCollection = localsTypeDetectorHelperVisitor.LocalDeletedDefs.ToArray();
// Добавляем в класс метод с обертками для локальных переменных
pdCloned.proc_header.name.meth_name = new ident(YieldConsts.YieldHelperMethodPrefix+ "_locals_type_detector>" + pd.proc_header.name.meth_name.name); // = new method_name("<yield_helper_locals_type_detector>" + pd.proc_header.className.meth_name.className);
if (IsClassMethod(pd))
{
var cd = UpperTo<class_definition>();
if (cd != null)
{
// Метод класса описан в классе
var classMembers = UpperTo<class_members>();
classMembers.Add(pdCloned);
}
else
{
// Метод класса описан вне класса
var decls = UpperTo<declarations>();
var classMembers = decls.list
.Select(decl => decl as type_declarations)
.Where(tdecls => tdecls != null)
.SelectMany(tdecls => tdecls.types_decl)
.Where(td => td.type_name.name == GetClassName(pd).name)
.Select(td => td.type_def as class_definition)
.Where(_cd => _cd != null)
.SelectMany(_cd => _cd.body.class_def_blocks);
// Вставляем предописание метода-хелпера
var helperPredefHeader = ObjectCopier.Clone(pdCloned.proc_header);
helperPredefHeader.name.class_name = null;
classMembers.First().members.Insert(0, helperPredefHeader);
// Вставляем тело метода-хелпера
UpperTo<declarations>().InsertBefore(pd, pdCloned);
}
}
else
{
UpperTo<declarations>().InsertBefore(pd, pdCloned);
}
}
/// <summary>
/// Отображение локальных в клонированные локальные
/// </summary>
/// <param className="from">Откуда</param>
/// <param className="to">Куда</param>
/// <returns>Отображение</returns>
private Dictionary<var_def_statement, var_def_statement> CreateLocalsClonesMap(IEnumerable<var_def_statement> from, IEnumerable<var_def_statement> to)
{
// Нужно тк клонировали метод для создания хелпера-определителя типов локальных переменных - Eq не будет работать
// Строим отображение из локальных переменных клона оригинального метода в локальные переменные основного метода
Dictionary<var_def_statement, var_def_statement> localsClonesMap = new Dictionary<var_def_statement, var_def_statement>();
var localsArr = from.ToArray();
var localsClonesArr = to.ToArray();
// Create map :: locals -> cloned locals
for (int i = 0; i < localsArr.Length; ++i)
{
localsClonesMap.Add(localsArr[i], localsClonesArr[i]);
}
return localsClonesMap;
}
/// <summary>
/// Вставляем описание классов-хелперов для yield перед методом-итератором в зависимости от его описания
/// </summary>
/// <param className="pd">Метод-итератор</param>
/// <param className="cct">Описание классов-хелперов для yield</param>
private void InsertYieldHelpers(procedure_definition pd, type_declarations cct)
{
if (IsClassMethod(pd))
{
var cd = UpperTo<class_definition>();
if (cd != null)
{
// Если метод класса описан в классе
var td = UpperTo<type_declarations>();
// frninja 20/04/16 - выпилено
//foreach (var helperName in cct.types_decl.Select(ttd => ttd.type_name))
//{
// var helperPredef = new type_declaration(helperName, new class_definition());
//td.types_decl.Insert(0, helperPredef);
//}
// Insert class predefenition!
//var iteratorClassPredef = new type_declaration(GetClassName(pd), new class_definition(null));
//td.types_decl.Insert(0, iteratorClassPredef);
foreach (var helper in cct.types_decl)
{
td.types_decl.Add(helper);
}
}
else
{
// Метод класса описан вне класса
UpperTo<declarations>().InsertBefore(pd, cct);
}
}
else
{
UpperTo<declarations>().InsertBefore(pd, cct);
}
}
/// <summary>
/// Захватываем имена в методе
/// </summary>
/// <param className="pd">Метод-итератор</param>
/// <param className="deletedLocals">Коллекция удаленных локальных переменных</param>
/// <param className="capturedLocalsNamesMap">Построенное отображение имен локальных переменных в захваченные имена</param>
/// <param className="capturedFormalParamsNamesMap">Построенное отображение имен формальных параметров в захваченные имена</param>
private void ReplaceCapturedVariables(procedure_definition pd,
IEnumerable<var_def_statement> deletedLocals,
out IDictionary<string, string> capturedLocalsNamesMap,
out IDictionary<string, string> capturedFormalParamsNamesMap)
{
// Структуры данных под классификацию имен в методе
// Classification
ISet<string> CollectedLocalsNames = new HashSet<string>();
ISet<string> CollectedFormalParamsNames = new HashSet<string>();
ISet<string> CollectedClassFieldsNames = new HashSet<string>();
ISet<string> CollectedClassMethodsNames = new HashSet<string>();
ISet<string> CollectedClassPropertiesNames = new HashSet<string>();
ISet<string> CollectedUnitGlobalsNames = new HashSet<string>();
ISet<var_def_statement> CollectedLocals = new HashSet<var_def_statement>();
ISet<var_def_statement> CollectedFormalParams = new HashSet<var_def_statement>();
// Map from ident idName -> captured ident idName
capturedLocalsNamesMap = new Dictionary<string, string>();
capturedFormalParamsNamesMap = new Dictionary<string, string>();
// Собираем инфу о именах
// Collect locals
CollectedLocals.UnionWith(deletedLocals);
CollectedLocalsNames.UnionWith(deletedLocals.SelectMany(vds => vds.vars.idents).Select(id => id.name));
// Collect formal params
CollectFormalParams(pd, CollectedFormalParams);
CollectFormalParamsNames(pd, CollectedFormalParamsNames);
// Collect class fields
CollectClassFieldsNames(pd, CollectedClassFieldsNames);
// Collect class methods
CollectClassMethodsNames(pd, CollectedClassMethodsNames);
// Collect class properties
CollectClassPropertiesNames(pd, CollectedClassPropertiesNames);
// Collect unit globals
CollectUnitGlobalsNames(pd, CollectedUnitGlobalsNames);
// Строим отображения для имён захваченных локальных переменных и формальных параметров
// Create maps :: idName -> captureName
CreateCapturedLocalsNamesMap(CollectedLocalsNames, capturedLocalsNamesMap);
CreateCapturedFormalParamsNamesMap(CollectedFormalParamsNames, capturedFormalParamsNamesMap);
// Выполняем замену захват имён в теле метода
// AHAHA test!
ReplaceCapturedVariablesVisitor rcapVis = new ReplaceCapturedVariablesVisitor(
CollectedLocalsNames,
CollectedFormalParamsNames,
CollectedClassFieldsNames,
CollectedClassMethodsNames,
CollectedClassPropertiesNames,
CollectedUnitGlobalsNames,
capturedLocalsNamesMap,
capturedFormalParamsNamesMap,
IsClassMethod(pd),
GetClassName(pd)
);
// Replace
(pd.proc_body as block).program_code.visit(rcapVis);
}
private bool IsExtensionMethod(procedure_definition pd)
{
var tdecls = UpperTo<declarations>().defs.OfType<type_declarations>().SelectMany(tds => tds.types_decl);
var isExtension = pd.proc_header.proc_attributes.proc_attributes.Any(attr => attr.name == "extensionmethod");
if (isExtension)
{
// Метод объявлен как extensionmethod
// !!!!!!!! TODO: Проверить что имя класса не находится в этом модуле.
// Убираем за ненадобностью имя класса ибо оно указано как тип обязательного параметра self
pd.proc_header.name.class_name = null;
return true;
}
else
{
// Если не похоже на метод-расширение или объявление вне класса
if (pd.proc_header.name.class_name == null)
return false;
// Разрешаем только имена типов из этого модуля (не расширения)
if (!tdecls.Any(td => td.type_name.name == pd.proc_header.name.class_name.name))
{
// Имя в модуле не найдено -> метод расширение описанный без extensionmethod. Ругаемся!!!
throw new SyntaxError("Possible extension-method definintion without extensionmethod keyword. Please use extensionmethod syntax",
"",
pd.proc_header.source_context,
pd.proc_header);
}
}
return false;
}
public override void visit(procedure_definition pd)
{
if (!pd.has_yield)
return;
/*if (pd != null && pd.proc_header != null && pd.proc_header.name != null && pd.proc_header.name.meth_name != null && pd.proc_header.name.meth_name.name != null)
if (pd.proc_header.name.meth_name.name.StartsWith(YieldConsts.YieldHelperMethodPrefix))
return;
*/
//var isExtension = IsExtensionMethod(pd);
//hasYields = false;
//if (pd.proc_header is function_header)
// mids = new FindMainIdentsVisitor();
//base.visit(pd);
//if (!hasYields) // т.е. мы разобрали функцию и уже выходим. Это значит, что пока yield будет обрабатываться только в функциях. Так это и надо.
// return;
// Проверяем проблемы имен для for
CheckVariablesRedefenitionVisitor checkVarRedefVisitor = new CheckVariablesRedefenitionVisitor(
new HashSet<string>(
pd.proc_header.parameters != null
?
pd.proc_header.parameters.params_list.SelectMany(fp => fp.idents.idents.Select(id => id.name))
:
Enumerable.Empty<string>()));
pd.visit(checkVarRedefVisitor);
// Переименовываем одинаковые имена в мини-ПИ
RenameSameBlockLocalVarsVisitor renameLocalsVisitor = new RenameSameBlockLocalVarsVisitor();
pd.visit(renameLocalsVisitor);
// Теперь lowering
LoweringVisitor.Accept(pd);
// frninja 13/04/16 - убираем лишние begin..end
DeleteRedundantBeginEnds deleteBeginEndVisitor = new DeleteRedundantBeginEnds();
pd.visit(deleteBeginEndVisitor);
// Обработка метода для корректного захвата локальных переменных и их типов
yield_locals_type_map_helper localsTypeMapHelper;
IEnumerable<var_def_statement> localsClonesCollection;
CreateLocalVariablesTypeProxies(pd, out localsClonesCollection, out localsTypeMapHelper);
// frninja 16/11/15: перенес ниже чтобы работал захват для lowered for
var dld = new DeleteAllLocalDefs(); // mids.vars - все захваченные переменные
pd.visit(dld); // Удалить в локальных и блочных описаниях этой процедуры все переменные и вынести их в отдельный список var_def_statement
// Строим отображение из локальных переменных клона оригинального метода в локальные переменные основного метода
Dictionary<var_def_statement, var_def_statement> localsCloneMap = CreateLocalsClonesMap(dld.LocalDeletedDefs, localsClonesCollection);
// frninja 08/12/15
// Выполняем захват имён
IDictionary<string, string> CapturedLocalsNamesMap;
IDictionary<string, string> CapturedFormalParamsNamesMap;
ReplaceCapturedVariables(pd, dld.LocalDeletedDefs, out CapturedLocalsNamesMap, out CapturedFormalParamsNamesMap);
//mids.vars.Except(dld.LocalDeletedDefsNames); // параметры остались. Их тоже надо исключать - они и так будут обработаны
// В результате работы в mids.vars что-то осталось. Это не локальные переменные и с ними непонятно что делать
// Обработать параметры!
// Как? Ищем в mids formal_parametrs, но надо выделить именно обращение к параметрам - не полям класса, не глобальным переменным
var cfa = new ConstructFiniteAutomata((pd.proc_body as block).program_code);
cfa.Transform();
(pd.proc_body as block).program_code = cfa.res;
// Конструируем определение класса
var cct = GenClassesForYield(pd, dld.LocalDeletedDefs, CapturedLocalsNamesMap, CapturedFormalParamsNamesMap, localsCloneMap, localsTypeMapHelper); // все удаленные описания переменных делаем описанием класса
// Вставляем классы-хелперы
InsertYieldHelpers(pd, cct);
//mids = null; // вдруг мы выйдем из процедуры, не зайдем в другую, а там - оператор! Такого конечно не может быть
}
public override void visit(yield_node yn)
{
//hasYields = true;
//if (mids != null) // если мы - внутри процедуры
// yn.visit(mids);
//else throw new SyntaxError("Yield must be in functions only", "", yn.source_context, yn);
// mids.vars - надо установить, какие из них - локальные, какие - из этого класса, какие - являются параметрами функции, а какие - глобальные (все остальные)
// те, которые являются параметрами, надо скопировать в локальные переменные и переименовать использование везде по ходу данной функции
// самое сложное - переменные-поля этого класса - они требуют в создаваемом классе, реализующем итератор, хранить Self текущего класса и добавлять это Self везде по ходу алгоритма
// вначале будем считать, что переменные-поля этого класса и переменные-параметры не захватываются yield
//base.visit(yn);
}
}
class ConstructFiniteAutomata
{
public statement_list res = new statement_list();
statement_list stl;
int curState = 0;
statement_list curStatList;
statement_list StatListAfterCase = new statement_list();
case_node cas; // формируемый case
//private Dictionary<labeled_statement, List<int>> dispatches = new Dictionary<labeled_statement, List<int>>();
private labeled_statement OuterLabeledStatement;
private Dictionary<int, labeled_statement> Dispatches = new Dictionary<int,labeled_statement>();
public ConstructFiniteAutomata(statement_list stl)
{
this.stl = stl;
}
private void AddState(out int stateNumber, out ident resumeLabel)
{
stateNumber = curState++;
resumeLabel = null;
}
public void Process(statement st)
{
if (!(st is yield_node || st is labeled_statement))
{
curStatList.Add(st);
}
if (st is yield_node)
{
var yn = st as yield_node;
curState += 1;
curStatList.AddMany(
new assign(YieldConsts.Current, yn.ex),
new assign(YieldConsts.State, curState),
new assign("Result", true),
new procedure_call("exit")
);
curStatList = new statement_list();
case_variant cv = new case_variant(new expression_list(new int32_const(curState)), curStatList);
cas.conditions.variants.Add(cv);
}
if (st is labeled_statement)
{
var ls = st as labeled_statement;
// frninja 13/04/16 - диспетчерезация к следующему состоянию
curStatList.Add(new goto_statement(ls.label_name));
curStatList = StatListAfterCase;
curStatList.Add(new labeled_statement(ls.label_name));
Process(ls.to_statement);
}
}
public void Transform()
{
cas = new case_node(new ident(YieldConsts.State));
curStatList = new statement_list();
case_variant cv = new case_variant(new expression_list(new int32_const(curState)), curStatList);
cas.conditions.variants.Add(cv);
foreach (var st in stl.subnodes)
Process(st);
// frninja 13/04/16 - фикс для зависающего в последнем состоянии
var lastStateCV = cas.conditions.variants.Last().exec_if_true as statement_list;
if (lastStateCV != null)
{
lastStateCV.Add(new procedure_call("exit"));
}
stl.subnodes = BaseChangeVisitor.SeqStatements(cas, StatListAfterCase).ToList();
//statement_list res = new statement_list(cas);
res = stl;
}
}
}

View file

@ -0,0 +1,168 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
namespace SyntaxVisitors
{
public class RenameSameBlockLocalVarsVisitor : BaseChangeVisitor
{
// Надо хранить принадлежность имени конкретному ПИ на определенном уровне вложенности
// И отображение этого имени в новое
// Map :: CurrentLevel -> { BlockName -> NewBlockName }
private List<Dictionary<string, string>> BlockNamesStack { get; set; }
private Dictionary<string, int> BlockNamesCounter { get; set; }
private int CurrentLevel = -1;
public RenameSameBlockLocalVarsVisitor()
{
this.BlockNamesStack = new List<Dictionary<string, string>>();
this.BlockNamesCounter = new Dictionary<string, int>();
}
public override void visit(declarations decls)
{
// Для обхода в правильном порядке сверху вниз
var vd_s = decls.defs.OfType<variable_definitions>().ToArray();
for (int i = 0; i < vd_s.Count(); ++i)
{
ProcessNode(vd_s[i]);
}
}
public override void visit(procedure_header pd)
{
// DO NOTHING
}
public override void visit(function_header fh)
{
// DO NOTHING
}
public override void visit(formal_parameters fp)
{
// DO NOTHING
}
public override void visit(statement_list stlist)
{
++CurrentLevel;
if (BlockNamesStack.Count <= CurrentLevel)
{
// Создаем отображение для имен текущего уровня вложенности мини-пространства имен
BlockNamesStack.Add(new Dictionary<string, string>());
}
//base.visit(stlist);
for (var i = 0; i < stlist.list.Count; ++i)
ProcessNode(stlist.list[i]);
BlockNamesStack.RemoveAt(BlockNamesStack.Count - 1);
--CurrentLevel;
}
public override void visit(var_statement vs)
{
if (vs.var_def.vars.idents.Any(id => id.name.StartsWith("$")))
return;
var newLocalNames = vs.var_def.vars.idents.Select(id =>
{
var newName = this.CreateNewVariableName(id.name);
BlockNamesStack[CurrentLevel].Add(id.name, newName);
return new ident(newName, id.source_context);
});
var newVS = new var_statement(new var_def_statement(new ident_list(newLocalNames.ToArray()),
vs.var_def.vars_type,
vs.var_def.inital_value));
Replace(vs, newVS);
base.visit(newVS);
}
public override void visit(variable_definitions vd)
{
if (vd.var_definitions.Any(vds => vds.vars.idents.Any(id => id.name.StartsWith("$"))))
return;
++CurrentLevel;
if (BlockNamesStack.Count <= CurrentLevel)
{
// Создаем отображение для имен текущего уровня вложенности мини-пространства имен
BlockNamesStack.Add(new Dictionary<string, string>());
}
var newVD = new variable_definitions(
vd.var_definitions.Select(vds =>
{
var newLocalNames = vds.vars.idents.Select(id =>
{
var newName = this.CreateNewVariableName(id.name);
BlockNamesStack[CurrentLevel].Add(id.name, newName);
return new ident(newName, id.source_context);
});
return new var_def_statement(new ident_list(newLocalNames.ToArray()), vds.vars_type, vds.inital_value);
}).ToList(),
vd.source_context);
Replace(vd, newVD);
base.visit(newVD);
}
public override void visit(ident id)
{
var newName = this.GetNewVariableName(id.name);
if ((object)newName != null)
{
Replace(id, new ident(newName, id.source_context));
}
}
public override void visit(dot_node dn)
{
ProcessNode(dn.left);
if (dn.right.GetType() != typeof(ident))
ProcessNode(dn.right);
}
private string CreateNewVariableName(string name)
{
if (BlockNamesCounter.ContainsKey(name))
{
++BlockNamesCounter[name];
}
else
{
BlockNamesCounter.Add(name, 0);
}
return "$" + name + "__" + BlockNamesCounter[name];
}
private string GetNewVariableName(string name)
{
for (int i = CurrentLevel; i >= 0; --i)
{
if (BlockNamesStack[i].ContainsKey(name))
{
return BlockNamesStack[i][name];
}
}
return null;
}
}
}

View file

@ -0,0 +1,199 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
using PascalABCCompiler.YieldHelpers;
namespace SyntaxVisitors
{
public class ReplaceCapturedVariablesVisitor : BaseChangeVisitor
{
private ISet<string> CollectedLocals = new HashSet<string>();
private ISet<string> CollectedFormalParams = new HashSet<string>();
private ISet<string> CollectedClassFields = new HashSet<string>();
private ISet<string> CollectedUnitGlobals = new HashSet<string>();
// Maps :: idName -> capturedName
private IDictionary<string, string> CapturedLocalsMap = new Dictionary<string, string>();
private IDictionary<string, string> CapturedFormalParamsMap = new Dictionary<string, string>();
private bool IsInClassMethod = true;
private ident ClassName;
public ReplaceCapturedVariablesVisitor(IEnumerable<string> locals,
IEnumerable<string> formalParams,
IEnumerable<string> classFields,
IEnumerable<string> classMethods,
IEnumerable<string> classProperties,
IEnumerable<string> unitGlobals,
IDictionary<string, string> localsMap,
IDictionary<string, string> formalParamsMap,
bool isInClassMethod, ident className)
{
CollectedLocals = new HashSet<string>(locals);
CollectedFormalParams = new HashSet<string>(formalParams);
CollectedClassFields = new HashSet<string>(classFields);
CollectedUnitGlobals = new HashSet<string>(unitGlobals);
CapturedLocalsMap = new Dictionary<string, string>(localsMap);
CapturedFormalParamsMap = new Dictionary<string, string>(formalParamsMap);
IsInClassMethod = isInClassMethod;
ClassName = className;
// Methods hack
CollectedClassFields.UnionWith(classMethods);
// Properties hack
CollectedClassFields.UnionWith(classProperties);
}
public override void visit(labeled_statement ls)
{
ProcessNode(ls.to_statement);
}
public override void visit(goto_statement gt)
{
// Empty
}
// frninja 12/05/16 - фикс для yield_unknown_ident
public override void visit(yield_unknown_ident unk)
{
yield_var_def_statement_with_unknown_type x;
// Empty
}
public override void visit(ident id)
{
// Check dot node
var upper = UpperNode(1);
//if (upper is dot_node)
// return;
var idName = id.name;
var idSourceContext = id.source_context;
// frninja 31/03/16 - фикс селфа для extensionmethod
if (idName.ToLower() == "self" && !CollectedFormalParams.Contains(idName))
{
var newSelf = new dot_node(new ident("self"), new ident(YieldConsts.Self));
Replace(id, newSelf);
return;
}
// Detect where is id from
if (CollectedLocals.Contains(idName))
{
Replace(id, new ident(CapturedLocalsMap[idName], idSourceContext));
}
else if (CollectedFormalParams.Contains(idName))
{
Replace(id, new ident(CapturedFormalParamsMap[idName], idSourceContext));
}
else if (IsInClassMethod)
{
// In class -> check fields
if (CollectedClassFields.Contains(idName))
{
// Good
// Name in class fields -> capture as class field
var capturedId = new dot_node(new dot_node(new ident("self"), new ident(YieldConsts.Self)), id);
Replace(id, capturedId);
}
else
{
// Bad
// At syntax we don't know if the className is class field or not coz of e.g. base .NET classes
// HERE WE SHOULD REPLACE TO yield_unknown_reference -> so decision is passed to semantic
// Check for globals will be processed at semantic, too
if (!id.name.StartsWith("<")) // Check for already captured
{
Replace(id, new yield_unknown_ident(id, ClassName));
}
}
}
else
{
// Not in class -> check globals
if (CollectedUnitGlobals.Contains(idName))
{
// Global -> just do nothing
}
else
{
// What about static classes - search at semantic
// HERE WE SHOULD REPLACE TO yield_unknown_reference -> so decision is passed to semantic
}
}
}
/*public override void visit(procedure_call pc)
{
ProcessNode(pc.func_name);
var methCall = pc.func_name as method_call;
if ((object)methCall != null)
{
foreach (var param in methCall.parameters.expressions)
{
param.visit(this);
}
}
}*/
public override void visit(dot_node dn)
{
var rid = dn.right as ident;
if ((object)rid != null && rid.name != YieldConsts.Self)
ProcessNode(dn.left);
// Most nested
// DotNode (DLeft, DRight) -> DotNode(DotNode("self", "<>__self"), DRight)
// LEFT self -> captured self (self.captured_self)
/*var id = dn.left as ident;
if ((object)id != null && (id.className == "self" || CollectedClassFields.Contains(id.className)))
{
// Some magic for blocking back-traverse from BaseChangeVisitor redoin' work
//var rid = dn.right as ident;
//if ((object)rid != null && rid.className != Consts.Self)
{
var newDotNode = new dot_node(new dot_node(new ident("self"), new ident(Consts.Self)), dn.right);
// Change right?
//var capturedRight = new dot_node(new ident(Consts.Self), dn.right);
//var newDotNode = new dot_node(dn.left, capturedRight);
Replace(dn, newDotNode);
}
// Some magic for blocking back-traverse from BaseChangeVisitor redoin' work
//var rid = dn.right as ident;
//if ((object)rid != null && rid.className != Consts.Self)
// {
// var capturedSelf = new dot_node(new ident("self"), new ident(Consts.Self));
// Replace(dn.left, capturedSelf);
// }
}
else
{
ProcessNode(dn.left);
}*/
//if (dn.right.GetType() != typeof(ident))
// ProcessNode(dn.right);
}
}
}

View file

@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
namespace SyntaxVisitors
{
public class ReplaceForVariableVisitor : BaseChangeVisitor
{
private ident _oldName;
private ident _newName;
public ReplaceForVariableVisitor(ident oldName, ident newName)
{
_oldName = oldName;
_newName = newName;
}
public override void visit(ident id)
{
if (id.name != _oldName.name)
{
return;
}
var upperNode = UpperNode();
if (
(object)upperNode != null && (object)(upperNode as dot_node) == null)
{
Replace(id, _newName);
}
}
// frninja 11/03/16 - оно тут вообще надо???
public override void visit(dot_node dn)
{
ProcessNode(dn.left);
if (dn.right.GetType() != typeof(ident))
ProcessNode(dn.right);
}
}
}

View file

@ -0,0 +1,116 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
namespace SyntaxVisitors
{
public class ReplaceFormalParametersRefsVisitor : BaseChangeVisitor
{
public Dictionary<string, type_definition> CollectedFormalParameters = new Dictionary<string, type_definition>();
// Типа-стек соответствий paramName -> <>num__paramName для разных уровней вложенности методов
private List<Dictionary<string, string>> formalParametersStack = new List<Dictionary<string, string>>();
private bool _isClassMethod = false;
public ReplaceFormalParametersRefsVisitor()
{
}
// Лучше запретить yield в вложенных функциях и в функциях со вложенными!
// Запретить-запретить-запретить
public override void visit(procedure_definition pd)
{
// var u = UpperNode(3);
// В случае отсутствия формальных параметров
if ((object)pd.proc_header.parameters == null)
{
base.visit(pd.proc_body);
return;
}
formalParametersStack.Add(new Dictionary<string, string>());
int currentLevel = formalParametersStack.Count - 1;
foreach (var plist in pd.proc_header.parameters.params_list)
{
foreach (var id in plist.idents.idents)
{
var paramName = id.name;
var hoistedParamName = CapturedNamesHelper.MakeCapturedFormalParameterName(id.name);
formalParametersStack[currentLevel].Add(paramName, hoistedParamName);
// Захват
CollectedFormalParameters.Add(hoistedParamName, plist.vars_type);
}
}
base.visit(pd.proc_body);
formalParametersStack.RemoveAt(currentLevel);
}
public override void visit(ident id)
{
int? paramNameLevel = null;
var paramName = id.name;
// Ищем с какого уровня имя
for (int level = formalParametersStack.Count - 1; level >= 0; --level)
{
if (formalParametersStack[level].ContainsKey(paramName))
{
// Нашли!
paramNameLevel = level;
break;
}
}
bool isField = false;
// Локальные параметры обрабатываются в другом визиторе
// Параметр функции
if ((object)paramNameLevel != null)
{
var upper = UpperNode();
// Подозреваем обращение к параметру метода
if ((object)upper == null || (object)upper != null && (upper as dot_node) == null)
{
// Это не self.paramName - поле класса и не что-то другое?
// Нашли обращение к параметру?
var self = new ident("self", id.source_context);
// Заменяем paramName -> self.hoistedParamName: <>num__paramName
var hoistedParamName = new ident(formalParametersStack[(int)paramNameLevel][paramName], id.source_context);
var selfId = new dot_node(self, hoistedParamName);
Replace(id, selfId);
}
// Иначе проверить что это поле класса! self.paramName или какой-то другой очень извращенный вариант вроде (someMethod: self).paramName
}
// Поле класса
// Параметр внешней функции (если наша - вложенная)
// Глобальная переменная
}
}
}

167
Yield/YieldConversionSyntax/.gitignore vendored Normal file
View file

@ -0,0 +1,167 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
.vs/
# Build results
[Bb]inaries/
[Dd]ebug/
[Rr]elease/
x64/
[Bb]in/
[Oo]bj/
# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
!packages/*/build/
# NuGet restore semaphore
build/ToolsetPackages/toolsetpackages.semaphore
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
UnitTestResults.html
# NuGet V3 artifacts
*-packages.config
*.nuget.props
*.nuget.targets
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.wrn
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.scc
# Visual Studio cache files
*.sln.ide/
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.Publish.xml
# NuGet Packages Directory
packages/
# Windows Azure Build Output
csx
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.[Pp]ublish.xml
*.pfx
*.publishsettings
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
App_Data/*.mdf
App_Data/*.ldf
#LightSwitch generated files
GeneratedArtifacts/
_Pvt_Extensions/
ModelManifest.xml
# =========================
# Windows detritus
# =========================
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Mac desktop service store files
.DS_Store

View file

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("YieldConversionSyntax")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Hewlett-Packard")]
[assembly: AssemblyProduct("YieldConversionSyntax")]
[assembly: AssemblyCopyright("Copyright © Hewlett-Packard 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("4517de68-2805-461c-a8ac-5f9684772182")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View file

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{276EE073-60F6-46D2-8811-1B8026BCAADA}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>YieldConversionSyntax</RootNamespace>
<AssemblyName>YieldConversionSyntax</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="YieldDesugarSyntaxTreeConverter.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Compiler\Compiler.csproj">
<Project>{1e42361a-eda3-4872-88af-a3aaf600d36d}</Project>
<Name>Compiler</Name>
</ProjectReference>
<ProjectReference Include="..\..\SyntaxTreeConverters\SyntaxTreeConverters.csproj">
<Project>{f10a5330-dcf4-4533-877c-7b1b1be23884}</Project>
<Name>SyntaxTreeConverters</Name>
</ProjectReference>
<ProjectReference Include="..\..\SyntaxTree\SyntaxTree.csproj">
<Project>{c2cac65a-b2ae-4ccc-b067-e6b8e75df73a}</Project>
<Name>SyntaxTree</Name>
</ProjectReference>
<ProjectReference Include="..\SyntaxVisitors\SyntaxVisitors.csproj">
<Project>{a9ab4282-83b4-41a7-86c3-e5bf6a45e7e2}</Project>
<Name>SyntaxVisitors</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View file

@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
using SyntaxVisitors;
using PascalABCCompiler.SyntaxTreeConverters;
namespace YieldDesugarSyntaxTreeConverter
{
public class YieldDesugarSyntaxTreeConverter : ISyntaxTreeConverter
{
public string Name { get; set; }
public string Version { get; set; }
public string Description { get; set; }
public string Copyright { get; set; }
public ConverterType ConverterType { get; set; }
public ExecutionOrder ExecutionOrder { get; set; }
public syntax_tree_node Convert(syntax_tree_node root)
{
root.visit(new MarkMethodHasYieldVisitor());
root.visit(new ProcessYieldCapturedVarsVisitor());
return root;
}
/*public void Change(syntax_tree_node sn)
{
//sn.visit(new CalcConstExprs());
//sn.visit(new LoweringVisitor());
sn.visit(new ProcessYieldCapturedVarsVisitor());
}*/
}
}

167
Yield/YieldHelpers/.gitignore vendored Normal file
View file

@ -0,0 +1,167 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
.vs/
# Build results
[Bb]inaries/
[Dd]ebug/
[Rr]elease/
x64/
[Bb]in/
[Oo]bj/
# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
!packages/*/build/
# NuGet restore semaphore
build/ToolsetPackages/toolsetpackages.semaphore
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
UnitTestResults.html
# NuGet V3 artifacts
*-packages.config
*.nuget.props
*.nuget.targets
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.wrn
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.scc
# Visual Studio cache files
*.sln.ide/
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.Publish.xml
# NuGet Packages Directory
packages/
# Windows Azure Build Output
csx
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.[Pp]ublish.xml
*.pfx
*.publishsettings
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
App_Data/*.mdf
App_Data/*.ldf
#LightSwitch generated files
GeneratedArtifacts/
_Pvt_Extensions/
ModelManifest.xml
# =========================
# Windows detritus
# =========================
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Mac desktop service store files
.DS_Store

View file

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("YieldHelpers")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Hewlett-Packard")]
[assembly: AssemblyProduct("YieldHelpers")]
[assembly: AssemblyCopyright("Copyright © Hewlett-Packard 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("1befc5f9-6102-4f55-b677-5457ebcd6327")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View file

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PascalABCCompiler.YieldHelpers
{
public static class YieldConsts
{
public static string Current = "<>2__current";
public static string State = "<>1__state";
public static string Self = "<>4__self";
public static string YieldHelperMethodPrefix = "<yield_helper";
public enum ReservedNum { StateField = 1, CurrentField = 2, MethodFormalParam = 3, MethodSelf = 4, MethodLocalVariable = 5 }
}
}

View file

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{CE5C55C2-A11C-4E94-A9FA-3FC6CA3E4C09}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>YieldHelpers</RootNamespace>
<AssemblyName>YieldHelpers</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="YieldConsts.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

167
Yield/tests/.gitignore vendored Normal file
View file

@ -0,0 +1,167 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
.vs/
# Build results
[Bb]inaries/
[Dd]ebug/
[Rr]elease/
x64/
[Bb]in/
[Oo]bj/
# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
!packages/*/build/
# NuGet restore semaphore
build/ToolsetPackages/toolsetpackages.semaphore
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
UnitTestResults.html
# NuGet V3 artifacts
*-packages.config
*.nuget.props
*.nuget.targets
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.wrn
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.scc
# Visual Studio cache files
*.sln.ide/
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.Publish.xml
# NuGet Packages Directory
packages/
# Windows Azure Build Output
csx
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.[Pp]ublish.xml
*.pfx
*.publishsettings
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
App_Data/*.mdf
App_Data/*.ldf
#LightSwitch generated files
GeneratedArtifacts/
_Pvt_Extensions/
ModelManifest.xml
# =========================
# Windows detritus
# =========================
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Mac desktop service store files
.DS_Store

Binary file not shown.

View file

@ -0,0 +1,29 @@
type A = class;
type A = class
field1: integer;
field2: integer;
procedure fun1;
begin
field1 += 1;
end;
procedure fun2;
end;
type B = class
end;
procedure A.fun2;
begin
field1 += 1;
field2 += 4;
end;
procedure fun3;
begin
end;
begin
end.

View file

View file

@ -0,0 +1,14 @@
//unit TestUnitGlobalsCollector;
//interface
var testGlobal: integer;
//implementation
//var testGlobalImpl: integer;
type A = class
testField: integer;
end;
begin
testGlobal := 777;
end.

Binary file not shown.

10
Yield/tests/UnitClass.pas Normal file
View file

@ -0,0 +1,10 @@
unit UnitClass;
interface
type UnitClassTest = class
testField: real;
end;
implementation
end.

Binary file not shown.

View file

@ -0,0 +1,17 @@
type A = class
testField: real;
function Gen: sequence of real;
end;
function A.Gen: sequence of real;
begin
yield testField;
end;
begin
var q := new A();
q.Gen.Println;
end.

Binary file not shown.

View file

@ -0,0 +1,15 @@
type A = class
testField: real;
function Gen: sequence of real;
begin
yield testField;
end;
end;
begin
var q := new A();
q.Gen.Println;
end.

Binary file not shown.

View file

@ -0,0 +1,9 @@
function Gen: sequence of real;
begin
yield 1;
end;
begin
Gen.Println;
end.

Binary file not shown.

View file

@ -0,0 +1,10 @@
function Gen: sequence of real;
begin
yield 1;
end;
begin
foreach var x in Gen() do
write(x, ' ');
end.

Binary file not shown.

View file

@ -0,0 +1,9 @@
function Gen<T>: sequence of T;
begin
yield default(T);
end;
begin
Gen&<real>.Println;
end.

View file

@ -0,0 +1,15 @@
type A<T> = class
testField: T;
function Gen: sequence of T;
begin
yield testField;
end;
end;
begin
var q := new A<integer>();
q.Gen.Println;
end.

Binary file not shown.

View file

@ -0,0 +1,19 @@
type B<T> = class
testBaseField: T;
end;
type A<T> = class(B<T>)
testField: T;
function Gen: sequence of T;
begin
yield testBaseField;
end;
end;
begin
var q := new A<integer>();
q.Gen.Println;
end.

BIN
Yield/tests/testFor.exe Normal file

Binary file not shown.

27
Yield/tests/testFor.pas Normal file
View file

@ -0,0 +1,27 @@
var i: integer;
function Gen: sequence of integer;
begin
for var i := 10 downto 1 do
yield i;
for var i := 2 to 5 do
begin
if (i mod 2 = 0) then
begin
yield i;
end;
end
end;
(* procedure Gen;
begin
for var i := 10 downto 1 do
writeln(i);
end; *)
begin
//Gen();
var q := Gen();
foreach var e in q do
writeln(e);
end.

BIN
Yield/tests/testFor2.exe Normal file

Binary file not shown.

20
Yield/tests/testFor2.pas Normal file
View file

@ -0,0 +1,20 @@
var i: integer;
procedure Gen;
begin
for var i := 10 downto 1 do
writeln(i);
for var i := 2 to 5 do
begin
if (i mod 2 = 0) then
begin
writeln(i);
end;
end
end;
begin
Gen();
end.

BIN
Yield/tests/testFor3.exe Normal file

Binary file not shown.

19
Yield/tests/testFor3.pas Normal file
View file

@ -0,0 +1,19 @@
var i: integer;
function Gen: sequence of integer;
begin
for var i := 2 to 5 do
begin
if (i mod 2 = 0) then
begin
yield i;
end;
end
end;
begin
var q := Gen();
foreach var x in q do
writeln(x);
end.

BIN
Yield/tests/testIf.exe Normal file

Binary file not shown.

25
Yield/tests/testIf.pas Normal file
View file

@ -0,0 +1,25 @@
function Gen: sequence of integer;
begin
var i := 1;
if (i mod 2 = 0) then
begin
yield i;
end;
i += 1;
if (i mod 2 = 0) then
begin
yield i;
end;
i += 1;
if (i mod 2 = 0) then
begin
yield i;
end;
end;
begin
var q := Gen();
foreach var x in q do
writeln(x);
end.

BIN
Yield/tests/yield1.exe Normal file

Binary file not shown.

11
Yield/tests/yield1.pas Normal file
View file

@ -0,0 +1,11 @@
function Gen: sequence of integer;
begin
yield 1;
yield 5;
end;
begin
var q := Gen();
foreach var x in q do
Print(x);
end.

BIN
Yield/tests/yield10.exe Normal file

Binary file not shown.

45
Yield/tests/yield10.pas Normal file
View file

@ -0,0 +1,45 @@
var aa: real := 555.0;
function mcos: real;
begin
result := 99.6;
end;
procedure msin;
begin
end;
type R = class
testR: real := 77.3;
testI: integer;
//property sin: real read testR;
private
function sin(x: real): real;
begin
result := 83.9;
end;
end;
type A = class(R)
testField: real := 23.3;
function Gen(n: integer): sequence of real;
var j,k: real;
begin
//yield testField;
//yield testR;
//msin;
//yield mcos;
//yield cos(3.14);
yield sin(3.14);
//yield jgdFail;
end;
end;
begin
var t := new A();
foreach var x in t.Gen(5) do
Print(x);
end.

BIN
Yield/tests/yield11.exe Normal file

Binary file not shown.

48
Yield/tests/yield11.pas Normal file
View file

@ -0,0 +1,48 @@
uses System.IO;
uses UnitClass;
var aa: real := 555.0;
type R = class
testR: real := 77.3;
testI: integer;
property sin: real read testR;
function sin2(x: real): real;
begin
result := 83.9;
end;
private
testRr: real := 23.3;
end;
type A = class(UnitClassTest)
(*constructor Create;
begin
inherited Create('hz');
end;
constructor Create(path: string);
begin
inherited Create(path);
end;*)
function Gen(n: integer): sequence of real;
var j,k: real;
begin
//var x := BaseStream;
//var x := 56.4;
//var y := x;
yield testField;
//yield Peek();
end;
end;
begin
var t := new A();
foreach var x in t.Gen(5) do
Print(x);
end.

BIN
Yield/tests/yield12.exe Normal file

Binary file not shown.

41
Yield/tests/yield12.pas Normal file
View file

@ -0,0 +1,41 @@
var aa: real := 555.0;
function mcos: real;
begin
result := 99.6;
end;
procedure msin;
begin
end;
type R = class
testR: real := 77.3;
testI: integer;
//property sin: real read testR;
//private
function sin2(x: real): real;
begin
result := 83.9;
end;
end;
type A = class(R)
testField: real;
function Gen(n: integer): sequence of real;
var j := n;
begin
yield testField;
yield sin(3.14);
yield j;
end;
end;
begin
var t := new A();
foreach var x in t.Gen(5) do
Print(x);
end.

BIN
Yield/tests/yield14.exe Normal file

Binary file not shown.

52
Yield/tests/yield14.pas Normal file
View file

@ -0,0 +1,52 @@
var aa: real := 555.0;
function mcos: real;
begin
result := 99.6;
end;
procedure msin;
begin
end;
type R = class
testR: real := 77.3;
testI: integer;
function sin2(x: real): real;
begin
result := 83.9;
end;
end;
type A = class(R)
testField: real;
function Gen(n: integer): sequence of real;
var j := n;
var jj : real := j;
begin
//begin
var x := 777;
//yield xx;
//end;
//begin
//var x := 89.3;
//begin
// var x := 9;
//end;
yield jj;
for var x := 1 to j do
begin
yield x;
end;
//end;
end;
end;
begin
var t := new A();
foreach var x in t.Gen(5) do
Print(x);
end.

BIN
Yield/tests/yield15.exe Normal file

Binary file not shown.

16
Yield/tests/yield15.pas Normal file
View file

@ -0,0 +1,16 @@
function Gen(n: integer): sequence of real;
var j := n;
var jj : real := j;
begin
var x := 777;
yield jj;
for var x := 1 to j do
begin
yield x;
end;
end;
begin
foreach var x in Gen(5) do
Print(x);
end.

BIN
Yield/tests/yield17.exe Normal file

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show more