88 lines
3.5 KiB
C#
88 lines
3.5 KiB
C#
|
|
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 MoveAllLocalDefsToLists : 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>(); // SSM - не очень понимаю, зачем хранить строки, identы и
|
|||
|
|
|
|||
|
|
public IEnumerable<var_def_statement> LocalDeletedDefs
|
|||
|
|
{
|
|||
|
|
get
|
|||
|
|
{
|
|||
|
|
return new List<var_def_statement>(LocalDeletedVD.Union(LocalDeletedVS));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
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);
|
|||
|
|
//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) // описания до begin
|
|||
|
|
{
|
|||
|
|
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))));
|
|||
|
|
|
|||
|
|
// еще - не заходить в лямбды
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|