Правки в yield визиторах
This commit is contained in:
parent
4c4413073c
commit
735f692141
|
|
@ -15,7 +15,7 @@ internal static class RevisionClass
|
|||
public const string Major = "3";
|
||||
public const string Minor = "1";
|
||||
public const string Build = "0";
|
||||
public const string Revision = "1269";
|
||||
public const string Revision = "1270";
|
||||
|
||||
public const string MainVersion = Major + "." + Minor;
|
||||
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
%COREVERSION%=0
|
||||
%REVISION%=1269
|
||||
%MINOR%=1
|
||||
%REVISION%=1270
|
||||
%COREVERSION%=0
|
||||
%MAJOR%=3
|
||||
|
|
|
|||
|
|
@ -318,7 +318,7 @@
|
|||
</Node>
|
||||
</Items>
|
||||
</Node>
|
||||
<Node Name="QuestionPoint">
|
||||
<Node Name="QuestionPoint - незаконченное">
|
||||
<Items>
|
||||
<Node Name="visit(SyntaxTree.question_colon_expression">
|
||||
<FileName>\treeconverter\treeconversion\syntax_tree_visitor.cs</FileName>
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
!define VERSION '3.1.0.1269'
|
||||
!define VERSION '3.1.0.1270'
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/// Модуль электронного задачника Programming Taskbook 4
|
||||
unit PT4;
|
||||
unit PT4;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Модуль для подключения задачника Programming Taskbook
|
||||
|
|
|
|||
20
TestSuite/yield_capture_field_base_class.pas
Normal file
20
TestSuite/yield_capture_field_base_class.pas
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
type
|
||||
X = class
|
||||
v := 2;
|
||||
end;
|
||||
|
||||
var v := 666;
|
||||
|
||||
type
|
||||
A = class(X)
|
||||
function f: sequence of integer;
|
||||
begin
|
||||
var a := 1;
|
||||
yield a+v;
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
var a1 := new A;
|
||||
Assert(a1.f.Print.SequenceEqual(Seq(3)));
|
||||
end.
|
||||
|
|
@ -12,6 +12,16 @@ namespace SyntaxVisitors
|
|||
{
|
||||
public class AddBeginEndsVisitor : BaseChangeVisitor
|
||||
{
|
||||
public static AddBeginEndsVisitor New
|
||||
{
|
||||
get { return new AddBeginEndsVisitor(); }
|
||||
}
|
||||
|
||||
public static void Accept(procedure_definition pd)
|
||||
{
|
||||
New.ProcessNode(pd);
|
||||
}
|
||||
|
||||
public override void Exit(syntax_tree_node st)
|
||||
{
|
||||
var sts = st as statement;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,18 @@ namespace SyntaxVisitors
|
|||
{
|
||||
public class DeleteRedundantBeginEnds : BaseChangeVisitor
|
||||
{
|
||||
public static DeleteRedundantBeginEnds New
|
||||
{
|
||||
get { return new DeleteRedundantBeginEnds(); }
|
||||
}
|
||||
|
||||
public static DeleteRedundantBeginEnds Accept(procedure_definition pd)
|
||||
{
|
||||
var n = New;
|
||||
n.ProcessNode(pd);
|
||||
return n;
|
||||
}
|
||||
|
||||
public override void Exit(syntax_tree_node st)
|
||||
{
|
||||
var stl = st as statement_list;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ using PascalABCCompiler.SyntaxTree;
|
|||
|
||||
namespace SyntaxVisitors
|
||||
{
|
||||
public class DeleteAllLocalDefs : BaseChangeVisitor
|
||||
public class MoveAllLocalDefsToLists : BaseChangeVisitor
|
||||
{
|
||||
|
||||
private List<var_def_statement> LocalDeletedVD = new List<var_def_statement>(); // все локальные описания
|
||||
|
|
@ -28,10 +28,22 @@ namespace SyntaxVisitors
|
|||
}
|
||||
}
|
||||
|
||||
public DeleteAllLocalDefs() // надо запускать этот визитор начиная с корня подпрограммы
|
||||
public MoveAllLocalDefsToLists() // надо запускать этот визитор начиная с корня подпрограммы
|
||||
{
|
||||
}
|
||||
|
||||
public static MoveAllLocalDefsToLists New
|
||||
{
|
||||
get { return new MoveAllLocalDefsToLists(); }
|
||||
}
|
||||
|
||||
public static MoveAllLocalDefsToLists Accept(procedure_definition pd)
|
||||
{
|
||||
var n = New;
|
||||
n.ProcessNode(pd);
|
||||
return n;
|
||||
}
|
||||
|
||||
public override void visit(var_statement vs) // локальные описания внутри процедуры
|
||||
{
|
||||
LocalDeletedVS.Insert(0, vs.var_def);
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@ namespace SyntaxVisitors
|
|||
{
|
||||
public class LocalVariablesTypeDetectorHelperVisior : BaseChangeVisitor
|
||||
{
|
||||
public List<var_def_statement> LocalDeletedDefs = new List<var_def_statement>(); // все локальные описания
|
||||
public List<var_def_statement> LocalDeletedDefs = new List<var_def_statement>(); // variable_definitions - описания до начала блока
|
||||
|
||||
public List<var_def_statement> LocalDeletedVS = new List<var_def_statement>(); // var_statement's, потом объединим с LocalDeletedVD для верного порядка
|
||||
public List<var_def_statement> LocalDeletedVS = new List<var_def_statement>(); // var_statement's - внутриблочные описания
|
||||
|
||||
public LocalVariablesTypeDetectorHelperVisior()
|
||||
{
|
||||
|
|
@ -30,7 +30,7 @@ namespace SyntaxVisitors
|
|||
|
||||
LocalDeletedVS.Insert(0, vs.var_def);
|
||||
|
||||
ReplaceStatement(vs, new yield_var_def_statement_with_unknown_type(vs.var_def));
|
||||
//ReplaceStatement(vs, new yield_var_def_statement_with_unknown_type(vs.var_def));
|
||||
}
|
||||
|
||||
public override void visit(variable_definitions vd)
|
||||
|
|
@ -40,7 +40,7 @@ namespace SyntaxVisitors
|
|||
LocalDeletedDefs.Insert(0, v);
|
||||
}
|
||||
|
||||
Replace(vd, new yield_variable_definitions_with_unknown_type(vd));
|
||||
//Replace(vd, new yield_variable_definitions_with_unknown_type(vd));
|
||||
|
||||
// еще - не заходить в лямбды
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,8 +81,8 @@ namespace SyntaxVisitors
|
|||
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 // отображение для оберток локальных переменных
|
||||
IDictionary<string, string> formalParamsMap//, // отображение для захваченных имен формальных параметров
|
||||
//IDictionary<var_def_statement, var_def_statement> localsCloneMap // отображение для оберток локальных переменных
|
||||
)
|
||||
{
|
||||
var fh = (pd.proc_header as function_header);
|
||||
|
|
@ -104,7 +104,7 @@ namespace SyntaxVisitors
|
|||
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]), null);
|
||||
return new var_def_statement(ids, new yield_unknown_expression_type(vds), null); // SSM - убрал localsCloneMap[vds] - заменил на vds - не знаю, зачем вообще это отображение делалось - всё равно оно было тождественным!!!
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -606,7 +606,7 @@ namespace SyntaxVisitors
|
|||
/// </summary>
|
||||
/// <param className="pd">Объявление метода</param>
|
||||
/// <returns>Коллекция посещенных локальных переменных</returns>
|
||||
private void CreateLocalVariablesTypeProxies(procedure_definition pd, out IEnumerable<var_def_statement> localsClonesCollection)
|
||||
/*private void CreateLocalVariablesTypeProxies(procedure_definition pd, out IEnumerable<var_def_statement> localsClonesCollection)
|
||||
{
|
||||
// Выполняем определение типов локальных переменных с автовыводом типов
|
||||
|
||||
|
|
@ -631,8 +631,8 @@ namespace SyntaxVisitors
|
|||
// frninja 05/06/16 - фиксим source_context
|
||||
pd.proc_header.name.meth_name.source_context); // = new method_name("<yield_helper_locals_type_detector>" + pd.proc_header.className.meth_name.className);
|
||||
|
||||
//InsertHelperMethod(pd, pdCloned); // SSM 13.07.16 - вызов этого метода можно не добавлять
|
||||
}
|
||||
InsertHelperMethod(pd, pdCloned); // SSM 13.07.16 - вызов этого метода можно не добавлять
|
||||
}*/
|
||||
|
||||
/// <summary>
|
||||
/// Отображение локальных в клонированные локальные
|
||||
|
|
@ -640,7 +640,7 @@ namespace SyntaxVisitors
|
|||
/// <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)
|
||||
/*private Dictionary<var_def_statement, var_def_statement> CreateLocalsClonesMap(IEnumerable<var_def_statement> from, IEnumerable<var_def_statement> to)
|
||||
{
|
||||
// Нужно тк клонировали метод для создания хелпера-определителя типов локальных переменных - Eq не будет работать
|
||||
|
||||
|
|
@ -657,7 +657,7 @@ namespace SyntaxVisitors
|
|||
}
|
||||
|
||||
return localsClonesMap;
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
|
||||
|
|
@ -890,11 +890,12 @@ namespace SyntaxVisitors
|
|||
|
||||
|
||||
// frninja 05/06/16 - вставляем предописание если метод-итератор описан не в классе (обычная функция) чтоб работали рекурсивные вызовы
|
||||
// SSM - это приводит к ошибке в случае метода расширения. Простое решение - не вызывать это если это - метод расширения.
|
||||
// SSM - но лучше конечно выдавать более достойное сообщение об ошибке или решить эту проблему
|
||||
bool methodPredefCreated = InsertGlobalIteratorMethodPredefinition(pd);
|
||||
|
||||
// frninja 24/05/16 - оборачиваем одиночные операторы в begin..end
|
||||
AddBeginEndsVisitor addBeginEndsVis = new AddBeginEndsVisitor();
|
||||
pd.visit(addBeginEndsVis);
|
||||
AddBeginEndsVisitor.Accept(pd);
|
||||
|
||||
/*
|
||||
// Проверяем проблемы имен для for
|
||||
|
|
@ -908,35 +909,32 @@ namespace SyntaxVisitors
|
|||
pd.visit(checkVarRedefVisitor);
|
||||
*/
|
||||
|
||||
// Переименовываем одинаковые имена в мини-ПИ
|
||||
RenameSameBlockLocalVarsVisitor renameLocalsVisitor = new RenameSameBlockLocalVarsVisitor();
|
||||
pd.visit(renameLocalsVisitor);
|
||||
|
||||
ReplaceYieldWithLamdasVisitor replaceYieldWithLabdaVis = new ReplaceYieldWithLamdasVisitor();
|
||||
pd.visit(replaceYieldWithLabdaVis);
|
||||
|
||||
// frninja 31/05/16 - добавляем метод-хелпер, возьмет на себя проверку разных ошибок уже существующим бэкендом
|
||||
CreateErrorCheckerHelper(pd);
|
||||
CreateErrorCheckerHelper(pd); // SSM 14/07/16 - переставил до переименования переменных чтобы отлавливались ошибки одинаковых имен в разных пространствах имен
|
||||
// SSM - можно сделать спец визитор, который бы отлавливал дубли имен - тогда этого не надо
|
||||
|
||||
// Переименовываем одинаковые имена в мини-ПИ: begin var a := 1 end; begin var a := 1 end;
|
||||
RenameSameBlockLocalVarsVisitor.Accept(pd);
|
||||
|
||||
// Выносим выражение с лямбдой из yield
|
||||
ReplaceYieldWithLamdasVisitor.Accept(pd);
|
||||
|
||||
// Теперь lowering
|
||||
LoweringVisitor.Accept(pd);
|
||||
|
||||
// frninja 13/04/16 - убираем лишние begin..end
|
||||
DeleteRedundantBeginEnds deleteBeginEndVisitor = new DeleteRedundantBeginEnds();
|
||||
pd.visit(deleteBeginEndVisitor);
|
||||
DeleteRedundantBeginEnds.Accept(pd);
|
||||
|
||||
// Обработка метода для корректного захвата локальных переменных и их типов
|
||||
IEnumerable<var_def_statement> localsClonesCollection;
|
||||
CreateLocalVariablesTypeProxies(pd, out localsClonesCollection);
|
||||
|
||||
//IEnumerable<var_def_statement> localsClonesCollection;
|
||||
//CreateLocalVariablesTypeProxies(pd, out localsClonesCollection);
|
||||
|
||||
// frninja 16/11/15: перенес ниже чтобы работал захват для lowered for
|
||||
|
||||
var dld = new DeleteAllLocalDefs(); // mids.vars - все захваченные переменные
|
||||
pd.visit(dld); // Удалить в локальных и блочных описаниях этой процедуры все переменные и вынести их в отдельный список var_def_statement
|
||||
var dld = MoveAllLocalDefsToLists.Accept(pd); // Удалить в локальных и блочных описаниях этой процедуры все переменные и вынести их в отдельный список var_def_statement
|
||||
|
||||
// Строим отображение из локальных переменных клона оригинального метода в локальные переменные основного метода
|
||||
Dictionary<var_def_statement, var_def_statement> localsCloneMap = CreateLocalsClonesMap(dld.LocalDeletedDefs, localsClonesCollection);
|
||||
//Dictionary<var_def_statement, var_def_statement> localsCloneMap = CreateLocalsClonesMap(dld.LocalDeletedDefs, localsClonesCollection);
|
||||
|
||||
// frninja 08/12/15
|
||||
|
||||
|
|
@ -945,7 +943,6 @@ namespace SyntaxVisitors
|
|||
IDictionary<string, string> CapturedFormalParamsNamesMap;
|
||||
ReplaceCapturedVariables(pd, dld.LocalDeletedDefs, out CapturedLocalsNamesMap, out CapturedFormalParamsNamesMap);
|
||||
|
||||
|
||||
//mids.vars.Except(dld.LocalDeletedDefsNames); // параметры остались. Их тоже надо исключать - они и так будут обработаны
|
||||
// В результате работы в mids.vars что-то осталось. Это не локальные переменные и с ними непонятно что делать
|
||||
|
||||
|
|
@ -958,7 +955,7 @@ namespace SyntaxVisitors
|
|||
(pd.proc_body as block).program_code = cfa.res;
|
||||
|
||||
// Конструируем определение класса
|
||||
var cct = GenClassesForYield(pd, dld.LocalDeletedDefs, CapturedLocalsNamesMap, CapturedFormalParamsNamesMap, localsCloneMap); // все удаленные описания переменных делаем описанием класса
|
||||
var cct = GenClassesForYield(pd, dld.LocalDeletedDefs, CapturedLocalsNamesMap, CapturedFormalParamsNamesMap/*, localsCloneMap*/); // все удаленные описания переменных делаем описанием класса
|
||||
|
||||
// Вставляем классы-хелперы
|
||||
InsertYieldHelpers(pd, cct);
|
||||
|
|
|
|||
|
|
@ -28,6 +28,16 @@ namespace SyntaxVisitors
|
|||
this.BlockNamesCounter = new Dictionary<string, int>();
|
||||
}
|
||||
|
||||
public static RenameSameBlockLocalVarsVisitor New
|
||||
{
|
||||
get { return new RenameSameBlockLocalVarsVisitor(); }
|
||||
}
|
||||
|
||||
public static void Accept(procedure_definition pd)
|
||||
{
|
||||
New.ProcessNode(pd);
|
||||
}
|
||||
|
||||
public override void visit(declarations decls)
|
||||
{
|
||||
// Для обхода в правильном порядке сверху вниз
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ namespace SyntaxVisitors
|
|||
// frninja 12/05/16 - фикс для yield_unknown_ident
|
||||
public override void visit(yield_unknown_ident unk)
|
||||
{
|
||||
yield_var_def_statement_with_unknown_type x;
|
||||
//yield_var_def_statement_with_unknown_type x;
|
||||
// Empty
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,16 @@ namespace SyntaxVisitors
|
|||
return new ident("$lambdaVar$" + _lambdaNum);
|
||||
}
|
||||
|
||||
public static ReplaceYieldWithLamdasVisitor New
|
||||
{
|
||||
get { return new ReplaceYieldWithLamdasVisitor(); }
|
||||
}
|
||||
|
||||
public static void Accept(procedure_definition pd)
|
||||
{
|
||||
New.ProcessNode(pd);
|
||||
}
|
||||
|
||||
public override void visit(yield_node yn)
|
||||
{
|
||||
var lambdaSearcher = new TreeConverter.LambdaExpressions.LambdaSearcher(yn);
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ namespace YieldDesugarSyntaxTreeConverter
|
|||
root.visit(new ProcessYieldCapturedVarsVisitor());
|
||||
|
||||
#if DEBUG
|
||||
//root.visit(new SimplePrettyPrinterVisitor(@"d:\zzz.txt"));
|
||||
root.visit(new SimplePrettyPrinterVisitor(@"d:\zzz.txt"));
|
||||
#endif
|
||||
|
||||
return root;
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Reference in a new issue