Обновлен проект с визиторами.

Исправлен ToString в write.
Убраны параметры по умолчанию из метода расширения Print (пока это вызывает падение)
This commit is contained in:
miks1965 2015-08-10 11:31:02 +03:00
parent 50a7481a1b
commit 1fccb1e103
24 changed files with 225 additions and 188 deletions

View file

@ -15,7 +15,7 @@ internal static class RevisionClass
public const string Major = "2";
public const string Minor = "2";
public const string Build = "0";
public const string Revision = "999";
public const string Revision = "1001";
public const string MainVersion = Major + "." + Minor;
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;

View file

@ -1,4 +1,4 @@
%MINOR%=2
%REVISION%=999
%REVISION%=1001
%MAJOR%=2
%COREVERSION%=0

View file

@ -1 +1 @@
!define VERSION '2.2.0.999'
!define VERSION '2.2.0.1001'

View file

@ -90,7 +90,7 @@ namespace PascalABCCompiler.SyntaxTree
return cm;
}
public static class_definition BuildClassDefinition(bool is_class, params class_members[] cms)
public static class_definition BuildClassOrRecordDefinition(bool is_class, params class_members[] cms)
{
var cb = new class_body();
foreach (var cm in cms)
@ -101,6 +101,11 @@ namespace PascalABCCompiler.SyntaxTree
return cd;
}
public static class_definition BuildClassDefinition(params class_members[] cms)
{
return BuildClassOrRecordDefinition(true,cms);
}
// names и types передаю во внешний мир на предмет анализа того, что они не указатели. Снаружи они инициализируются пустыми списками
public static void AddMembersForAutoClass(class_definition cd, ref List<ident> names, ref List<type_definition> types) // SSM 24.03.14
{
@ -169,7 +174,7 @@ namespace PascalABCCompiler.SyntaxTree
var cm2 = BuildSimpleConstructorSection(names, formnames, types);
var cm3 = BuildOneMemberSection(pd);
return new type_declaration(class_name, BuildClassDefinition(true, cm1, cm2, cm3), BuildGenSC);
return new type_declaration(class_name, BuildClassOrRecordDefinition(true, cm1, cm2, cm3), BuildGenSC);
}
public static type_declaration BuildAutoClass(string class_name, List<ident> names, List<type_definition> types, bool is_class)
@ -180,7 +185,7 @@ namespace PascalABCCompiler.SyntaxTree
var cm2 = BuildSimpleConstructorSection(fnames,names,types);
var cm3 = BuildSimpleReadPropertiesSection(names, fnames, types);
return new type_declaration(class_name, BuildClassDefinition(is_class, cm1, cm2, cm3), BuildGenSC);
return new type_declaration(class_name, BuildClassOrRecordDefinition(is_class, cm1, cm2, cm3), BuildGenSC);
}
public static type_declaration BuildClassWithFieldsOnly(string class_name, List<ident> names, List<type_definition> types, bool is_class)
@ -189,7 +194,7 @@ namespace PascalABCCompiler.SyntaxTree
var cm1 = BuildClassFieldsSection(fnames, types);
return new type_declaration(class_name, BuildClassDefinition(is_class, cm1), BuildGenSC);
return new type_declaration(class_name, BuildClassOrRecordDefinition(is_class, cm1), BuildGenSC);
}
public static procedure_definition BuildShortFuncDefinition(formal_parameters fp, procedure_attributes_list att, method_name name, type_definition result, expression ex, SourceContext headsc)

View file

@ -2721,6 +2721,26 @@ end;
//------------------------------------------------------------------------------
// StructuredObjectToString
//------------------------------------------------------------------------------
// Âîçâðàùàåò ïåðåîïðåäåëåííûé â ïîñëåäíåì ïîòîìêå ToString èëè nil åñëè ToString îïðåäåëåí â Object
function RedefinedToString(o: object): System.Reflection.MethodInfo;
begin
var t := o.GetType;
var meth: System.Reflection.MethodInfo := nil;
while t<>typeof(Object) do
begin
meth := t.GetMethod('ToString',System.Reflection.BindingFlags.Public or
System.Reflection.BindingFlags.Instance or
System.Reflection.BindingFlags.DeclaredOnly,nil,new System.Type[0],nil);
if meth<>nil then
break;
t := t.BaseType;
end;
if t=typeof(Object) then
Result := nil
else Result := meth;
end;
function ArrNToString(a: System.Array; indexes: array of integer; i: integer): string; forward;
function StructuredObjectToString(o: Object; n: integer := 0): string;
@ -2775,7 +2795,7 @@ begin
end
else
begin
var q := o.GetType.GetMethod('ToString',System.Reflection.BindingFlags.Public or System.Reflection.BindingFlags.Instance,nil,new System.Type[0],nil);
var q := RedefinedToString(o);
var gg := o.GetType.FullName.StartsWith('System.Tuple');
var gg1 := o.GetType.Name.StartsWith('KeyValuePair');
if (q<>nil) and q.IsVirtual and not gg and not gg1 then
@ -2997,7 +3017,7 @@ end;}
// Extension methods for IEnumerable<T>
//------------------------------------------------------------------------------
/// Âûâîäèò ïîñëåäîâàòåëüíîñòü íà ýêðàí, èñïîëüçóÿ delim â êà÷åñòâå ðàçäåëèòåëÿ
function System.Collections.Generic.IEnumerable<T>.Print(delim: string := ' '): sequence of T;
function System.Collections.Generic.IEnumerable<T>.Print(delim: string): sequence of T;
begin
var g := Self.GetEnumerator();
if g.MoveNext() then
@ -3007,16 +3027,28 @@ begin
Result := Self;
end;
/// Âûâîäèò ïîñëåäîâàòåëüíîñòü íà ýêðàí, èñïîëüçóÿ ïðîáåë â êà÷åñòâå ðàçäåëèòåëÿ
function System.Collections.Generic.IEnumerable<T>.Print(): sequence of T;
begin
Result := Self.Print(' ');
end;
/// Âûâîäèò ïîñëåäîâàòåëüíîñòü íà ýêðàí, èñïîëüçóÿ delim â êà÷åñòâå ðàçäåëèòåëÿ, è ïåðåõîäèò íà íîâóþ ñòðîêó
function System.Collections.Generic.IEnumerable<T>.Println(delim: string := ' '): sequence of T;
function System.Collections.Generic.IEnumerable<T>.Println(delim: string): sequence of T;
begin
Self.Print(delim);
Writeln;
Result := Self;
end;
/// Âûâîäèò ïîñëåäîâàòåëüíîñòü íà ýêðàí, èñïîëüçóÿ ïðîáåë êà÷åñòâå ðàçäåëèòåëÿ, è ïåðåõîäèò íà íîâóþ ñòðîêó
function System.Collections.Generic.IEnumerable<T>.Println(): sequence of T;
begin
Result := Self.Println(' ');
end;
/// Ïðåîáðàçóåò ýëåìåíòû ïîñëåäîâàòåëüíîñòè â ñòðîêîâîå ïðåäñòàâëåíèå, ïîñëå ÷åãî îáúåäèíÿåò èõ â ñòðîêó, èñïîëüçóÿ delim â êà÷åñòâå ðàçäåëèòåëÿ
function System.Collections.Generic.IEnumerable<T>.JoinIntoString(delim: string := ' '): string;
function System.Collections.Generic.IEnumerable<T>.JoinIntoString(delim: string): string;
begin
var g := Self.GetEnumerator();
var sb := new System.Text.StringBuilder('');
@ -3027,6 +3059,12 @@ begin
Result := sb.ToString;
end;
/// Ïðåîáðàçóåò ýëåìåíòû ïîñëåäîâàòåëüíîñòè â ñòðîêîâîå ïðåäñòàâëåíèå, ïîñëå ÷åãî îáúåäèíÿåò èõ â ñòðîêó, èñïîëüçóÿ ïðîáåë â êà÷åñòâå ðàçäåëèòåëÿ
function System.Collections.Generic.IEnumerable<T>.JoinIntoString(): string;
begin
Result := Self.JoinIntoString(' ');
end;
/// Ïðèìåíÿåò äåéñòâèå ê êàæäîìó ýëåìåíòó ïîñëåäîâàòåëüíîñòè
procedure System.Collections.Generic.IEnumerable<T>.&ForEach(action: Action<T>);
begin

View file

@ -286,7 +286,7 @@ namespace TreeConverter.LambdaExpressions.Closure
var nextNodeWhereVarsAreCaptured = upperScopesStack.Pop();
if (!_capturedVarsClassDefs.ContainsKey(nextNodeWhereVarsAreCaptured.ScopeIndex))
{
var classDef = SyntaxTreeBuilder.BuildClassDefinition(true);
var classDef = SyntaxTreeBuilder.BuildClassDefinition();
var typeDeclaration = new type_declaration(GeneratedClassName, classDef);
_capturedVarsClassDefs.Add(nextNodeWhereVarsAreCaptured.ScopeIndex,
new ScopeClassDefinition(
@ -462,7 +462,7 @@ namespace TreeConverter.LambdaExpressions.Closure
{
if (!_capturedVarsClassDefs.ContainsKey(scope.ScopeIndex))
{
var classDef = SyntaxTreeBuilder.BuildClassDefinition(true);
var classDef = SyntaxTreeBuilder.BuildClassDefinition();
var typeDeclaration = new type_declaration(GeneratedClassName, classDef);
_capturedVarsClassDefs.Add(scope.ScopeIndex,
new ScopeClassDefinition(
@ -641,7 +641,7 @@ namespace TreeConverter.LambdaExpressions.Closure
{
if (!_capturedVarsClassDefs.ContainsKey(currentNode.ScopeIndex))
{
var classDef = SyntaxTreeBuilder.BuildClassDefinition(true);
var classDef = SyntaxTreeBuilder.BuildClassDefinition();
var typeDeclaration = new type_declaration(((CapturedVariablesTreeNodeClassScope)currentNode).ClassName, classDef);
_capturedVarsClassDefs.Add(currentNode.ScopeIndex,
new ScopeClassDefinition(currentNode.CorrespondingSyntaxTreeNode,
@ -654,7 +654,7 @@ namespace TreeConverter.LambdaExpressions.Closure
{
if (!_capturedVarsClassDefs.ContainsKey(currentNode.ScopeIndex))
{
var classDef = SyntaxTreeBuilder.BuildClassDefinition(true);
var classDef = SyntaxTreeBuilder.BuildClassDefinition();
var typeDeclaration = new type_declaration(GeneratedClassName, classDef);
_capturedVarsClassDefs.Add(currentNode.ScopeIndex,
new ScopeClassDefinition(currentNode.CorrespondingSyntaxTreeNode,

View file

@ -567,7 +567,7 @@ namespace TreeConverter.LambdaExpressions.Closure
private Tuple<type_declaration, List<procedure_definition>> CreateTypeDeclarationWithForwardDeclaration(type_declaration cl)
{
var oldClDef = (class_definition) cl.type_def;
var classDef = SyntaxTreeBuilder.BuildClassDefinition(true);
var classDef = SyntaxTreeBuilder.BuildClassDefinition();
var typeDeclaration = new type_declaration(cl.type_name, classDef);
classDef.where_section = oldClDef.where_section;
var procedures = new List<procedure_definition>();

View file

@ -5,9 +5,9 @@ VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ParsePABC1", "ParsePABC1\ParsePABC1.csproj", "{BAA767F1-6544-4A44-BA17-5FBFCF6F2D99}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SyntaxTree", "..\..\PascalABC.NET\!PABC_Git\SyntaxTree\SyntaxTree.csproj", "{C2CAC65A-B2AE-4CCC-B067-E6B8E75DF73A}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SyntaxTree", "..\SyntaxTree\SyntaxTree.csproj", "{C2CAC65A-B2AE-4CCC-B067-E6B8E75DF73A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCompletion", "..\..\PascalABC.NET\!PABC_Git\CodeCompletion\CodeCompletion.csproj", "{1AB15F6E-C22E-499A-A7ED-54BA7DE5CFA6}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCompletion", "..\CodeCompletion\CodeCompletion.csproj", "{1AB15F6E-C22E-499A-A7ED-54BA7DE5CFA6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution

View file

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

View file

@ -11,61 +11,57 @@ namespace ParsePABC1
{
class BaseChangeVisitor : CollectUpperNodesVisitor
{
public override void DefaultVisit(syntax_tree_node 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");
int ind = -1;
for (var i = 0; i < upper.subnodes_count; i++)
if (from == upper[i])
{
ind = i;
break;
}
upper[ind] = to;
upper.Replace(from, to);
}
public statement_list UpperStatementList()
public T UpperNodeAs<T>(int up = 1) where T : syntax_tree_node
{
var stl = UpperNode() as statement_list;
var stl = UpperNode(up) as T;
if (stl == null)
throw new Exception("оператор вложен не в statement_list");
throw new Exception("Элемент вложен не в " + typeof(T));
return stl;
}
public bool DeleteInIdentList(ident id)
{
var idl = UpperNodeAs<ident_list>();
return idl.Remove(id);
}
public bool DeleteInStatementList(statement st)
{
var stl = UpperStatementList();
bool b = stl.subnodes.Remove(st);
return b;
}
public bool DeleteInIdentList(ident id)
{
var idl = UpperNode() as ident_list;
if (idl==null)
throw new Exception("идентификатор не вложен в id_list");
var b = idl.idents.Remove(id);
return b;
var stl = UpperNodeAs<statement_list>();
return stl.Remove(st);
}
public void ReplaceStatement(statement from, statement to)
{
var stl = UpperStatementList();
var ind = stl.subnodes.IndexOf(from);
if (ind == -1)
throw new Exception("оператор from не найден - некорректный вызов ReplaceStatement");
stl.subnodes[ind] = to;
var stl = UpperNodeAs<statement_list>();
stl.Replace(from, to);
}
public void ReplaceStatement(statement from, List<statement> to)
public void ReplaceStatement(statement from, IEnumerable<statement> to)
{
var stl = UpperStatementList();
var ind = stl.subnodes.IndexOf(from);
if (ind == -1)
throw new Exception("оператор from не найден - некорректный вызов ReplaceStatement");
stl.subnodes.RemoveAt(ind);
stl.subnodes.InsertRange(ind, to);
var stl = UpperNodeAs<statement_list>();
stl.Replace(from, to);
}
}

View file

@ -9,7 +9,7 @@ using PascalABCCompiler.SyntaxTree;
namespace ParsePABC1
{
class BaseEnterExitVisitor: WalkingVisitor
class BaseEnterExitVisitor: WalkingVisitorNew
{
public BaseEnterExitVisitor()
{

View file

@ -49,9 +49,11 @@ namespace ParsePABC1
public override void visit(class_definition cl)
{
type_declarations tds = UpperNode(2) as type_declarations;
var f = tds.types_decl.Find(td => td.type_def == cl);
if (PrintInfo)
{
var f = tds.types_decl.Find(td => td.type_def == cl);
Console.WriteLine(" " + f.type_name);
}
base.visit(cl);
}
}

View file

@ -9,7 +9,7 @@ using PascalABCCompiler.SyntaxTree;
namespace ParsePABC1
{
public class FindLocalDefsVisitor : WalkingVisitor // Запускать только для подпрограмм
public class FindLocalDefsVisitor : WalkingVisitorNew // Запускать только для подпрограмм
{
public ISet<string> ids = new HashSet<string>();
private bool indef = false;
@ -33,7 +33,7 @@ namespace ParsePABC1
}
}
public class FindMainIdentsVisitor : WalkingVisitor // в выражении yield это надо будет.
public class FindMainIdentsVisitor : WalkingVisitorNew // в выражении yield это надо будет.
{
public HashSet<string> vars = new HashSet<string>();
public override void visit(ident id)

View file

@ -19,36 +19,26 @@ namespace ParsePABC1
lbnum++;
return "lb#" + lbnum.ToString();
}
public override void Exit(syntax_tree_node st)
public override void visit(while_node wn)
{
if (st.GetType() == typeof(while_node))
{
var wn = st as while_node;
ProcessNode(wn.statements);
var gt1 = new goto_statement(newLabelName());
var gt2 = new goto_statement(newLabelName());
var gt3 = new goto_statement(newLabelName());
var stl = new statement_list();
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 gt1 = new goto_statement(newLabelName());
var gt2 = new goto_statement(newLabelName());
var gt3 = new goto_statement(newLabelName());
var stl = new statement_list(lb3, gt2, lb1, gt3, lb2);
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());
Replace(wn, stl);
// в declarations ближайшего блока добавить описание labels
block bl = listNodes.FindLast(x => x is block) as block;
stl.Add(lb3).Add(gt2).Add(lb1).Add(gt3).Add(lb2);
//var op = new if_node(wn.expr, wn.statements, null);
Replace(wn, stl);
// в declarations ближайшего блока добавить описание labels
block bl = listNodes.FindLast(x => x is block) as block;
var il = new ident_list();
il.Add(gt1.label).Add(gt2.label).Add(gt3.label);
var ld = new label_definitions(il);
bl.defs.Add(ld);
}
base.Exit(st);
var ld = new label_definitions(gt1.label, gt2.label, gt3.label);
bl.defs.Add(ld);
}
}

View file

@ -54,31 +54,16 @@ namespace ParsePABC1
if (idents.Count == 0)
{
// Выше - variable_definitions, еще выше - declarations
var uvdsl = UpperNode() as variable_definitions;
uvdsl.var_definitions.Remove(vd); // Проблема - мы удаляем первую var_def_statement и вторая становится первой. А в цикле обхода - индексы что естественно
var uvdsl = UpperNodeAs<variable_definitions>();
uvdsl.var_definitions.Remove(vd);
if (uvdsl.var_definitions.Count == 0)
{
var d = UpperNode(2) as declarations;
var d = UpperNodeAs<declarations>(2);
d.defs.Remove(uvdsl);
}
}
}
}
}
public override void visit(variable_definitions vd)
{
if (vd.var_definitions != null)
for (int i = vd.var_definitions.Count - 1; i >= 0; --i) // в обратном порядке - тогда удаление текущего элемента работает корректно
ProcessNode(vd.var_definitions[i]);
}
public override void visit(declarations d)
{
if (d.defs != null)
for (int i = d.defs.Count - 1; i >= 0; --i) // в обратном порядке - тогда удаление текущего элемента работает корректно
ProcessNode(d.defs[i]);
}
public void AfterProcTraverse()
{
idsToDelete.ExceptWith(deletedIdsToDeleteInLocalScope); // исключаем из множества удаляемых идентификаторов те, которые мы нашли и удалили в секции var_statement. Это надо делать не для каждого описания, а в конце подпрограммы после удаления из всех секций var_statement

View file

@ -11,6 +11,7 @@
<AssemblyName>ParsePABC1</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@ -83,11 +84,11 @@
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\PascalABC.NET\!PABC_Git\CodeCompletion\CodeCompletion.csproj">
<ProjectReference Include="..\..\CodeCompletion\CodeCompletion.csproj">
<Project>{1ab15f6e-c22e-499a-a7ed-54ba7de5cfa6}</Project>
<Name>CodeCompletion</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\PascalABC.NET\!PABC_Git\SyntaxTree\SyntaxTree.csproj">
<ProjectReference Include="..\..\SyntaxTree\SyntaxTree.csproj">
<Project>{c2cac65a-b2ae-4ccc-b067-e6b8e75df73a}</Project>
<Name>SyntaxTree</Name>
</ProjectReference>

View file

@ -19,8 +19,7 @@ namespace ParsePABC1
return "clyield#" + clnum.ToString();
}
public FindMainIdentsVisitor mids = new FindMainIdentsVisitor(); // захваченные переменные процедуры по всем её yield
public FindMainIdentsVisitor mids; // захваченные переменные процедуры по всем её yield
public int countNodesVisited;
@ -44,61 +43,54 @@ namespace ParsePABC1
// сокращение обходимых узлов. Как сделать фильтр по тем узлам, которые необходимо обходить? Например, все операторы (без выражений и описаний), все описания (без операторов)
if (st is assign || st is var_def_statement || st is procedure_call || st is procedure_header || st is expression)
{
visitNode = false;
}
if (st is procedure_definition)
{
mids.vars.Clear(); // очищать при входе в процедуру
visitNode = false; // фильтр - куда не заходить
}
}
public override void Exit(syntax_tree_node st)
type_declaration GenClassForYield(procedure_definition pd, IEnumerable<var_def_statement> fields)
{
if (st is procedure_definition) // т.е. мы разобрали процедуру и уже выходим. Это значит, что пока yield будет обрабатываться только в процедурах. Так это и надо.
{
if (!hasYields)
return;
var dld = new DeleteLocalDefs(mids.vars); // mids.vars - все захваченные переменные
st.visit(dld); // Удалить в локальных и блочных описаниях этой процедуры все захваченные переменные
// В результате работы в mids.vars что-то осталось. Это не локальные переменные и с ними непонятно что делать
dld.AfterProcTraverse();
var cm = new class_members(access_modifer.public_modifer);
foreach (var m in dld.BlockDeletedIds)
cm.Add(m);
cm.Add(st as procedure_definition);
var cc = new type_declaration(newClassName(), SyntaxTreeBuilder.BuildClassDefinition(true, cm), SyntaxTreeBuilder.BuildGenSC);
var cct = new type_declarations(cc, null);
Replace(st, cct);
/*Console.WriteLine("Удаленные переменные: " + (st as procedure_definition).proc_header.name.meth_name.name);
foreach (var dd in dld.deletedIdsToDeleteInLocalScope)
Console.Write(dd + " ");
Console.WriteLine();
Console.WriteLine("Оставшиеся переменные: " + (st as procedure_definition).proc_header.name.meth_name.name);
foreach (var dd in mids.vars)
Console.Write(dd + " ");
Console.WriteLine();*/
}
base.Exit(st);
// Теперь на месте процедуры генерируем класс
var cm = new class_members(access_modifer.public_modifer);
foreach (var m in fields)
cm.Add(m);
cm.Add(pd);
return new type_declaration(newClassName(), SyntaxTreeBuilder.BuildClassDefinition(cm), SyntaxTreeBuilder.BuildGenSC);
}
public override void visit(procedure_definition pd)
{
hasYields = false;
mids = new FindMainIdentsVisitor();
base.visit(pd);
if (!hasYields) // т.е. мы разобрали процедуру и уже выходим. Это значит, что пока yield будет обрабатываться только в процедурах. Так это и надо.
return;
var dld = new DeleteLocalDefs(mids.vars); // mids.vars - все захваченные переменные
pd.visit(dld); // Удалить в локальных и блочных описаниях этой процедуры все захваченные переменные
// В результате работы в mids.vars что-то осталось. Это не локальные переменные и с ними непонятно что делать
dld.AfterProcTraverse();
// Конструируем определение класса
var cc = GenClassForYield(pd, dld.BlockDeletedIds.Union(dld.LocalDeletedIds));
var cct = new type_declarations(cc);
Replace(pd, cct);
mids = null; // вдруг мы выйдем из процедуры, не зайдем в другую, а там - оператор! Такого конечно не может быть
}
public override void visit(yield_node yn)
{
hasYields = true;
yn.visit(mids);
if (mids != null) // если мы - внутри процедуры
yn.visit(mids);
// mids.vars - надо установить, какие из них - локальные, какие - из этого класса, какие - являются параметрами функции, а какие - глобальные (все остальные)
// те, которые являются параметрами, надо скопировать в локальные переменные и переименовать использование везде по ходу данной функции
// самое сложное - переменные-поля этого класса - они требуют в создаваемом классе, реализующем итератор, хранить Self текущего класса и добавлять это Self везде по ходу алгоритма
// вначале будем считать, что переменные-поля этого класса и переменные-параметры не захватываются yield
//base.visit(yn);
}
public override void visit(declarations d) // в обратном порядке
{
if (d.defs != null)
for (int i = d.defs.Count - 1; i >= 0; --i) // в обратном порядке - тогда удаление текущего элемента работает корректно
ProcessNode(d.defs[i]);
}
}
}

View file

@ -1,4 +1,5 @@
using System;
using static System.Console;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -24,44 +25,52 @@ namespace ParsePABC1
if (cu == null)
{
Console.WriteLine("Не распарсилось");
WriteLine("Не распарсилось");
}
return cu;
}
static void Main(string[] args)
{
var cu = ParseFile(@"d:\w5\ex1.pas");
if (cu == null)
return;
/*cu.visit(new ChangeWhileVisitor());
cu.visit(new DeleteRedundantBeginEnds());*/
try
{
var cu = ParseFile(@"d:\w5\yield2.pas");
if (cu == null)
return;
/*cu.visit(new CollectUpperNamespacesVisitor());
/*cu.visit(new ChangeWhileVisitor());
cu.visit(new DeleteRedundantBeginEnds());*/
var allv = new AllVarsInProcYields();
cu.visit(allv);
allv.PrintDict();*/
/*cu.visit(new CollectUpperNamespacesVisitor());
/*var cnt = new CountNodesVisitor();
cu.visit(cnt);
cnt.PrintSortedByValue();*/
var allv = new AllVarsInProcYields();
cu.visit(allv);
allv.PrintDict();*/
/*var ld = new HashSet<string>();
ld.Add("a");
ld.Add("p1");
ld.Add("s");
var dld = new DeleteLocalDefs(ld);
cu.visit(dld);*/
/*var cnt = new CountNodesVisitor();
cu.visit(cnt);
cnt.PrintSortedByValue();*/
/*var p = new ProcessYieldCapturedVarsVisitor();
cu.visit(p);*/
/*var ld = new HashSet<string>();
ld.Add("a");
ld.Add("p1");
ld.Add("s");
var dld = new DeleteLocalDefs(ld);
cu.visit(dld);*/
var p = new CalcConstExprs();
cu.visit(p);
var p = new ProcessYieldCapturedVarsVisitor();
cu.visit(p);
/*var p = new CalcConstExprs();
cu.visit(p);*/
cu.visit(new SimplePrettyPrinterVisitor());
}
catch (Exception e)
{
Console.WriteLine(e);
}
cu.visit(new SimplePrettyPrinterVisitor());
}
}
}

View file

@ -14,7 +14,7 @@ using PascalABCCompiler.SyntaxTree;
namespace ParsePABC1
{
class SimplePrettyPrinterVisitor: WalkingVisitor
class SimplePrettyPrinterVisitor: WalkingVisitorNew
{
int off = 0;

View file

@ -7,8 +7,8 @@ const ccc: integer = 2;
type bcd = integer;
begin
var k: integer;
yield x111.x222+fff;
yield aaa[i]^.d+(bbb.c*nnn^)*fff(4);
// yield x111.x222+fff;
// yield aaa[i]^.d+(bbb.c*nnn^)*fff(4);
end;
function f(var i,j,k: integer): integer;

View file

@ -11,6 +11,7 @@ var l,m,n: integer;
kk,jj: real;
begin
var i,j,k,mmm: integer;
yield x111.x222+fff;
yield l*k;
yield i*n;
end;

View file

@ -1,13 +1,13 @@
type A = class
j,k: integer;
end;
function Gen: sequence of integer;
var j,k: real;
begin
var i := 1;
while i<=10 do
begin
yield i*i;
i += 1;
end;
yield i*j;
end;
begin
write(1)
end.

Binary file not shown.

View file

@ -3017,7 +3017,7 @@ end;}
// Extension methods for IEnumerable<T>
//------------------------------------------------------------------------------
/// Выводит последовательность на экран, используя delim в качестве разделителя
function System.Collections.Generic.IEnumerable<T>.Print(delim: string := ' '): sequence of T;
function System.Collections.Generic.IEnumerable<T>.Print(delim: string): sequence of T;
begin
var g := Self.GetEnumerator();
if g.MoveNext() then
@ -3027,16 +3027,28 @@ begin
Result := Self;
end;
/// Âûâîäèò ïîñëåäîâàòåëüíîñòü íà ýêðàí, èñïîëüçóÿ ïðîáåë â êà÷åñòâå ðàçäåëèòåëÿ
function System.Collections.Generic.IEnumerable<T>.Print(): sequence of T;
begin
Result := Self.Print(' ');
end;
/// Выводит последовательность на экран, используя delim в качестве разделителя, и переходит на новую строку
function System.Collections.Generic.IEnumerable<T>.Println(delim: string := ' '): sequence of T;
function System.Collections.Generic.IEnumerable<T>.Println(delim: string): sequence of T;
begin
Self.Print(delim);
Writeln;
Result := Self;
end;
/// Âûâîäèò ïîñëåäîâàòåëüíîñòü íà ýêðàí, èñïîëüçóÿ ïðîáåë êà÷åñòâå ðàçäåëèòåëÿ, è ïåðåõîäèò íà íîâóþ ñòðîêó
function System.Collections.Generic.IEnumerable<T>.Println(): sequence of T;
begin
Result := Self.Println(' ');
end;
/// Преобразует элементы последовательности в строковое представление, после чего объединяет их в строку, используя delim в качестве разделителя
function System.Collections.Generic.IEnumerable<T>.JoinIntoString(delim: string := ' '): string;
function System.Collections.Generic.IEnumerable<T>.JoinIntoString(delim: string): string;
begin
var g := Self.GetEnumerator();
var sb := new System.Text.StringBuilder('');
@ -3047,6 +3059,12 @@ begin
Result := sb.ToString;
end;
/// Ïðåîáðàçóåò ýëåìåíòû ïîñëåäîâàòåëüíîñòè â ñòðîêîâîå ïðåäñòàâëåíèå, ïîñëå ÷åãî îáúåäèíÿåò èõ â ñòðîêó, èñïîëüçóÿ ïðîáåë â êà÷åñòâå ðàçäåëèòåëÿ
function System.Collections.Generic.IEnumerable<T>.JoinIntoString(): string;
begin
Result := Self.JoinIntoString(' ');
end;
/// Применяет действие к каждому элементу последовательности
procedure System.Collections.Generic.IEnumerable<T>.&ForEach(action: Action<T>);
begin