diff --git a/packages/safe-ds-lang/src/language/generation/python/safe-ds-python-generator.ts b/packages/safe-ds-lang/src/language/generation/python/safe-ds-python-generator.ts index a93a849c7..6d979c703 100644 --- a/packages/safe-ds-lang/src/language/generation/python/safe-ds-python-generator.ts +++ b/packages/safe-ds-lang/src/language/generation/python/safe-ds-python-generator.ts @@ -604,10 +604,12 @@ export class SafeDsPythonGenerator { private generateExpressionLambda(node: SdsExpressionLambda, frame: GenerationInfoFrame): Generated { const name = frame.getUniqueLambdaName(node); const parameters = this.generateParameters(node.parameterList, frame); - const result = this.generateExpression(node.result, frame); + const lambdaFrame = frame.newScope(); + const result = this.generateExpression(node.result, lambdaFrame); const extraStatement = expandTracedToNode(node)` def ${name}(${parameters}): + ${joinToNode(lambdaFrame.getExtraStatements())} return ${result} `; frame.addExtraStatement(node, extraStatement); @@ -1204,8 +1206,9 @@ class GenerationInfoFrame { insidePipeline: boolean = false, targetPlaceholders: string[] | undefined = undefined, disableRunnerIntegration: boolean = false, + idManager: IdManager = new IdManager(), ) { - this.idManager = new IdManager(); + this.idManager = idManager; this.importSet = importSet; this.utilitySet = utilitySet; this.typeVariableSet = typeVariableSet; @@ -1262,6 +1265,18 @@ class GenerationInfoFrame { getUniqueReceiverName(receiver: SdsExpression): string { return `${RECEIVER_PREFIX}${this.idManager.assignId(receiver)}`; } + + newScope(): GenerationInfoFrame { + return new GenerationInfoFrame( + this.importSet, + this.utilitySet, + this.typeVariableSet, + this.isInsidePipeline, + this.targetPlaceholders, + this.disableRunnerIntegration, + this.idManager, + ); + } } export interface GenerateOptions { diff --git a/packages/safe-ds-lang/tests/resources/generation/python/runner integration/expressions/block lambdas/generated/tests/generation/python/runnerIntegration/blockLambdas/gen_input.py b/packages/safe-ds-lang/tests/resources/generation/python/runner integration/expressions/block lambdas/generated/tests/generation/python/runnerIntegration/blockLambdas/gen_input.py new file mode 100644 index 000000000..f6e6c26ee --- /dev/null +++ b/packages/safe-ds-lang/tests/resources/generation/python/runner integration/expressions/block lambdas/generated/tests/generation/python/runnerIntegration/blockLambdas/gen_input.py @@ -0,0 +1,26 @@ +# Imports ---------------------------------------------------------------------- + +import safeds_runner +from tests.generation.python.runnerIntegration.blockLambdas import f + +# Pipelines -------------------------------------------------------------------- + +def myPipeline(): + def __gen_lambda_1(p): + __gen_receiver_0 = p + __gen_block_lambda_result_r = safeds_runner.memoized_dynamic_call( + __gen_receiver_0, + "g", + [], + {}, + [] + ) + return __gen_block_lambda_result_r + __gen_result = safeds_runner.memoized_static_call( + "tests.generation.python.runnerIntegration.blockLambdas.f", + f, + [__gen_lambda_1], + {}, + [] + ) + safeds_runner.save_placeholder('result', __gen_result) diff --git a/packages/safe-ds-lang/tests/resources/generation/python/runner integration/expressions/block lambdas/generated/tests/generation/python/runnerIntegration/blockLambdas/gen_input.py.map b/packages/safe-ds-lang/tests/resources/generation/python/runner integration/expressions/block lambdas/generated/tests/generation/python/runnerIntegration/blockLambdas/gen_input.py.map new file mode 100644 index 000000000..95354d311 --- /dev/null +++ b/packages/safe-ds-lang/tests/resources/generation/python/runner integration/expressions/block lambdas/generated/tests/generation/python/runnerIntegration/blockLambdas/gen_input.py.map @@ -0,0 +1 @@ +{"version":3,"sources":["input.sdsdev"],"names":["mypipeline","p","r","f"],"mappings":"AAEA;;;;;;;AAYA,IAASA,UAAU;IAEX,mBAACC,CAAC;QACYA,mBAAAA,CAAC;QAAX,0BAAMC,CAAC,GAAG;;;;;;;QADd,OACI,0BAAMA,CAAC;IAFf,eAAa;;QAAAC,CAAC;SACV;;;;IADJ","file":"gen_input.py"} \ No newline at end of file diff --git a/packages/safe-ds-lang/tests/resources/generation/python/runner integration/expressions/block lambdas/generated/tests/generation/python/runnerIntegration/blockLambdas/gen_input_myPipeline.py b/packages/safe-ds-lang/tests/resources/generation/python/runner integration/expressions/block lambdas/generated/tests/generation/python/runnerIntegration/blockLambdas/gen_input_myPipeline.py new file mode 100644 index 000000000..beb776a1f --- /dev/null +++ b/packages/safe-ds-lang/tests/resources/generation/python/runner integration/expressions/block lambdas/generated/tests/generation/python/runnerIntegration/blockLambdas/gen_input_myPipeline.py @@ -0,0 +1,4 @@ +from .gen_input import myPipeline + +if __name__ == '__main__': + myPipeline() diff --git a/packages/safe-ds-lang/tests/resources/generation/python/runner integration/expressions/block lambdas/input.sdsdev b/packages/safe-ds-lang/tests/resources/generation/python/runner integration/expressions/block lambdas/input.sdsdev new file mode 100644 index 000000000..a238b88ae --- /dev/null +++ b/packages/safe-ds-lang/tests/resources/generation/python/runner integration/expressions/block lambdas/input.sdsdev @@ -0,0 +1,21 @@ +// Related to https://github.com/Safe-DS/DSL/issues/1136 + +package tests.generation.python.runnerIntegration.blockLambdas + +class MyClass { + @Pure + fun g() -> r: Int +} + +@Pure +fun f( + callback: (p: MyClass) -> (r: Int) +) -> result: Any + +pipeline myPipeline { + val result = f( + (p) { + yield r = p.g(); + } + ); +} diff --git a/packages/safe-ds-lang/tests/resources/generation/python/runner integration/expressions/expression lambdas/generated/tests/generation/python/runnerIntegration/expressionLambdas/gen_input.py b/packages/safe-ds-lang/tests/resources/generation/python/runner integration/expressions/expression lambdas/generated/tests/generation/python/runnerIntegration/expressionLambdas/gen_input.py new file mode 100644 index 000000000..b76113684 --- /dev/null +++ b/packages/safe-ds-lang/tests/resources/generation/python/runner integration/expressions/expression lambdas/generated/tests/generation/python/runnerIntegration/expressionLambdas/gen_input.py @@ -0,0 +1,25 @@ +# Imports ---------------------------------------------------------------------- + +import safeds_runner +from tests.generation.python.runnerIntegration.expressionLambdas import f + +# Pipelines -------------------------------------------------------------------- + +def myPipeline(): + def __gen_lambda_0(p): + __gen_receiver_1 = p + return safeds_runner.memoized_dynamic_call( + __gen_receiver_1, + "g", + [], + {}, + [] + ) + __gen_result = safeds_runner.memoized_static_call( + "tests.generation.python.runnerIntegration.expressionLambdas.f", + f, + [__gen_lambda_0], + {}, + [] + ) + safeds_runner.save_placeholder('result', __gen_result) diff --git a/packages/safe-ds-lang/tests/resources/generation/python/runner integration/expressions/expression lambdas/generated/tests/generation/python/runnerIntegration/expressionLambdas/gen_input.py.map b/packages/safe-ds-lang/tests/resources/generation/python/runner integration/expressions/expression lambdas/generated/tests/generation/python/runnerIntegration/expressionLambdas/gen_input.py.map new file mode 100644 index 000000000..b002d235c --- /dev/null +++ b/packages/safe-ds-lang/tests/resources/generation/python/runner integration/expressions/expression lambdas/generated/tests/generation/python/runnerIntegration/expressionLambdas/gen_input.py.map @@ -0,0 +1 @@ +{"version":3,"sources":["input.sdsdev"],"names":["mypipeline","p","f"],"mappings":"AAEA;;;;;;;AAYA,IAASA,UAAU;IAEX,mBAACC,CAAC;QAAKA,mBAAAA,CAAC;eAAD;;;;;;;IADX,eAAa;;QAAAC,CAAC;SACV;;;;IADJ","file":"gen_input.py"} \ No newline at end of file diff --git a/packages/safe-ds-lang/tests/resources/generation/python/runner integration/expressions/expression lambdas/generated/tests/generation/python/runnerIntegration/expressionLambdas/gen_input_myPipeline.py b/packages/safe-ds-lang/tests/resources/generation/python/runner integration/expressions/expression lambdas/generated/tests/generation/python/runnerIntegration/expressionLambdas/gen_input_myPipeline.py new file mode 100644 index 000000000..beb776a1f --- /dev/null +++ b/packages/safe-ds-lang/tests/resources/generation/python/runner integration/expressions/expression lambdas/generated/tests/generation/python/runnerIntegration/expressionLambdas/gen_input_myPipeline.py @@ -0,0 +1,4 @@ +from .gen_input import myPipeline + +if __name__ == '__main__': + myPipeline() diff --git a/packages/safe-ds-lang/tests/resources/generation/python/runner integration/expressions/expression lambdas/input.sdsdev b/packages/safe-ds-lang/tests/resources/generation/python/runner integration/expressions/expression lambdas/input.sdsdev new file mode 100644 index 000000000..20ae0e6c5 --- /dev/null +++ b/packages/safe-ds-lang/tests/resources/generation/python/runner integration/expressions/expression lambdas/input.sdsdev @@ -0,0 +1,19 @@ +// Related to https://github.com/Safe-DS/DSL/issues/1136 + +package tests.generation.python.runnerIntegration.expressionLambdas + +class MyClass { + @Pure + fun g() -> r: Int +} + +@Pure +fun f( + callback: (p: MyClass) -> (r: Int) +) -> result: Any + +pipeline myPipeline { + val result = f( + (p) -> p.g() + ); +}