UNPKG

mathjs

Version:

Math.js is an extensive math library for JavaScript and Node.js. It features a flexible expression parser and offers an integrated solution to work with numbers, big numbers, complex numbers, units, and matrices.

149 lines (131 loc) 4.04 kB
var error = require('../../error'); /** * Node */ function Node() { if (!(this instanceof Node)) { throw new SyntaxError('Constructor must be called with the new operator'); } } /** * Evaluate the node * @return {*} result */ // TODO: cleanup deprecated code one day. Deprecated since version 0.19.0 Node.prototype.eval = function () { throw new Error('Node.eval is deprecated. ' + 'Use Node.compile(math).eval([scope]) instead.'); }; /** * Compile the node to javascript code * @param {Object} math math.js instance * @return {{eval: function}} expr Returns an object with a function 'eval', * which can be invoked as expr.eval([scope]), * where scope is an optional object with * variables. */ Node.prototype.compile = function (math) { if (typeof math !== 'object') { throw new TypeError('Object expected for parameter math'); } // definitions globally available inside the closure of the compiled expressions var defs = { math: math, error: error }; var code = this._compile(defs); var defsCode = Object.keys(defs).map(function (name) { return ' var ' + name + ' = defs["' + name + '"];'; }); var factoryCode = defsCode.join(' ') + 'return {' + ' "eval": function (scope) {' + ' try {' + ' scope = scope || {};' + ' return ' + code + ';' + ' } catch (err) {' + // replace an index-out-of-range-error with a one-based message ' if (err instanceof defs.error.IndexError) {' + ' err = new defs.error.IndexError(err.index + 1, err.min + 1, err.max + 1);' + ' }' + ' throw err;' + ' }' + ' }' + '};'; var factory = new Function ('defs', factoryCode); return factory(defs); }; /** * Compile the node to javascript code * @param {Object} defs Object which can be used to define functions * and constants globally available inside the closure * of the compiled expression * @return {String} js * @private */ Node.prototype._compile = function (defs) { throw new Error('Cannot compile a Node interface'); }; /** * Find any node in the node tree matching given filter. For example, to * find all nodes of type SymbolNode having name 'x': * * var results = Node.find({ * type: SymbolNode, * properties: { * name: 'x' * } * }); * * @param {Object} filter Available parameters: * {Function} type * {Object<String, String>} properties * @return {Node[]} nodes An array with nodes matching given filter criteria */ Node.prototype.find = function (filter) { return this.match(filter) ? [this] : []; }; /** * Test if this object matches given filter * @param {Object} [filter] Available parameters: * {Function} type * {Object<String, *>} properties * @return {Boolean} matches True if there is a match */ Node.prototype.match = function (filter) { var match = true; if (filter) { if (filter.type && !(this instanceof filter.type)) { match = false; } var properties = filter.properties; if (match && properties) { for (var prop in properties) { if (properties.hasOwnProperty(prop)) { if (this[prop] !== properties[prop]) { match = false; break; } } } } } return match; }; /** * Get string representation * @return {String} */ Node.prototype.toString = function() { return ''; }; /** * Test whether an object is a Node * @param {*} object * @returns {boolean} isNode */ Node.isNode = function isNode (object) { return object instanceof Node; } module.exports = Node;