angel-eval
Version:
A conditional expression parser and interpreter.
97 lines (75 loc) • 2.44 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.evaluate = evaluate;
exports.default = exports.parse = void 0;
var _memoize = _interopRequireDefault(require("lodash/memoize"));
var _isString = _interopRequireDefault(require("lodash/isString"));
var _isBoolean = _interopRequireDefault(require("lodash/isBoolean"));
var _nearley = require("nearley");
var _Evaluatable = _interopRequireDefault(require("./Evaluatable"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const grammar = _nearley.Grammar.fromCompiled(require("./grammar.js"));
function createParser() {
return new _nearley.Parser(grammar);
}
/**
* Parses the given expression and returns an
* `Evaluatable` that can be evaluated with a context.
*
* @param {string} expression
* @returns {Evaluatable}
*/
const _parse = expression => {
if (!(0, _isString.default)(expression) || expression.length === 0) {
throw new Error("expression needs to be a non-empty string");
}
const parser = createParser();
try {
parser.feed(expression);
const [node] = parser.results; // if (!(node instanceof Evaluatable)) {
// throw new Error("Result needs to be an instance of Evaluatable");
// }
return node;
} catch (e) {
const segments = e.message.split(/\r?\n/g).slice(0, 4);
segments[2] = segments[2].substring(1);
segments[3] = segments[3].substring(1);
throw new Error(segments.join("\n"));
}
};
/**
* Parses the given expression and returns an
* `Evaluatable` that can be evaluated with a context.
*
* This function is memoized for optimization.
*
* You can access the function's cache using `parse.cache`.
*/
const parse = (0, _memoize.default)(_parse);
/**
* Evaluates the given expression using the context provided.
*
* @param {string} expression
* @param {{ [key: string]: any }} [context]
* @param {boolean} [strictBoolean] Whether to always return a boolean.
* @returns {boolean}
*/
exports.parse = parse;
function evaluate(expression, context = {}, strictBoolean = true) {
const node = parse(expression); // console.dir(node, { depth: 100 });
let value = node.evaluate(context);
if (!(0, _isBoolean.default)(value) && strictBoolean) {
value = !!value;
}
return value;
}
var _default = {
createParser,
_parse,
// public methods
parse,
evaluate
};
exports.default = _default;