mirror of
https://github.com/josdejong/mathjs.git
synced 2025-12-08 19:46:04 +00:00
130 lines
4.1 KiB
JavaScript
130 lines
4.1 KiB
JavaScript
'use strict';
|
|
|
|
var latex = require('../../utils/latex');
|
|
|
|
function factory (type, config, load, typed) {
|
|
var Node = load(require('./Node'));
|
|
var ArrayNode = load(require('./ArrayNode'));
|
|
|
|
var keywords = require('../keywords');
|
|
var operators = require('../operators');
|
|
|
|
/**
|
|
* @constructor AssignmentNode
|
|
* @extends {Node}
|
|
* Define a symbol, like "a = 3.2"
|
|
*
|
|
* @param {string} name Symbol name
|
|
* @param {Node} expr The expression defining the symbol
|
|
*/
|
|
function AssignmentNode(name, expr) {
|
|
if (!(this instanceof AssignmentNode)) {
|
|
throw new SyntaxError('Constructor must be called with the new operator');
|
|
}
|
|
|
|
// validate input
|
|
if (typeof name !== 'string') throw new TypeError('String expected for parameter "name"');
|
|
if (!(expr && expr.isNode)) throw new TypeError('Node expected for parameter "expr"');
|
|
if (name in keywords) throw new Error('Illegal symbol name, "' + name + '" is a reserved keyword');
|
|
|
|
this.name = name;
|
|
this.expr = expr;
|
|
}
|
|
|
|
AssignmentNode.prototype = new Node();
|
|
|
|
AssignmentNode.prototype.type = 'AssignmentNode';
|
|
|
|
AssignmentNode.prototype.isAssignmentNode = true;
|
|
|
|
/**
|
|
* Compile the node to javascript code
|
|
* @param {Object} defs Object which can be used to define functions
|
|
* or constants globally available for the compiled
|
|
* expression
|
|
* @param {Object} args Object with local function arguments, the key is
|
|
* the name of the argument, and the value is `true`.
|
|
* The object may not be mutated, but must be
|
|
* extended instead.
|
|
* @private
|
|
*/
|
|
AssignmentNode.prototype._compile = function (defs, args) {
|
|
return 'scope["' + this.name + '"] = ' + this.expr._compile(defs, args) + '';
|
|
};
|
|
|
|
|
|
/**
|
|
* Execute a callback for each of the child nodes of this node
|
|
* @param {function(child: Node, path: string, parent: Node)} callback
|
|
*/
|
|
AssignmentNode.prototype.forEach = function (callback) {
|
|
callback(this.expr, 'expr', this);
|
|
};
|
|
|
|
/**
|
|
* Create a new AssignmentNode having it's childs be the results of calling
|
|
* the provided callback function for each of the childs of the original node.
|
|
* @param {function(child: Node, path: string, parent: Node): Node} callback
|
|
* @returns {AssignmentNode} Returns a transformed copy of the node
|
|
*/
|
|
AssignmentNode.prototype.map = function (callback) {
|
|
return new AssignmentNode(this.name, this._ifNode(callback(this.expr, 'expr', this)));
|
|
};
|
|
|
|
/**
|
|
* Create a clone of this node, a shallow copy
|
|
* @return {AssignmentNode}
|
|
*/
|
|
AssignmentNode.prototype.clone = function() {
|
|
return new AssignmentNode(this.name, this.expr);
|
|
};
|
|
|
|
/*
|
|
* Is parenthesis needed?
|
|
* @param {node} node
|
|
* @param {string} parenthesis
|
|
* @private
|
|
*/
|
|
function needParenthesis(node, parenthesis) {
|
|
var precedence = operators.getPrecedence(node, parenthesis);
|
|
var exprPrecedence = operators.getPrecedence(node.expr, parenthesis);
|
|
return (parenthesis === 'all')
|
|
|| ((exprPrecedence !== null) && (exprPrecedence <= precedence));
|
|
}
|
|
|
|
/**
|
|
* Get string representation
|
|
* @param {Object} options
|
|
* @return {string}
|
|
*/
|
|
AssignmentNode.prototype._toString = function(options) {
|
|
var parenthesis = (options && options.parenthesis) ? options.parenthesis : 'keep';
|
|
var expr = this.expr.toString(options);
|
|
if (needParenthesis(this, parenthesis)) {
|
|
expr = '(' + expr + ')';
|
|
}
|
|
return this.name + ' = ' + expr;
|
|
};
|
|
|
|
/**
|
|
* Get LaTeX representation
|
|
* @param {Object} options
|
|
* @return {string}
|
|
*/
|
|
AssignmentNode.prototype._toTex = function(options) {
|
|
var parenthesis = (options && options.parenthesis) ? options.parenthesis : 'keep';
|
|
var expr = this.expr.toTex(options);
|
|
if (needParenthesis(this, parenthesis)) {
|
|
expr = '\\left(' + expr + '\\right)';
|
|
}
|
|
|
|
return latex.toSymbol(this.name) + ':=' + expr;
|
|
};
|
|
|
|
return AssignmentNode;
|
|
}
|
|
|
|
exports.name = 'AssignmentNode';
|
|
exports.path = 'expression.node';
|
|
exports.factory = factory;
|