Skip to content

Commit c40347c

Browse files
authored
feat: partially evaluate lambdas and segments (#734)
Closes partially #603 ### Summary of Changes Partially evaluate lambdas and segments.
1 parent 8d59607 commit c40347c

File tree

7 files changed

+132
-117
lines changed

7 files changed

+132
-117
lines changed

packages/safe-ds-lang/src/language/partialEvaluation/model.ts

+36-33
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
1-
import { stream } from 'langium';
1+
import { type NamedAstNode, stream } from 'langium';
22
import { isEmpty } from '../../helpers/collectionUtils.js';
33
import {
44
isSdsAbstractResult,
5-
SdsAbstractResult,
6-
SdsBlockLambdaResult,
5+
type SdsAbstractResult,
6+
type SdsBlockLambda,
7+
type SdsBlockLambdaResult,
8+
type SdsCallable,
79
type SdsDeclaration,
8-
SdsEnumVariant,
9-
SdsExpression,
10-
SdsParameter,
11-
SdsReference,
12-
SdsResult,
10+
type SdsEnumVariant,
11+
type SdsExpression,
12+
type SdsExpressionLambda,
13+
type SdsLambda,
14+
type SdsParameter,
15+
type SdsReference,
1316
} from '../generated/ast.js';
14-
import { getParameters } from '../helpers/nodeProperties.js';
17+
import { getParameters, streamBlockLambdaResults } from '../helpers/nodeProperties.js';
1518

1619
export type ParameterSubstitutions = Map<SdsParameter, EvaluatedNode>;
1720
export type ResultSubstitutions = Map<SdsAbstractResult, EvaluatedNode>;
@@ -139,20 +142,27 @@ export const isConstant = (node: EvaluatedNode): node is Constant => {
139142
};
140143

141144
// -------------------------------------------------------------------------------------------------
142-
// Closures
145+
// Callables
143146
// -------------------------------------------------------------------------------------------------
144147

145-
export abstract class Closure extends EvaluatedNode {
148+
export abstract class EvaluatedCallable<T extends SdsCallable> extends EvaluatedNode {
149+
abstract readonly callable: T;
146150
override readonly isFullyEvaluated: boolean = false;
151+
}
152+
153+
export abstract class Closure<T extends SdsLambda> extends EvaluatedCallable<T> {
147154
abstract readonly substitutionsOnCreation: ParameterSubstitutions;
148155
}
149156

150-
export class BlockLambdaClosure extends Closure {
157+
export class BlockLambdaClosure extends Closure<SdsBlockLambda> {
158+
readonly results: SdsBlockLambdaResult[];
159+
151160
constructor(
161+
override readonly callable: SdsBlockLambda,
152162
override readonly substitutionsOnCreation: ParameterSubstitutions,
153-
readonly results: SdsBlockLambdaResult[],
154163
) {
155164
super();
165+
this.results = streamBlockLambdaResults(callable).toArray();
156166
}
157167

158168
override equals(other: unknown): boolean {
@@ -163,9 +173,8 @@ export class BlockLambdaClosure extends Closure {
163173
}
164174

165175
return (
166-
this.results.length === other.results.length &&
167-
substitutionsAreEqual(this.substitutionsOnCreation, other.substitutionsOnCreation) &&
168-
this.results.every((thisResult, i) => thisResult === other.results[i])
176+
this.callable === other.callable &&
177+
substitutionsAreEqual(this.substitutionsOnCreation, other.substitutionsOnCreation)
169178
);
170179
}
171180

@@ -174,12 +183,15 @@ export class BlockLambdaClosure extends Closure {
174183
}
175184
}
176185

177-
export class ExpressionLambdaClosure extends Closure {
186+
export class ExpressionLambdaClosure extends Closure<SdsExpressionLambda> {
187+
readonly result: SdsExpression;
188+
178189
constructor(
190+
override readonly callable: SdsExpressionLambda,
179191
override readonly substitutionsOnCreation: ParameterSubstitutions,
180-
readonly result: SdsExpression,
181192
) {
182193
super();
194+
this.result = callable.result;
183195
}
184196

185197
override equals(other: unknown): boolean {
@@ -190,7 +202,7 @@ export class ExpressionLambdaClosure extends Closure {
190202
}
191203

192204
return (
193-
this.result === other.result &&
205+
this.callable === other.callable &&
194206
substitutionsAreEqual(this.substitutionsOnCreation, other.substitutionsOnCreation)
195207
);
196208
}
@@ -200,28 +212,19 @@ export class ExpressionLambdaClosure extends Closure {
200212
}
201213
}
202214

203-
export class SegmentClosure extends Closure {
204-
override readonly substitutionsOnCreation = new Map<SdsParameter, EvaluatedNode>();
215+
export class NamedCallable<T extends SdsCallable & NamedAstNode> extends EvaluatedCallable<T> {
216+
override readonly isFullyEvaluated: boolean = false;
205217

206-
constructor(readonly results: SdsResult[]) {
218+
constructor(override readonly callable: T) {
207219
super();
208220
}
209221

210222
override equals(other: unknown): boolean {
211-
if (other === this) {
212-
return true;
213-
} else if (!(other instanceof SegmentClosure)) {
214-
return false;
215-
}
216-
217-
return (
218-
this.results.length === other.results.length &&
219-
this.results.every((thisResult, i) => thisResult === other.results[i])
220-
);
223+
return other instanceof NamedCallable && this.callable === other.callable;
221224
}
222225

223226
override toString(): string {
224-
return `$SegmentClosure`;
227+
return this.callable.name;
225228
}
226229
}
227230

0 commit comments

Comments
 (0)