Yield tree conversion projects added
This commit is contained in:
parent
c2387fc548
commit
4050d31097
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
|
@ -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)
|
||||
{
|
||||
// Неверно работает. Пока не используется. Доделать
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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
167
Yield/ParsePABC1/.gitignore
vendored
Normal 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
|
||||
6
Yield/ParsePABC1/App.config
Normal file
6
Yield/ParsePABC1/App.config
Normal 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>
|
||||
56
Yield/ParsePABC1/ProgramOld.cs
Normal file
56
Yield/ParsePABC1/ProgramOld.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
36
Yield/ParsePABC1/Properties/AssemblyInfo.cs
Normal file
36
Yield/ParsePABC1/Properties/AssemblyInfo.cs
Normal 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")]
|
||||
111
Yield/ParsePABC1/YieldTest.csproj
Normal file
111
Yield/ParsePABC1/YieldTest.csproj
Normal 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
167
Yield/SyntaxVisitors/.gitignore
vendored
Normal 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
|
||||
81
Yield/SyntaxVisitors/AllVarsInProcYieldsProba.cs
Normal file
81
Yield/SyntaxVisitors/AllVarsInProcYieldsProba.cs
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
102
Yield/SyntaxVisitors/BaseVisitors/BaseChangeVisitor.cs
Normal file
102
Yield/SyntaxVisitors/BaseVisitors/BaseChangeVisitor.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
27
Yield/SyntaxVisitors/BaseVisitors/BaseEnterExitVisitor.cs
Normal file
27
Yield/SyntaxVisitors/BaseVisitors/BaseEnterExitVisitor.cs
Normal 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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
61
Yield/SyntaxVisitors/BaseVisitors/CollectNamespaces.cs
Normal file
61
Yield/SyntaxVisitors/BaseVisitors/CollectNamespaces.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
35
Yield/SyntaxVisitors/BaseVisitors/HasStatementVisitor.cs
Normal file
35
Yield/SyntaxVisitors/BaseVisitors/HasStatementVisitor.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
50
Yield/SyntaxVisitors/BaseVisitors/SmallHelperVisitors.cs
Normal file
50
Yield/SyntaxVisitors/BaseVisitors/SmallHelperVisitors.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
51
Yield/SyntaxVisitors/ChangeWhileVisitor.cs
Normal file
51
Yield/SyntaxVisitors/ChangeWhileVisitor.cs
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
50
Yield/SyntaxVisitors/ObjectCopier.cs
Normal file
50
Yield/SyntaxVisitors/ObjectCopier.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
120
Yield/SyntaxVisitors/Optimization/CalcConstExprs.cs
Normal file
120
Yield/SyntaxVisitors/Optimization/CalcConstExprs.cs
Normal 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); // это обязательно!
|
||||
}
|
||||
}
|
||||
}
|
||||
36
Yield/SyntaxVisitors/Properties/AssemblyInfo.cs
Normal file
36
Yield/SyntaxVisitors/Properties/AssemblyInfo.cs
Normal 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")]
|
||||
107
Yield/SyntaxVisitors/SyntaxVisitors.csproj
Normal file
107
Yield/SyntaxVisitors/SyntaxVisitors.csproj
Normal 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>
|
||||
44
Yield/SyntaxVisitors/UniversalVisitors/CountNodesVisitor.cs
Normal file
44
Yield/SyntaxVisitors/UniversalVisitors/CountNodesVisitor.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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;");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
74
Yield/SyntaxVisitors/YieldVisitors/DeleteAllLocalDefs.cs
Normal file
74
Yield/SyntaxVisitors/YieldVisitors/DeleteAllLocalDefs.cs
Normal 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))));
|
||||
|
||||
// еще - не заходить в лямбды
|
||||
}
|
||||
}
|
||||
}
|
||||
72
Yield/SyntaxVisitors/YieldVisitors/DeleteLocalDefs.cs
Normal file
72
Yield/SyntaxVisitors/YieldVisitors/DeleteLocalDefs.cs
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
148
Yield/SyntaxVisitors/YieldVisitors/JustTestVisitor.cs
Normal file
148
Yield/SyntaxVisitors/YieldVisitors/JustTestVisitor.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
|
||||
// еще - не заходить в лямбды
|
||||
}
|
||||
}
|
||||
}
|
||||
204
Yield/SyntaxVisitors/YieldVisitors/LoweringVisitor.cs
Normal file
204
Yield/SyntaxVisitors/YieldVisitors/LoweringVisitor.cs
Normal 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));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
884
Yield/SyntaxVisitors/YieldVisitors/ProcessYieldsCapturedVars.cs
Normal file
884
Yield/SyntaxVisitors/YieldVisitors/ProcessYieldsCapturedVars.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
167
Yield/YieldConversionSyntax/.gitignore
vendored
Normal 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
|
||||
36
Yield/YieldConversionSyntax/Properties/AssemblyInfo.cs
Normal file
36
Yield/YieldConversionSyntax/Properties/AssemblyInfo.cs
Normal 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")]
|
||||
72
Yield/YieldConversionSyntax/YieldConversionSyntax.csproj
Normal file
72
Yield/YieldConversionSyntax/YieldConversionSyntax.csproj
Normal 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>
|
||||
|
|
@ -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
167
Yield/YieldHelpers/.gitignore
vendored
Normal 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
|
||||
36
Yield/YieldHelpers/Properties/AssemblyInfo.cs
Normal file
36
Yield/YieldHelpers/Properties/AssemblyInfo.cs
Normal 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")]
|
||||
20
Yield/YieldHelpers/YieldConsts.cs
Normal file
20
Yield/YieldHelpers/YieldConsts.cs
Normal 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 }
|
||||
}
|
||||
}
|
||||
54
Yield/YieldHelpers/YieldHelpers.csproj
Normal file
54
Yield/YieldHelpers/YieldHelpers.csproj
Normal 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
167
Yield/tests/.gitignore
vendored
Normal 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
|
||||
BIN
Yield/tests/TestClassFieldsCollector.exe
Normal file
BIN
Yield/tests/TestClassFieldsCollector.exe
Normal file
Binary file not shown.
29
Yield/tests/TestClassFieldsCollector.pas
Normal file
29
Yield/tests/TestClassFieldsCollector.pas
Normal 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.
|
||||
0
Yield/tests/TestUnitGlobalsCollector.exe
Normal file
0
Yield/tests/TestUnitGlobalsCollector.exe
Normal file
14
Yield/tests/TestUnitGlobalsCollector.pas
Normal file
14
Yield/tests/TestUnitGlobalsCollector.pas
Normal 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.
|
||||
BIN
Yield/tests/TestUnitGlobalsCollector.pcu
Normal file
BIN
Yield/tests/TestUnitGlobalsCollector.pcu
Normal file
Binary file not shown.
10
Yield/tests/UnitClass.pas
Normal file
10
Yield/tests/UnitClass.pas
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
unit UnitClass;
|
||||
|
||||
interface
|
||||
type UnitClassTest = class
|
||||
testField: real;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
BIN
Yield/tests/basic/yieldSimpleExternalClassDef.exe
Normal file
BIN
Yield/tests/basic/yieldSimpleExternalClassDef.exe
Normal file
Binary file not shown.
17
Yield/tests/basic/yieldSimpleExternalClassDef.pas
Normal file
17
Yield/tests/basic/yieldSimpleExternalClassDef.pas
Normal 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.
|
||||
BIN
Yield/tests/basic/yieldSimpleInClassDef.exe
Normal file
BIN
Yield/tests/basic/yieldSimpleInClassDef.exe
Normal file
Binary file not shown.
15
Yield/tests/basic/yieldSimpleInClassDef.pas
Normal file
15
Yield/tests/basic/yieldSimpleInClassDef.pas
Normal 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.
|
||||
BIN
Yield/tests/basic/yieldSimpleMethodDef.exe
Normal file
BIN
Yield/tests/basic/yieldSimpleMethodDef.exe
Normal file
Binary file not shown.
9
Yield/tests/basic/yieldSimpleMethodDef.pas
Normal file
9
Yield/tests/basic/yieldSimpleMethodDef.pas
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
function Gen: sequence of real;
|
||||
begin
|
||||
yield 1;
|
||||
end;
|
||||
|
||||
|
||||
begin
|
||||
Gen.Println;
|
||||
end.
|
||||
BIN
Yield/tests/basic/yieldSimpleMethodDef2.exe
Normal file
BIN
Yield/tests/basic/yieldSimpleMethodDef2.exe
Normal file
Binary file not shown.
10
Yield/tests/basic/yieldSimpleMethodDef2.pas
Normal file
10
Yield/tests/basic/yieldSimpleMethodDef2.pas
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
function Gen: sequence of real;
|
||||
begin
|
||||
yield 1;
|
||||
end;
|
||||
|
||||
|
||||
begin
|
||||
foreach var x in Gen() do
|
||||
write(x, ' ');
|
||||
end.
|
||||
BIN
Yield/tests/basic/yieldSimpleMethodDef_old.exe
Normal file
BIN
Yield/tests/basic/yieldSimpleMethodDef_old.exe
Normal file
Binary file not shown.
0
Yield/tests/template/yieldMethodTemplate.exe
Normal file
0
Yield/tests/template/yieldMethodTemplate.exe
Normal file
9
Yield/tests/template/yieldMethodTemplate.pas
Normal file
9
Yield/tests/template/yieldMethodTemplate.pas
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
function Gen<T>: sequence of T;
|
||||
begin
|
||||
yield default(T);
|
||||
end;
|
||||
|
||||
|
||||
begin
|
||||
Gen&<real>.Println;
|
||||
end.
|
||||
15
Yield/tests/template/yieldSimpleTemplate.pas
Normal file
15
Yield/tests/template/yieldSimpleTemplate.pas
Normal 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.
|
||||
BIN
Yield/tests/template/yieldSimpleTemplateWithField.exe
Normal file
BIN
Yield/tests/template/yieldSimpleTemplateWithField.exe
Normal file
Binary file not shown.
19
Yield/tests/template/yieldSimpleTemplateWithField.pas
Normal file
19
Yield/tests/template/yieldSimpleTemplateWithField.pas
Normal 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
BIN
Yield/tests/testFor.exe
Normal file
Binary file not shown.
27
Yield/tests/testFor.pas
Normal file
27
Yield/tests/testFor.pas
Normal 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
BIN
Yield/tests/testFor2.exe
Normal file
Binary file not shown.
20
Yield/tests/testFor2.pas
Normal file
20
Yield/tests/testFor2.pas
Normal 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
BIN
Yield/tests/testFor3.exe
Normal file
Binary file not shown.
19
Yield/tests/testFor3.pas
Normal file
19
Yield/tests/testFor3.pas
Normal 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
BIN
Yield/tests/testIf.exe
Normal file
Binary file not shown.
25
Yield/tests/testIf.pas
Normal file
25
Yield/tests/testIf.pas
Normal 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
BIN
Yield/tests/yield1.exe
Normal file
Binary file not shown.
11
Yield/tests/yield1.pas
Normal file
11
Yield/tests/yield1.pas
Normal 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
BIN
Yield/tests/yield10.exe
Normal file
Binary file not shown.
45
Yield/tests/yield10.pas
Normal file
45
Yield/tests/yield10.pas
Normal 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
BIN
Yield/tests/yield11.exe
Normal file
Binary file not shown.
48
Yield/tests/yield11.pas
Normal file
48
Yield/tests/yield11.pas
Normal 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
BIN
Yield/tests/yield12.exe
Normal file
Binary file not shown.
41
Yield/tests/yield12.pas
Normal file
41
Yield/tests/yield12.pas
Normal 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
BIN
Yield/tests/yield14.exe
Normal file
Binary file not shown.
52
Yield/tests/yield14.pas
Normal file
52
Yield/tests/yield14.pas
Normal 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
BIN
Yield/tests/yield15.exe
Normal file
Binary file not shown.
16
Yield/tests/yield15.pas
Normal file
16
Yield/tests/yield15.pas
Normal 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
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
Loading…
Reference in a new issue