Skip to content

Commit

Permalink
implmenting caching of matching FunctionDefs in FunctionRef to improv…
Browse files Browse the repository at this point in the history
…e performance.
  • Loading branch information
rdingwell committed Oct 10, 2024
1 parent 94cea07 commit be9c71b
Showing 1 changed file with 26 additions and 9 deletions.
35 changes: 26 additions & 9 deletions src/elm/reusable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,27 +59,28 @@ export class FunctionDef extends Expression {
export class FunctionRef extends Expression {
name: string;
library: string;
functionDefs: FunctionDef[] | null;

constructor(json: any) {
super(json);
this.name = json.name;
this.library = json.libraryName;
this.functionDefs = null;
}

async exec(ctx: Context) {
getFunctionDefs(ctx: Context, args: any) {
if (this.functionDefs != null) {
// cache hit
return this.functionDefs;
}
let functionDefs, child_ctx;

Check failure on line 76 in src/elm/reusable.ts

View workflow job for this annotation

GitHub Actions / Check lint and prettier

'child_ctx' is defined but never used

Check failure on line 76 in src/elm/reusable.ts

View workflow job for this annotation

GitHub Actions / Check lint and prettier

'child_ctx' is defined but never used
if (this.library) {
const lib = ctx.get(this.library);
functionDefs = lib ? lib.getFunction(this.name) : undefined;
const libCtx = ctx.getLibraryContext(this.library);
child_ctx = libCtx ? libCtx.childContext() : undefined;
} else {
functionDefs = ctx.get(this.name);
child_ctx = ctx.childContext();
}
const args = await this.execArgs(ctx);

// Filter out functions w/ wrong number of arguments.
functionDefs = functionDefs.filter((f: any) => f.parameters.length === args.length);
// If there is still > 1 matching function, filter by argument types
if (functionDefs.length > 1) {
Expand All @@ -101,17 +102,33 @@ export class FunctionRef extends Expression {
return match;
});
}
this.functionDefs = functionDefs;
return functionDefs;
}

async exec(ctx: Context) {
const args = await this.execArgs(ctx);
// Filter out functions w/ wrong number of arguments.
const fDefs = this.getFunctionDefs(ctx, args);
// If there is still > 1 matching function, calculate a score based on quality of matches
if (functionDefs.length > 1) {
if (fDefs.length > 1) {
// TODO
}

if (functionDefs.length === 0) {
if (fDefs.length === 0) {
throw new Error('no function with matching signature could be found');
}

let child_ctx;
if (this.library) {
const libCtx = ctx.getLibraryContext(this.library);
child_ctx = libCtx ? libCtx.childContext() : undefined;
} else {
child_ctx = ctx.childContext();
}
// By this point, we should have only one function, but until implementation is completed,
// use the last one (no matter how many still remain)
const functionDef = functionDefs[functionDefs.length - 1];
const functionDef = fDefs[fDefs.length - 1];
for (let i = 0; i < functionDef.parameters.length; i++) {
child_ctx.set(functionDef.parameters[i].name, args[i]);
}
Expand Down

0 comments on commit be9c71b

Please sign in to comment.