UNPKG

@powerlang/egg-js

Version:

A Smalltalk VM that runs on top of JavaScript

251 lines (213 loc) 4.62 kB
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