UNPKG

@powerlang/egg-js

Version:

A Smalltalk VM that runs on top of JavaScript

348 lines (309 loc) 8.42 kB
import AstBindingTypes from './AstBindingTypes.js'; import AstNodeTypes from './AstNodeTypes.js'; import SArgumentBinding from './SArgumentBinding.js'; import SAssignment from './SAssignment.js'; import SBlock from './SBlock.js'; import SCascade from './SCascade.js'; import SCascadeMessage from './SCascadeMessage.js'; import SDynamicBinding from './SDynamicBinding.js'; import SFalseBinding from './SFalseBinding.js'; import SIdentifier from './SIdentifier.js'; import SLiteral from './SLiteral.js'; import SMessage from './SMessage.js'; import SMethod from './SMethod.js'; import SNestedDynamicBinding from './SNestedDynamicBinding.js'; import SNilBinding from './SNilBinding.js'; import SPragma from './SPragma.js'; import SReturn from './SReturn.js'; import SSelfBinding from './SSelfBinding.js'; import SSuperBinding from './SSuperBinding.js'; import STemporaryBinding from './STemporaryBinding.js'; import STrueBinding from './STrueBinding.js'; let TreecodeDecoder = class { static _BindingTypes = nil; static _NodeTypes = nil; constructor() { this._method = nil; this._stream = nil; this._builder = nil; } static initialize() { this._NodeTypes = Map.new(); this._BindingTypes = Map.new(); _cascade(this._NodeTypes, (_recv) => { _recv.at_put_(AssignmentId, SAssignment); _recv.at_put_(BlockId, SBlock); _recv.at_put_(CascadeId, SCascade); _recv.at_put_(LiteralId, SLiteral); _recv.at_put_(IdentifierId, SIdentifier); _recv.at_put_(MessageId, SMessage); return _recv.at_put_(ReturnId, SReturn);}); _cascade(this._BindingTypes, (_recv) => { _recv.at_put_(NilId, SNilBinding); _recv.at_put_(TrueId, STrueBinding); _recv.at_put_(FalseId, SFalseBinding); _recv.at_put_(ArgumentId, SArgumentBinding); _recv.at_put_(TemporaryId, STemporaryBinding); _recv.at_put_(SelfId, SSelfBinding); _recv.at_put_(SuperId, SSuperBinding); _recv.at_put_(DynamicVarId, SDynamicBinding); return _recv.at_put_(NestedDynamicVarId, SNestedDynamicBinding);}); return this; } static new() { return this.basicNew().initialize(); } bindingTypeOf_(id) { return this.constructor._BindingTypes.at_(id); } builder_(aRuntime) { this._builder = aRuntime; return this; } decodeArgument() { return _cascade(SArgumentBinding.new(), (_recv) => { _recv.index_(this.nextInteger()); return _recv.environment_(this.nextEnvironment());}); } decodeAssignment() { let assignment, assignees; assignment = SAssignment.new(); assignees = this.nextExpressionArray(); assignment.expression_(this.nextExpression()); assignees.do_((identifier) => { return assignment.assign_(identifier) }); return assignment; } decodeBlock() { let expression, inlined, block, index, code; expression = SBlock.new(); inlined = this.nextBoolean(); if (inlined) { expression.inlinedArgs_(this.nextArray()) } else { index = this.nextInteger(); block = this.literalAt_(index); if (nil !== this._builder) { code = this._builder.newExecutableCodeFor_(expression); this._builder.blockExecutableCode_put_(block, code) } ; _cascade(expression, (_recv) => { _recv.compiledCode_(block); _recv.index_(index); return _recv.capturedVariables_(this.nextArray());}) } ; expression.statements_(this.nextExpressionArray()); return expression; } decodeCascade() { let cascade, receiver, messages, message, count; cascade = SCascade.new(); receiver = this.nextExpression(); count = this.nextInteger(); messages = (1).to_(count).collect_((i) => { message = SCascadeMessage.decodeUsing_(this); return message.cascade_(cascade) }); return _cascade(cascade, (_recv) => { _recv.receiver_(receiver); return _recv.messages_(messages);}); } decodeCascadeMessage() { let selector, _arguments; selector = this.nextSymbol(); _arguments = this.nextExpressionArray(); return _cascade(SCascadeMessage.new(), (_recv) => { _recv.selector_(selector); return _recv.arguments_(_arguments);}); } decodeDynamicVar() { return SDynamicBinding.new().name_(this.nextSymbol()); } decodeIdentifier() { let type, binding; type = this.bindingTypeOf_(this.nextInteger()); binding = type.decodeUsing_(this); return SIdentifier.new().binding_(binding); } decodeLiteral() { let index, value; index = this.nextInteger(); if (index._equal(0)) { value = this.nextLiteralInteger() } else { value = this.literalAt_(index) } ; return _cascade(SLiteral.new(), (_recv) => { _recv.index_(index); return _recv.value_(value);}); } decodeMessage() { let inlined, selector, receiver, _arguments; inlined = this.nextBoolean(); selector = this.nextSymbol(); receiver = this.nextExpression(); _arguments = this.nextExpressionArray(); return _cascade(SMessage.new(), (_recv) => { _recv.receiver_(receiver); _recv.selector_(selector); _recv.arguments_(_arguments); return _recv.inlined_(inlined);}); } decodeMethod() { let type, node, next, pragma; type = this._stream.next(); if (type._notEqual(MethodId)) { this.error_("method treecode expected") } ; node = SMethod.new(); next = this._stream.peek(); if (next._equal(PragmaId)) { this._stream.next(); pragma = SPragma.new().name_(this.nextSymbolOrNil()); node.pragma_(pragma) } ; _cascade(node, (_recv) => { _recv.compiledCode_(this._method); return _recv.statements_(this.nextExpressionArray());}); return node; } decodeNestedDynamicVar() { return SNestedDynamicBinding.new().name_(this.nextSymbol()); } decodeReturn() { let expression, local; local = this.nextBoolean(); expression = this.nextExpression(); return _cascade(SReturn.new(), (_recv) => { _recv.local_(local); return _recv.expression_(expression);}); } decodeTemporary() { return _cascade(STemporaryBinding.new(), (_recv) => { _recv.index_(this.nextInteger()); return _recv.environment_(this.nextEnvironment());}); } literalAt_(anInteger) { let _retval; if (nil === this._builder) { _retval = this._method.at_(anInteger) } else { _retval = this._builder.method_literalAt_(this._method, anInteger) } ; return _retval; } method_(aMethod) { this._method = aMethod; return this; } nextArray() { let count; count = this.nextInteger(); return this._stream.next_(count); } nextBoolean() { return this._stream.next()._equal(1); } nextEnvironment() { let value, _retval; value = this.nextInteger(); _retval = nil; if (value._notEqual(-2)) { _retval = value } ; return _retval; } nextExpression() { let type; type = this.nodeTypeOf_(this._stream.next()); return type.decodeUsing_(this); } nextExpressionArray() { let count; count = this.nextInteger(); return (1).to_(count).collect_((arg) => { return this.nextExpression() }); } nextInteger() { let value, _retval; value = this._stream.next(); if (value._equal(128)) { return this._stream.int64() } ; if (value._lessEqualThan(127)) { _retval = value } else { _retval = (value-256) } ; return _retval; } nextLiteralInteger() { let value, _retval; value = this.nextInteger(); if (nil === this._builder) { _retval = value } else { _retval = this._builder.newInteger_(value) } ; return _retval; } nextSymbol() { let index; index = this.nextInteger(); return this.literalAt_(index); } nextSymbolOrNil() { let index, _retval; index = this.nextInteger(); _retval = nil; if (index._notEqual(0)) { _retval = this.literalAt_(index) } ; return _retval; } nextUnsignedInteger() { let value, _retval; value = this.nextByte(); if (value._lessThan(128)) { _retval = value } else { _retval = ((value-128)+this.nextUnsignedInteger().bitShift_(7)) } ; return _retval; } nodeTypeOf_(id) { return this.constructor._NodeTypes.at_(id); } stream_(aStream) { this._stream = aStream; return this; } } TreecodeDecoder.initialize(); export default TreecodeDecoder