pascalabcnet/SyntaxVisitors/YieldVisitors/CapturedLambdaInYieldVisitor.cs
Александр Земляк 1f4b44c2c0
Исправление ошибок при перекомпиляции pcu файлов (#3398)
* Move yield string constants to StringConstants class

* Add GeneratedNamesManager class to store all generated names during unit compilation

* Make GeneratedNamesManager class non static

* Add Utils project to installer files

* Add GeneratedNamesManager usage in CapturedVariablesSubstitutionsManager

* Move GeneratedNamesManager initialization in CompilationUnit constructor

* More GeneratedNamesManager usage

* QuestionPointDesugarVisitor fix
2026-03-08 18:30:33 +03:00

70 lines
2.4 KiB
C#

// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System.Collections.Generic;
using PascalABCCompiler.CoreUtils;
using PascalABCCompiler.SyntaxTree;
namespace SyntaxVisitors
{
public class CapturedLambdaInYieldVisitor : BaseChangeVisitor
{
private readonly GeneratedNamesManager generatedNamesManager;
private CapturedLambdaInYieldVisitor(GeneratedNamesManager generatedNamesManager)
{
this.generatedNamesManager = generatedNamesManager;
}
public static CapturedLambdaInYieldVisitor Create(GeneratedNamesManager generatedNamesManager) => new CapturedLambdaInYieldVisitor(generatedNamesManager);
public static void Accept(procedure_definition pd, GeneratedNamesManager generatedNamesManager)
{
Create(generatedNamesManager).ProcessNode(pd);
}
private string CreateNameForLambdaInYield()
{
return generatedNamesManager.GenerateName("@RenLamInYield", "$");
}
public override void visit(yield_node yn)
{
if (yn.ex is function_lambda_definition)
{
syntax_tree_node sn = yn;
do
{
sn = sn.Parent;
} while (sn != null && !(sn is procedure_definition));
procedure_definition pd = sn as procedure_definition;
if (sn == null)
{
// этого не будет
}
var fh = pd.proc_header as function_header;
if (fh == null)
{
// этого тоже не будет
}
var sq = fh.return_type as sequence_type;
if (sq == null)
{
// и этого не будет
}
var lst = new List<statement>();
var newid = new ident(CreateNameForLambdaInYield(), yn.ex.source_context);
var vs = new var_statement(newid, sq.elements_type, yn.ex);
vs.source_context = yn.ex.source_context;
var newyn = new yield_node(newid, newid.source_context);
lst.Add(vs);
lst.Add(newyn);
ReplaceStatementUsingParent(yn, lst);
}
}
}
}