simple-squiggle

A restricted subset of Squiggle
Log | Files | Refs | README

BlockNode.js (6095B)


      1 "use strict";
      2 
      3 Object.defineProperty(exports, "__esModule", {
      4   value: true
      5 });
      6 exports.createBlockNode = void 0;
      7 
      8 var _is = require("../../utils/is.js");
      9 
     10 var _array = require("../../utils/array.js");
     11 
     12 var _factory = require("../../utils/factory.js");
     13 
     14 var name = 'BlockNode';
     15 var dependencies = ['ResultSet', 'Node'];
     16 var createBlockNode = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) {
     17   var ResultSet = _ref.ResultSet,
     18       Node = _ref.Node;
     19 
     20   /**
     21    * @constructor BlockNode
     22    * @extends {Node}
     23    * Holds a set with blocks
     24    * @param {Array.<{node: Node} | {node: Node, visible: boolean}>} blocks
     25    *            An array with blocks, where a block is constructed as an Object
     26    *            with properties block, which is a Node, and visible, which is
     27    *            a boolean. The property visible is optional and is true by default
     28    */
     29   function BlockNode(blocks) {
     30     if (!(this instanceof BlockNode)) {
     31       throw new SyntaxError('Constructor must be called with the new operator');
     32     } // validate input, copy blocks
     33 
     34 
     35     if (!Array.isArray(blocks)) throw new Error('Array expected');
     36     this.blocks = blocks.map(function (block) {
     37       var node = block && block.node;
     38       var visible = block && block.visible !== undefined ? block.visible : true;
     39       if (!(0, _is.isNode)(node)) throw new TypeError('Property "node" must be a Node');
     40       if (typeof visible !== 'boolean') throw new TypeError('Property "visible" must be a boolean');
     41       return {
     42         node: node,
     43         visible: visible
     44       };
     45     });
     46   }
     47 
     48   BlockNode.prototype = new Node();
     49   BlockNode.prototype.type = 'BlockNode';
     50   BlockNode.prototype.isBlockNode = true;
     51   /**
     52    * Compile a node into a JavaScript function.
     53    * This basically pre-calculates as much as possible and only leaves open
     54    * calculations which depend on a dynamic scope with variables.
     55    * @param {Object} math     Math.js namespace with functions and constants.
     56    * @param {Object} argNames An object with argument names as key and `true`
     57    *                          as value. Used in the SymbolNode to optimize
     58    *                          for arguments from user assigned functions
     59    *                          (see FunctionAssignmentNode) or special symbols
     60    *                          like `end` (see IndexNode).
     61    * @return {function} Returns a function which can be called like:
     62    *                        evalNode(scope: Object, args: Object, context: *)
     63    */
     64 
     65   BlockNode.prototype._compile = function (math, argNames) {
     66     var evalBlocks = (0, _array.map)(this.blocks, function (block) {
     67       return {
     68         evaluate: block.node._compile(math, argNames),
     69         visible: block.visible
     70       };
     71     });
     72     return function evalBlockNodes(scope, args, context) {
     73       var results = [];
     74       (0, _array.forEach)(evalBlocks, function evalBlockNode(block) {
     75         var result = block.evaluate(scope, args, context);
     76 
     77         if (block.visible) {
     78           results.push(result);
     79         }
     80       });
     81       return new ResultSet(results);
     82     };
     83   };
     84   /**
     85    * Execute a callback for each of the child blocks of this node
     86    * @param {function(child: Node, path: string, parent: Node)} callback
     87    */
     88 
     89 
     90   BlockNode.prototype.forEach = function (callback) {
     91     for (var i = 0; i < this.blocks.length; i++) {
     92       callback(this.blocks[i].node, 'blocks[' + i + '].node', this);
     93     }
     94   };
     95   /**
     96    * Create a new BlockNode having it's childs be the results of calling
     97    * the provided callback function for each of the childs of the original node.
     98    * @param {function(child: Node, path: string, parent: Node): Node} callback
     99    * @returns {BlockNode} Returns a transformed copy of the node
    100    */
    101 
    102 
    103   BlockNode.prototype.map = function (callback) {
    104     var blocks = [];
    105 
    106     for (var i = 0; i < this.blocks.length; i++) {
    107       var block = this.blocks[i];
    108 
    109       var node = this._ifNode(callback(block.node, 'blocks[' + i + '].node', this));
    110 
    111       blocks[i] = {
    112         node: node,
    113         visible: block.visible
    114       };
    115     }
    116 
    117     return new BlockNode(blocks);
    118   };
    119   /**
    120    * Create a clone of this node, a shallow copy
    121    * @return {BlockNode}
    122    */
    123 
    124 
    125   BlockNode.prototype.clone = function () {
    126     var blocks = this.blocks.map(function (block) {
    127       return {
    128         node: block.node,
    129         visible: block.visible
    130       };
    131     });
    132     return new BlockNode(blocks);
    133   };
    134   /**
    135    * Get string representation
    136    * @param {Object} options
    137    * @return {string} str
    138    * @override
    139    */
    140 
    141 
    142   BlockNode.prototype._toString = function (options) {
    143     return this.blocks.map(function (param) {
    144       return param.node.toString(options) + (param.visible ? '' : ';');
    145     }).join('\n');
    146   };
    147   /**
    148    * Get a JSON representation of the node
    149    * @returns {Object}
    150    */
    151 
    152 
    153   BlockNode.prototype.toJSON = function () {
    154     return {
    155       mathjs: 'BlockNode',
    156       blocks: this.blocks
    157     };
    158   };
    159   /**
    160    * Instantiate an BlockNode from its JSON representation
    161    * @param {Object} json  An object structured like
    162    *                       `{"mathjs": "BlockNode", blocks: [{node: ..., visible: false}, ...]}`,
    163    *                       where mathjs is optional
    164    * @returns {BlockNode}
    165    */
    166 
    167 
    168   BlockNode.fromJSON = function (json) {
    169     return new BlockNode(json.blocks);
    170   };
    171   /**
    172    * Get HTML representation
    173    * @param {Object} options
    174    * @return {string} str
    175    * @override
    176    */
    177 
    178 
    179   BlockNode.prototype.toHTML = function (options) {
    180     return this.blocks.map(function (param) {
    181       return param.node.toHTML(options) + (param.visible ? '' : '<span class="math-separator">;</span>');
    182     }).join('<span class="math-separator"><br /></span>');
    183   };
    184   /**
    185    * Get LaTeX representation
    186    * @param {Object} options
    187    * @return {string} str
    188    */
    189 
    190 
    191   BlockNode.prototype._toTex = function (options) {
    192     return this.blocks.map(function (param) {
    193       return param.node.toTex(options) + (param.visible ? '' : ';');
    194     }).join('\\;\\;\n');
    195   };
    196 
    197   return BlockNode;
    198 }, {
    199   isClass: true,
    200   isNode: true
    201 });
    202 exports.createBlockNode = createBlockNode;