2020-06-21 21:46:50 +03:00
|
|
|
|
// 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;
|
2026-03-08 18:30:33 +03:00
|
|
|
|
using PascalABCCompiler.CoreUtils;
|
2020-06-21 21:46:50 +03:00
|
|
|
|
using PascalABCCompiler.SyntaxTree;
|
|
|
|
|
|
|
|
|
|
|
|
namespace SyntaxVisitors
|
|
|
|
|
|
{
|
|
|
|
|
|
public class CapturedLambdaInYieldVisitor : BaseChangeVisitor
|
|
|
|
|
|
{
|
2026-03-08 18:30:33 +03:00
|
|
|
|
private readonly GeneratedNamesManager generatedNamesManager;
|
2020-06-21 21:46:50 +03:00
|
|
|
|
|
2026-03-08 18:30:33 +03:00
|
|
|
|
private CapturedLambdaInYieldVisitor(GeneratedNamesManager generatedNamesManager)
|
2020-06-21 21:46:50 +03:00
|
|
|
|
{
|
2026-03-08 18:30:33 +03:00
|
|
|
|
this.generatedNamesManager = generatedNamesManager;
|
2020-06-21 21:46:50 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-08 18:30:33 +03:00
|
|
|
|
public static CapturedLambdaInYieldVisitor Create(GeneratedNamesManager generatedNamesManager) => new CapturedLambdaInYieldVisitor(generatedNamesManager);
|
2020-06-21 21:46:50 +03:00
|
|
|
|
|
2026-03-08 18:30:33 +03:00
|
|
|
|
public static void Accept(procedure_definition pd, GeneratedNamesManager generatedNamesManager)
|
2020-06-21 21:46:50 +03:00
|
|
|
|
{
|
2026-03-08 18:30:33 +03:00
|
|
|
|
Create(generatedNamesManager).ProcessNode(pd);
|
2020-06-21 21:46:50 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-08 18:30:33 +03:00
|
|
|
|
private string CreateNameForLambdaInYield()
|
2020-06-21 21:46:50 +03:00
|
|
|
|
{
|
2026-03-08 18:30:33 +03:00
|
|
|
|
return generatedNamesManager.GenerateName("@RenLamInYield", "$");
|
2020-06-21 21:46:50 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|