This commit is contained in:
Mikhalkovich Stanislav 2021-01-28 16:12:00 +03:00
parent ac1de524b4
commit ee27ca7136
9 changed files with 63 additions and 7 deletions

View file

@ -15,7 +15,7 @@ internal static class RevisionClass
public const string Major = "3";
public const string Minor = "7";
public const string Build = "2";
public const string Revision = "2814";
public const string Revision = "2818";
public const string MainVersion = Major + "." + Minor;
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;

View file

@ -1,4 +1,4 @@
%COREVERSION%=2
%REVISION%=2814
%REVISION%=2818
%MINOR%=7
%MAJOR%=3

Binary file not shown.

View file

@ -1 +1 @@
3.7.2.2814
3.7.2.2818

View file

@ -1 +1 @@
!define VERSION '3.7.2.2814'
!define VERSION '3.7.2.2818'

View file

@ -0,0 +1,4 @@
begin
var b := Arr(0, 1);
Assert(b.SelectMany(x -> b.SelectMany(y -> b.Select(z -> y).Select(w -> 1))).SequenceEqual(Arr(1)*8));
end.

View file

@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PascalABCCompiler.SyntaxTree;
namespace PascalABCCompiler.TreeConverter
{
public class HasCapturedLambdaParameterInInternalLambdaBody : BaseEnterExitVisitor
{
public bool HasCapturedParameter = false;
public List<ident> idents = new List<ident>();
public bool InLambda = false;
public HasCapturedLambdaParameterInInternalLambdaBody(function_lambda_definition fld)
{
idents = fld.ident_list.idents;
}
public static HasCapturedLambdaParameterInInternalLambdaBody New(function_lambda_definition fld)
{
return new HasCapturedLambdaParameterInInternalLambdaBody(fld);
}
public override void visit(var_def_statement vds)
{
//ProcessNode(vds.vars_type);
}
public override void visit(ident id)
{
if (!InLambda) // мы ищем только в лямбдах
return;
if (HasCapturedParameter)
return;
if (idents.Select(i => i.name).Contains(id.name,StringComparer.OrdinalIgnoreCase))
{
HasCapturedParameter = true;
}
}
public override void visit(function_lambda_definition fld)
{
InLambda = true;
ProcessNode(fld.proc_body);
}
}
}

View file

@ -20027,9 +20027,14 @@ namespace PascalABCCompiler.TreeConverter
int err_cnt = ErrorsList.Count;
try
{
expression_node yyy;
if (ff.parameters.expressions.Count > 0)
yyy = convert_strong(ff.parameters.expressions[0]);
// Видимо, дело только в лямбде. Попробовать всё обойти и найти захваченные параметры
// Если они есть, то ничего не делать и выйти
var vis = HasCapturedLambdaParameterInInternalLambdaBody.New(_function_lambda_definition);
vis.ProcessNode(ff.dereferencing_value);
if (vis.HasCapturedParameter) // SSM 28/01/2021 считать это функцией. Будет слабый вывод в редком числе случаев
return;
qq = convert_strong(ff.dereferencing_value);
if (qq is exit_procedure && stl.list.Count == 1 || qq is local_block_variable_reference && qq.type is compiled_type_node && (qq.type as compiled_type_node).compiled_type == typeof(Action))
{

View file

@ -110,6 +110,7 @@
<Compile Include="LambdaExpressions\LambdaProcessingState.cs" />
<Compile Include="LambdaExpressions\LambdaResultTypeInferrer.cs" />
<Compile Include="LambdaExpressions\LambdaSearcher.cs" />
<Compile Include="TreeConversion\HasCapturedLambdaParameterInInternalLambdaBody.cs" />
<Compile Include="TreeConversion\LambdaHelper.cs" />
<Compile Include="SymbolTable\DSST\AreaArrayTable.cs">
<SubType>Code</SubType>