var Node = require('./Node'); var latex = require('../../util/latex'); /** * A lazy evaluating conditional operator: 'condition ? trueExpr : falseExpr' * * @param {Node} condition Condition, must result in a boolean * @param {Node} trueExpr Expression evaluated when condition is true * @param {Node} falseExpr Expression evaluated when condition is true * * @constructor ConditionalNode * @extends {Node} */ function ConditionalNode (condition, trueExpr, falseExpr) { if (!(this instanceof ConditionalNode)) { throw new SyntaxError('Constructor must be called with the new operator'); } if (!(condition instanceof Node)) throw new TypeError('Parameter condition must be a Node'); if (!(trueExpr instanceof Node)) throw new TypeError('Parameter trueExpr must be a Node'); if (!(falseExpr instanceof Node)) throw new TypeError('Parameter falseExpr must be a Node'); this.condition = condition; this.trueExpr = trueExpr; this.falseExpr = falseExpr; } ConditionalNode.prototype = new Node(); ConditionalNode.prototype.type = 'ConditionalNode'; /** * 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 * @return {String} js * @private */ ConditionalNode.prototype._compile = function(defs) { // TODO: it would be faster instead of executing math.ifElse, to inline ifElse return ( 'math.ifElse(' + this.condition._compile(defs) + ', true, false) ? ' + '( ' + this.trueExpr._compile(defs) + ') : ' + '( ' + this.falseExpr._compile(defs) + ')' ); }; /** * Find all nodes matching given filter * @param {Object} filter See Node.find for a description of the filter options * @returns {Node[]} nodes */ ConditionalNode.prototype.find = function (filter) { var nodes = []; // check itself if (this.match(filter)) { nodes.push(this); } // search in parameters nodes = nodes.concat( this.condition.find(filter), this.trueExpr.find(filter), this.falseExpr.find(filter)); return nodes; }; /** * Get string representation * @return {String} str */ ConditionalNode.prototype.toString = function() { // TODO: not nice adding parenthesis al the time return '(' + this.condition.toString() + ') ? (' + this.trueExpr.toString() + ') : (' + this.falseExpr.toString() + ')'; }; /** * Get LaTeX representation * @return {String} str */ ConditionalNode.prototype.toTex = function() { var s = ( latex.addBraces(this.trueExpr.toTex()) + ', &\\quad' + latex.addBraces('\\text{if}\\;' + this.condition.toTex()) ) + '\\\\' + ( latex.addBraces(this.falseExpr.toTex()) + ', &\\quad' + latex.addBraces('\\text{otherwise}') ); return latex.addBraces(s, [ '\\left\\{\\begin{array}{l l}', '\\end{array}\\right.' ]); }; module.exports = ConditionalNode;