@powerlang/egg-js
Version:
A Smalltalk VM that runs on top of JavaScript
251 lines (213 loc) • 4.62 kB
JavaScript
import EvaluationContext from './EvaluationContext.js';
let LinkedEvaluationContext = class extends EvaluationContext {
constructor() {
super();
this._parent = nil;
this._method = nil;
this.__arguments = nil;
this._temporaries = nil;
this._environment = nil;
this._isBlock = nil;
this.__self = nil;
}
static new() {
return this.basicNew().initialize();
}
argumentAt_(anInteger) {
return this.__arguments.at_(anInteger);
}
argumentAt_in_(index, environmentIndex) {
let env;
if (nil === environmentIndex)
{
return this.__arguments.at_(index)
}
;
env = this.environmentFor_(environmentIndex);
return env.at_(index);
}
arguments() {
return this.__arguments;
}
arguments_(aCollection) {
this.__arguments = aCollection;
return this;
}
backtrace() {
let bt, next;
bt = Array.new();
next = this;
(() => {
return next.notNil().and_(() => {
return next.method().notNil()
})
}).whileTrue_(() => {
bt.add_([next.method().signature(), next.self()]._comma(next.arguments()));
return next = next.parent()
});
return bt;
}
beBlock() {
this._isBlock = true;
return this;
}
environment() {
return this._environment;
}
environment_(anObject) {
this._environment = anObject;
return this;
}
environmentFor_(anInteger) {
if (anInteger._equal(0))
{
return this._environment
}
;
if (anInteger._equal(-1))
{
return this._temporaries
}
;
return this._environment.at_(anInteger);
}
firstArgument() {
return this.__arguments.at_(1);
}
fourthArgument() {
return this.__arguments.at_(4);
}
framesCount() {
let current, result;
current = this;
result = 0;
(() => {
return current.notNil()
}).whileTrue_(() => {
result = (result+1);
return current = current.parent()
});
return result;
}
homeContext() {
let frame, searched;
const _home = {};
try {
if (!this._isBlock)
{
return this
}
;
frame = this._parent;
searched = this._runtime.closureHome_(this._environment);
(() => {
return frame.notNil()
}).whileTrue_(() => {
if (frame.environment()._equalEqual(searched))
{
throw [_home, frame]
}
;
return frame = frame.parent()
});
this.error_("home context not found");
return this;
} catch(e) { if (e[0] == _home) return e[1]; else throw(e); }
}
initialize() {
this._isBlock = false;
return this;
}
initializeForBlock_args_closure_(sblock, anArray, closure) {
if (sblock.isInlined())
{
anArray.with_do_(sblock.inlinedArgs(), (arg, i) => {
return this._temporaries.at_put_(i, arg)
})
} else {
this._temporaries = Array.new_(sblock.tempCount());
this.__arguments = anArray;
this._environment = closure
}
;
return this;
}
isBlock() {
return this._isBlock;
}
isHomeOf_(env) {
return this._environment._equalEqual(env).andNot_(() => {
return this._isBlock
});
}
method() {
return this._method;
}
method_(aMethod) {
let count;
this._method = aMethod;
count = this._runtime.methodTempCount_(aMethod);
this._temporaries = Array.new_(count);
return this;
}
methodArguments() {
return this.__arguments;
}
parent() {
return this._parent;
}
parent_(anEvaluationContext) {
this._parent = anEvaluationContext;
if (this._isBlock.not().and_(() => {
return this.framesCount()._greaterThan(1000)
}))
{
this.halt()
}
;
return this;
}
receiver() {
return this.__self;
}
secondArgument() {
return this.__arguments.at_(2);
}
self() {
return this.__self;
}
self_(anObject) {
this.__self = anObject;
return this;
}
stackTemporaryAt_(index) {
return this._temporaries.at_(index);
}
stackTemporaryAt_put_(index, value) {
return this._temporaries.at_put_(index, value);
}
temporaryAt_in_(index, environmentIndex) {
let env;
if (nil === environmentIndex)
{
return this.stackTemporaryAt_(index)
}
;
env = this.environmentFor_(environmentIndex);
return env.at_(index);
}
temporaryAt_in_put_(index, environmentIndex, value) {
let env;
if (nil === environmentIndex)
{
return this.stackTemporaryAt_put_(index, value)
}
;
env = this.environmentFor_(environmentIndex);
return env.at_put_(index, value);
}
thirdArgument() {
return this.__arguments.at_(3);
}
}
export default LinkedEvaluationContext