Обновлен проект с визиторами.
Исправлен ToString в write. Убраны параметры по умолчанию из метода расширения Print (пока это вызывает падение)
This commit is contained in:
parent
50a7481a1b
commit
1fccb1e103
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
%MINOR%=2
|
||||
%REVISION%=999
|
||||
%REVISION%=1001
|
||||
%MAJOR%=2
|
||||
%COREVERSION%=0
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
!define VERSION '2.2.0.999'
|
||||
!define VERSION '2.2.0.1001'
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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>();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ using PascalABCCompiler.SyntaxTree;
|
|||
|
||||
namespace ParsePABC1
|
||||
{
|
||||
class BaseEnterExitVisitor: WalkingVisitor
|
||||
class BaseEnterExitVisitor: WalkingVisitorNew
|
||||
{
|
||||
public BaseEnterExitVisitor()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ using PascalABCCompiler.SyntaxTree;
|
|||
|
||||
namespace ParsePABC1
|
||||
{
|
||||
class SimplePrettyPrinterVisitor: WalkingVisitor
|
||||
class SimplePrettyPrinterVisitor: WalkingVisitorNew
|
||||
{
|
||||
int off = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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.
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue