hertzscript-dispatcher
Version:
Executes preemptible JavaScript coroutines which conform to the HertzScript specification.
39 lines • 1.78 kB
JavaScript
// Process Control Block
// Wraps a Function or GeneratorFunction, and stores metadata about it
function HzFunctor(symbols, functor, thisArg = null, args = [], isTailCall = false) {
this.symbols = symbols;
this.image = functor;
this.thisArg = thisArg;
this.args = args === null ? [] : args;
this.instance = null;
this.isTailCall = isTailCall;
if (symbols.conSym in functor) this.type = "constructor";
else if (symbols.genSym in functor) this.type = "generator";
else if (symbols.iterSym in functor) this.type = "iterator";
else if (symbols.crtSym in functor) this.type = "coroutine";
else this.type = "unknown";
}
HzFunctor.prototype.initFunctor = function (thisArg = null, args = []) {
if (thisArg === null && this.thisArg !== null) thisArg = this.thisArg;
if (args.length === 0 && this.args.length !== 0) args = this.args;
if (this.type !== "unknown" && this.symbols.tokenSym in this.image) {
return this.image[this.symbols.tokenSym].apply(thisArg, args);
}
return this.image.apply(thisArg, args);
};
HzFunctor.prototype.callFunctor = function (nextValue, thisArg = null) {
if (this.type === "unknown") return this.initFunctor(thisArg);
if (this.type === "generator") return this.initFunctor(thisArg);
if (this.type === "iterator") return this.initFunctor(thisArg, [nextValue]);
if (!(this.symbols.tokenSym in this.image)) return this.initFunctor(thisArg);
if (this.instance === null) this.instance = this.initFunctor(thisArg);
return this.instance.next(nextValue);
};
HzFunctor.prototype.throwIntoFunctor = function (error) {
if (this.instance !== null) return this.instance.throw(error);
else throw error;
};
HzFunctor.prototype.returnFromFunctor = function () {
if (this.instance !== null) this.instance.return();
};
module.exports = HzFunctor;