js-slang
Version:
Javascript-based implementations of Source, written in Typescript
115 lines • 3.45 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.makeDummyContCallExpression = exports.Continuation = exports.isCallWithCurrentContinuation = exports.call_with_current_continuation = exports.Call_cc = exports.isApply = exports.apply = exports.Apply = void 0;
const utils_1 = require("./utils");
/**
* A dummy function used to detect for the apply function object.
* If the interpreter sees this specific function, it applies the function
* with the given arguments to apply.
*
* We need this to be a metaprocedure so that it can properly handle
* the arguments passed to it, even if they are continuations.
*/
class Apply extends Function {
constructor() {
super();
}
static get() {
return Apply.instance;
}
toString() {
return 'apply';
}
}
exports.Apply = Apply;
Apply.instance = new Apply();
exports.apply = Apply.get();
function isApply(value) {
return value === exports.apply;
}
exports.isApply = isApply;
/**
* A dummy function used to detect for the call/cc function object.
* If the interpreter sees this specific function, a continuation at the current
* point of evaluation is executed instead of a regular function call.
*/
class Call_cc extends Function {
constructor() {
super();
}
static get() {
return Call_cc.instance;
}
toString() {
return 'call/cc';
}
}
exports.Call_cc = Call_cc;
Call_cc.instance = new Call_cc();
exports.call_with_current_continuation = Call_cc.get();
function isCallWithCurrentContinuation(value) {
return value === exports.call_with_current_continuation;
}
exports.isCallWithCurrentContinuation = isCallWithCurrentContinuation;
/**
* An object representing a continuation of the CSE machine.
* When instantiated, it copies the control stack, and
* current environment at the point of capture.
*
* Continuations and functions are treated as the same by
* the typechecker so that they can be first-class values.
*/
class Continuation extends Function {
constructor(context, control, stash, env, transformers) {
super();
this.control = control.copy();
this.stash = stash.copy();
this.env = [...env];
this.transformers = transformers;
this.id = (0, utils_1.uniqueId)(context);
}
// As the continuation needs to be immutable (we can call it several times)
// we need to copy its elements whenever we access them
getControl() {
return this.control.copy();
}
getStash() {
return this.stash.copy();
}
getEnv() {
return [...this.env];
}
getTransformers() {
return this.transformers;
}
toString() {
return 'continuation';
}
equals(other) {
return this === other;
}
}
exports.Continuation = Continuation;
/**
* Provides an adequate representation of what calling
* call/cc or continuations looks like, to give to the
* APPLICATION instruction.
*/
function makeDummyContCallExpression(callee, argument) {
return {
type: 'CallExpression',
optional: false,
callee: {
type: 'Identifier',
name: callee
},
arguments: [
{
type: 'Identifier',
name: argument
}
]
};
}
exports.makeDummyContCallExpression = makeDummyContCallExpression;
//# sourceMappingURL=continuations.js.map
;