simple-squiggle

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

Parser.js (4666B)


      1 "use strict";
      2 
      3 Object.defineProperty(exports, "__esModule", {
      4   value: true
      5 });
      6 exports.createParserClass = void 0;
      7 
      8 var _factory = require("../utils/factory.js");
      9 
     10 var _map = require("../utils/map.js");
     11 
     12 var name = 'Parser';
     13 var dependencies = ['evaluate'];
     14 var createParserClass = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) {
     15   var evaluate = _ref.evaluate;
     16 
     17   /**
     18    * @constructor Parser
     19    * Parser contains methods to evaluate or parse expressions, and has a number
     20    * of convenience methods to get, set, and remove variables from memory. Parser
     21    * keeps a scope containing variables in memory, which is used for all
     22    * evaluations.
     23    *
     24    * Methods:
     25    *    const result = parser.evaluate(expr)  // evaluate an expression
     26    *    const value = parser.get(name)        // retrieve a variable from the parser
     27    *    const values = parser.getAll()        // retrieve all defined variables
     28    *    parser.set(name, value)               // set a variable in the parser
     29    *    parser.remove(name)                   // clear a variable from the
     30    *                                          // parsers scope
     31    *    parser.clear()                        // clear the parsers scope
     32    *
     33    * Example usage:
     34    *    const parser = new Parser()
     35    *    // Note: there is a convenience method which can be used instead:
     36    *    // const parser = new math.parser()
     37    *
     38    *    // evaluate expressions
     39    *    parser.evaluate('sqrt(3^2 + 4^2)')        // 5
     40    *    parser.evaluate('sqrt(-4)')               // 2i
     41    *    parser.evaluate('2 inch in cm')           // 5.08 cm
     42    *    parser.evaluate('cos(45 deg)')            // 0.7071067811865476
     43    *
     44    *    // define variables and functions
     45    *    parser.evaluate('x = 7 / 2')              // 3.5
     46    *    parser.evaluate('x + 3')                  // 6.5
     47    *    parser.evaluate('f(x, y) = x^y')          // f(x, y)
     48    *    parser.evaluate('f(2, 3)')                // 8
     49    *
     50    *    // get and set variables and functions
     51    *    const x = parser.get('x')                 // 7
     52    *    const f = parser.get('f')                 // function
     53    *    const g = f(3, 2)                         // 9
     54    *    parser.set('h', 500)
     55    *    const i = parser.evaluate('h / 2')        // 250
     56    *    parser.set('hello', function (name) {
     57    *        return 'hello, ' + name + '!'
     58    *    })
     59    *    parser.evaluate('hello("user")')          // "hello, user!"
     60    *
     61    *    // clear defined functions and variables
     62    *    parser.clear()
     63    *
     64    */
     65   function Parser() {
     66     if (!(this instanceof Parser)) {
     67       throw new SyntaxError('Constructor must be called with the new operator');
     68     }
     69 
     70     Object.defineProperty(this, 'scope', {
     71       value: (0, _map.createEmptyMap)(),
     72       writable: false
     73     });
     74   }
     75   /**
     76    * Attach type information
     77    */
     78 
     79 
     80   Parser.prototype.type = 'Parser';
     81   Parser.prototype.isParser = true;
     82   /**
     83    * Parse and evaluate the given expression
     84    * @param {string | string[]} expr   A string containing an expression,
     85    *                                   for example "2+3", or a list with expressions
     86    * @return {*} result     The result, or undefined when the expression was empty
     87    * @throws {Error}
     88    */
     89 
     90   Parser.prototype.evaluate = function (expr) {
     91     // TODO: validate arguments
     92     return evaluate(expr, this.scope);
     93   };
     94   /**
     95    * Get a variable (a function or variable) by name from the parsers scope.
     96    * Returns undefined when not found
     97    * @param {string} name
     98    * @return {* | undefined} value
     99    */
    100 
    101 
    102   Parser.prototype.get = function (name) {
    103     // TODO: validate arguments
    104     if (this.scope.has(name)) {
    105       return this.scope.get(name);
    106     }
    107   };
    108   /**
    109    * Get a map with all defined variables
    110    * @return {Object} values
    111    */
    112 
    113 
    114   Parser.prototype.getAll = function () {
    115     return (0, _map.toObject)(this.scope);
    116   };
    117   /**
    118    * Get a map with all defined variables
    119    * @return {Map} values
    120    */
    121 
    122 
    123   Parser.prototype.getAllAsMap = function () {
    124     return this.scope;
    125   };
    126   /**
    127    * Set a symbol (a function or variable) by name from the parsers scope.
    128    * @param {string} name
    129    * @param {* | undefined} value
    130    */
    131 
    132 
    133   Parser.prototype.set = function (name, value) {
    134     this.scope.set(name, value);
    135     return value;
    136   };
    137   /**
    138    * Remove a variable from the parsers scope
    139    * @param {string} name
    140    */
    141 
    142 
    143   Parser.prototype.remove = function (name) {
    144     this.scope.delete(name);
    145   };
    146   /**
    147    * Clear the scope with variables and functions
    148    */
    149 
    150 
    151   Parser.prototype.clear = function () {
    152     this.scope.clear();
    153   };
    154 
    155   return Parser;
    156 }, {
    157   isClass: true
    158 });
    159 exports.createParserClass = createParserClass;