UNPKG

es-vm

Version:

A visual machine run in ES env like Node/Browser

82 lines (73 loc) 1.99 kB
'use strict'; const statementClassMap = {}; const error = { NO_EXECUTE: (symbol) => { return `The Statement:${symbol} miss prototype.execute.`; } }; function linkNode(syntaxNode) { try { return new statementClassMap[syntaxNode.SYMBOL](syntaxNode); } catch (err) { console.error(syntaxNode); throw err; } } /** * Bind statement with a symbol. * @param {String} $Symbol Statement symbol. */ function register(statementClass, symbol, execution = true) { if (!statementClass.prototype.execute && execution) { throw new Error(`[ESVM-DEV]: ${error.NO_EXECUTE(symbol)}`); } statementClassMap[symbol] = statementClass; return statementClass; } /** * The most simple statement looks like: * { * SYMBOL: <string | used to query how to execute>, * [POSITION]: { * [IDENTIFIER]: <string | the line name user assigned>, * LINE: <unsigned number | the line of statement in the code>, * [COL]: <unsigned number | the line of statement in the code> * }, <object | statement position info from syntax tree> * BODY: { * [PROPERTIES] * } <object | > * } * * @class Statement */ class Statement { /** * @constructor * @param {Object} [POSITION={}] Position info of the statement. */ constructor ({POSITION} = {type: 'native'}) { this.position = POSITION; } /** * Link each statement node from a syntax tree by statement symbol. * @param {Object} syntaxNode Statement content. * @returns {Statement} Statement instance. */ linkNode (syntaxNode) { return linkNode(syntaxNode); } /** * Define execution rule for the statement. * Operation will be record in a stack. * @param {Kernel} vm * @param {Scope} scope */ *doExecution($) { $.vm.pushOperation(this); const ret = yield* this.execute($); $.vm.emit('writeback', ret, $.vm); $.vm.popOperation(); return ret; } } module.exports = {Statement, linkNode, register};