diff --git a/TestSuite/nested_lambdas_10.pas b/TestSuite/nested_lambdas_10.pas new file mode 100644 index 000000000..d211fbd7d --- /dev/null +++ b/TestSuite/nested_lambdas_10.pas @@ -0,0 +1,7 @@ +begin + var l := Range(2,1000).Where(x->Range(2,Round(sqrt(x))).All(i->x mod i <> 0)).ToList(); + assert(l.Count = 168); + assert(l.Contains(3)); + assert(l.Contains(7)); + assert(l.Contains(11)); +end. \ No newline at end of file diff --git a/TreeConverter/LambdaExpressions/Closure/CapturedVariablesSubstitutionClassGenerator.cs b/TreeConverter/LambdaExpressions/Closure/CapturedVariablesSubstitutionClassGenerator.cs index d05474013..814421da5 100644 --- a/TreeConverter/LambdaExpressions/Closure/CapturedVariablesSubstitutionClassGenerator.cs +++ b/TreeConverter/LambdaExpressions/Closure/CapturedVariablesSubstitutionClassGenerator.cs @@ -573,7 +573,21 @@ private void AddReferencesToIdentInLambda(type_declaration upperScopeWhereVarsAr dot_node substDotNode1; if (!nestedLambda) { - substDotNode1 = new dot_node(new ident(_capturedVarsClassDefs[scopeAsLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod.Value].GeneratedUpperClassFieldName), new ident(varName)); + var parts = new Stack(); + var dn = substDotNode; + parts.Push((ident)dn.right); + + while (!(dn.left is ident && dn.right is ident)) + { + dn = (dot_node)dn.left; + parts.Push((ident)dn.right); + } + + substDotNode1 = new dot_node(new ident(_capturedVarsClassDefs[scopeAsLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod.Value].GeneratedUpperClassFieldName), parts.Pop()); + while (parts.Count > 0) + { + substDotNode1 = new dot_node(substDotNode1, parts.Pop()); + } } else { @@ -593,7 +607,7 @@ private void AddReferencesToIdentInLambda(type_declaration upperScopeWhereVarsAr while (parts.Count > 0) { - substDotNode1 = new dot_node(substDotNode, parts.Pop()); + substDotNode1 = new dot_node(substDotNode1, parts.Pop()); } } diff --git a/TreeConverter/LambdaExpressions/Closure/CapturedVariablesTreeBuilder.cs b/TreeConverter/LambdaExpressions/Closure/CapturedVariablesTreeBuilder.cs index 2419aa7ca..daf0bdec3 100644 --- a/TreeConverter/LambdaExpressions/Closure/CapturedVariablesTreeBuilder.cs +++ b/TreeConverter/LambdaExpressions/Closure/CapturedVariablesTreeBuilder.cs @@ -551,6 +551,28 @@ public override void visit(PascalABCCompiler.SyntaxTree.for_node _for_node) public override void visit(function_lambda_definition lambdaDefinition) { + if (lambdaDefinition.formal_parameters != null && lambdaDefinition.formal_parameters.params_list != null && lambdaDefinition.formal_parameters.params_list.Count != 0) + { + var varDefsList = new List(); + for (var i = 0; i < lambdaDefinition.formal_parameters.params_list.Count; i++) + { + var varType = lambdaDefinition.formal_parameters.params_list[i].vars_type is lambda_inferred_type ? + LambdaHelper.ConvertSemanticTypeToSyntaxType((type_node)((lambda_inferred_type)lambdaDefinition.formal_parameters.params_list[i].vars_type).real_type) : + lambdaDefinition.formal_parameters.params_list[i].vars_type; + + for (var j = 0; j < lambdaDefinition.formal_parameters.params_list[i].idents.idents.Count; j++) + { + var varName = "<>" + lambdaDefinition.formal_parameters.params_list[i].idents.idents[j].name; + var vds = new var_def_statement(new ident(lambdaDefinition.formal_parameters.params_list[i].idents.idents[j].name), varType); + vds.inital_value = new ident(varName); + lambdaDefinition.formal_parameters.params_list[i].idents.idents[j].name = varName; + varDefsList.Add(new var_statement(vds)); + } + } + + ((statement_list)lambdaDefinition.proc_body).subnodes.InsertRange(0, varDefsList); + } + var procDecl = LambdaHelper.ConvertLambdaNodeToProcDefNode(lambdaDefinition); _visitor.body_exists = true; _visitor.hard_node_test_and_visit(procDecl.proc_header);