add callable closure vars

This commit is contained in:
LenAnderson
2024-04-02 08:48:41 -04:00
parent c2ddfdb85d
commit d826eb43d4
3 changed files with 120 additions and 63 deletions

View File

@ -1,4 +1,5 @@
import { substituteParams } from '../../script.js';
import { SlashCommandClosureExecutor } from './SlashCommandClosureExecutor.js';
import { SlashCommandClosureResult } from './SlashCommandClosureResult.js';
import { SlashCommandExecutor } from './SlashCommandExecutor.js';
import { SlashCommandScope } from './SlashCommandScope.js';
@ -10,7 +11,7 @@ export class SlashCommandClosure {
/**@type {Map<string,string|SlashCommandClosure>}*/ arguments = {};
// @ts-ignore
/**@type {Map<string,string|SlashCommandClosure>}*/ providedArguments = {};
/**@type {SlashCommandExecutor[]}*/ executorList = [];
/**@type {(SlashCommandExecutor|SlashCommandClosureExecutor)[]}*/ executorList = [];
/**@type {String}*/ keptText;
constructor(parent) {
@ -39,6 +40,10 @@ export class SlashCommandClosure {
return closure;
}
/**
*
* @returns Promise<SlashCommandClosureResult>
*/
async execute() {
const closure = this.getCopy();
return await closure.executeDirect();
@ -98,82 +103,94 @@ export class SlashCommandClosure {
}
for (const executor of this.executorList) {
interrupt = executor.command.interruptsGeneration;
let args = {
_scope: this.scope,
};
let value;
// substitute named arguments
for (const key of Object.keys(executor.args)) {
if (executor.args[key] instanceof SlashCommandClosure) {
if (executor instanceof SlashCommandClosureExecutor) {
const closure = this.scope.getVariable(executor.name);
if (!closure || !(closure instanceof SlashCommandClosure)) throw new Error(`${name} is not a closure.`);
closure.scope.parent = this.scope;
closure.providedArguments = executor.providedArguments;
const result = await closure.execute();
this.scope.pipe = result.pipe;
interrupt = result.interrupt;
} else {
interrupt = executor.command.interruptsGeneration;
let args = {
_scope: this.scope,
};
let value;
// substitute named arguments
for (const key of Object.keys(executor.args)) {
if (executor.args[key] instanceof SlashCommandClosure) {
/**@type {SlashCommandClosure}*/
const closure = executor.args[key];
closure.scope.parent = this.scope;
if (closure.executeNow) {
args[key] = (await closure.execute())?.pipe;
} else {
args[key] = closure;
}
} else {
args[key] = this.substituteParams(executor.args[key]);
}
// unescape named argument
if (typeof args[key] == 'string') {
args[key] = args[key]
?.replace(/\\\|/g, '|')
?.replace(/\\\{/g, '{')
?.replace(/\\\}/g, '}')
;
}
}
// substitute unnamed argument
if (executor.value === undefined) {
value = this.scope.pipe;
} else if (executor.value instanceof SlashCommandClosure) {
/**@type {SlashCommandClosure}*/
const closure = executor.args[key];
const closure = executor.value;
closure.scope.parent = this.scope;
if (closure.executeNow) {
args[key] = (await closure.execute())?.pipe;
value = (await closure.execute())?.pipe;
} else {
args[key] = closure;
value = closure;
}
} else if (Array.isArray(executor.value)) {
value = [];
for (let i = 0; i < executor.value.length; i++) {
let v = executor.value[i];
if (v instanceof SlashCommandClosure) {
/**@type {SlashCommandClosure}*/
const closure = v;
closure.scope.parent = this.scope;
if (closure.executeNow) {
v = (await closure.execute())?.pipe;
} else {
v = closure;
}
} else {
v = this.substituteParams(v);
}
value[i] = v;
}
if (!value.find(it=>it instanceof SlashCommandClosure)) {
value = value.join(' ');
}
} else {
args[key] = this.substituteParams(executor.args[key]);
value = this.substituteParams(executor.value);
}
// unescape named argument
if (typeof args[key] == 'string') {
args[key] = args[key]
// unescape unnamed argument
if (typeof value == 'string') {
value = value
?.replace(/\\\|/g, '|')
?.replace(/\\\{/g, '{')
?.replace(/\\\}/g, '}')
;
}
}
// substitute unnamed argument
if (executor.value === undefined) {
value = this.scope.pipe;
} else if (executor.value instanceof SlashCommandClosure) {
/**@type {SlashCommandClosure}*/
const closure = executor.value;
closure.scope.parent = this.scope;
if (closure.executeNow) {
value = (await closure.execute())?.pipe;
} else {
value = closure;
}
} else if (Array.isArray(executor.value)) {
value = [];
for (let i = 0; i < executor.value.length; i++) {
let v = executor.value[i];
if (v instanceof SlashCommandClosure) {
/**@type {SlashCommandClosure}*/
const closure = v;
closure.scope.parent = this.scope;
if (closure.executeNow) {
v = (await closure.execute())?.pipe;
} else {
v = closure;
}
} else {
v = this.substituteParams(v);
}
value[i] = v;
}
if (!value.find(it=>it instanceof SlashCommandClosure)) {
value = value.join(' ');
}
} else {
value = this.substituteParams(executor.value);
this.scope.pipe = await executor.command.callback(args, value);
}
// unescape unnamed argument
if (typeof value == 'string') {
value = value
?.replace(/\\\|/g, '|')
?.replace(/\\\{/g, '{')
?.replace(/\\\}/g, '}')
;
}
this.scope.pipe = await executor.command.callback(args, value);
}
return Object.assign(new SlashCommandClosureResult(), { interrupt, newText: this.keptText, pipe: this.scope.pipe });
/**@type {SlashCommandClosureResult} */
const result = Object.assign(new SlashCommandClosureResult(), { interrupt, newText: this.keptText, pipe: this.scope.pipe });
return result;
}
}