UNPKG

hyperformula

Version:

HyperFormula is a JavaScript engine for efficient processing of spreadsheet-like data and formulas

327 lines (285 loc) 10.1 kB
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } import "core-js/modules/es.math.trunc.js"; import "core-js/modules/es.string.trim.js"; import "core-js/modules/es.string.starts-with.js"; import "core-js/modules/es.array.slice.js"; import "core-js/modules/es.string.repeat.js"; import "core-js/modules/es.object.get-prototype-of.js"; import "core-js/modules/es.reflect.construct.js"; import "core-js/modules/es.symbol.js"; import "core-js/modules/es.symbol.description.js"; import "core-js/modules/es.object.to-string.js"; import "core-js/modules/es.symbol.iterator.js"; import "core-js/modules/es.array.iterator.js"; import "core-js/modules/es.string.iterator.js"; import "core-js/modules/web.dom-collections.iterator.js"; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } /** * @license * Copyright (c) 2021 Handsoncode. All rights reserved. */ import { CellError, ErrorType } from '../../Cell'; import { ErrorMessage } from '../../error-message'; import { getRawValue } from '../InterpreterValue'; import { ArgumentTypes, FunctionPlugin } from './FunctionPlugin'; export var RomanPlugin = /*#__PURE__*/function (_FunctionPlugin) { _inherits(RomanPlugin, _FunctionPlugin); var _super = _createSuper(RomanPlugin); function RomanPlugin() { _classCallCheck(this, RomanPlugin); return _super.apply(this, arguments); } _createClass(RomanPlugin, [{ key: "roman", value: function roman(ast, state) { var _this = this; return this.runFunction(ast.args, state, this.metadata('ROMAN'), function (val, mode) { val = Math.trunc(val); if (mode === false) { mode = 4; } else if (mode === true) { mode = 0; } mode = getRawValue(_this.coerceScalarToNumberOrError(mode)); if (mode instanceof CellError) { return mode; } mode = Math.trunc(mode); if (mode < 0) { return new CellError(ErrorType.VALUE, ErrorMessage.ValueSmall); } if (mode > 4) { return new CellError(ErrorType.VALUE, ErrorMessage.ValueLarge); } return romanMode(val, mode); }); } }, { key: "arabic", value: function arabic(ast, state) { return this.runFunction(ast.args, state, this.metadata('ARABIC'), function (inputString) { inputString = inputString.trim().toUpperCase(); var minusSign = false; if (inputString.startsWith('-')) { inputString = inputString.slice(1); minusSign = true; if (inputString === '') { return new CellError(ErrorType.VALUE, ErrorMessage.InvalidRoman); } } var work = { input: inputString, acc: 0 }; eatToken(work, { token: 'MMM', val: 3000 }, { token: 'MM', val: 2000 }, { token: 'M', val: 1000 }); eatToken(work, { token: 'IM', val: 999 }, { token: 'VM', val: 995 }, { token: 'XM', val: 990 }, { token: 'LM', val: 950 }, { token: 'CM', val: 900 }); eatToken(work, { token: 'D', val: 500 }, { token: 'ID', val: 499 }, { token: 'VD', val: 495 }, { token: 'XD', val: 490 }, { token: 'LD', val: 450 }, { token: 'CD', val: 400 }); eatToken(work, { token: 'CCC', val: 300 }, { token: 'CC', val: 200 }, { token: 'C', val: 100 }); eatToken(work, { token: 'IC', val: 99 }, { token: 'VC', val: 95 }, { token: 'XC', val: 90 }); eatToken(work, { token: 'L', val: 50 }, { token: 'IL', val: 49 }, { token: 'VL', val: 45 }, { token: 'XL', val: 40 }); eatToken(work, { token: 'XXX', val: 30 }, { token: 'XX', val: 20 }, { token: 'X', val: 10 }); eatToken(work, { token: 'IX', val: 9 }); eatToken(work, { token: 'V', val: 5 }, { token: 'IV', val: 4 }); eatToken(work, { token: 'III', val: 3 }, { token: 'II', val: 2 }, { token: 'I', val: 1 }); if (work.input !== '') { return new CellError(ErrorType.VALUE, ErrorMessage.InvalidRoman); } else { return minusSign ? -work.acc : work.acc; } }); } }]); return RomanPlugin; }(FunctionPlugin); RomanPlugin.implementedFunctions = { 'ROMAN': { method: 'roman', parameters: [{ argumentType: ArgumentTypes.NUMBER, minValue: 1, lessThan: 4000 }, { argumentType: ArgumentTypes.NOERROR, optionalArg: true, defaultValue: 0 }] }, 'ARABIC': { method: 'arabic', parameters: [{ argumentType: ArgumentTypes.STRING }] } }; function eatToken(inputAcc) { for (var _len = arguments.length, tokens = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { tokens[_key - 1] = arguments[_key]; } for (var _i = 0, _tokens = tokens; _i < _tokens.length; _i++) { var token = _tokens[_i]; if (inputAcc.input.startsWith(token.token)) { inputAcc.input = inputAcc.input.slice(token.token.length); inputAcc.acc += token.val; break; } } } function romanMode(input, mode) { var work = { val: input % 1000, acc: 'M'.repeat(Math.floor(input / 1000)) }; if (mode === 4) { absorb(work, 'IM', 999, 1000); absorb(work, 'ID', 499, 500); } if (mode >= 3) { absorb(work, 'VM', 995, 1000); absorb(work, 'VD', 495, 500); } if (mode >= 2) { absorb(work, 'XM', 990, 1000); absorb(work, 'XD', 490, 500); } if (mode >= 1) { absorb(work, 'LM', 950, 1000); absorb(work, 'LD', 450, 500); } absorb(work, 'CM', 900, 1000); absorb(work, 'CD', 400, 500); absorb(work, 'D', 500, 900); work.acc += 'C'.repeat(Math.floor(work.val / 100)); work.val %= 100; if (mode >= 2) { absorb(work, 'IC', 99, 100); absorb(work, 'IL', 49, 50); } if (mode >= 1) { absorb(work, 'VC', 95, 100); absorb(work, 'VL', 45, 50); } absorb(work, 'XC', 90, 100); absorb(work, 'XL', 40, 50); absorb(work, 'L', 50, 90); work.acc += 'X'.repeat(Math.floor(work.val / 10)); work.val %= 10; absorb(work, 'IX', 9, 10); absorb(work, 'IV', 4, 5); absorb(work, 'V', 5, 9); work.acc += 'I'.repeat(work.val); return work.acc; } function absorb(valAcc, token, lower, upper) { if (valAcc.val >= lower && valAcc.val < upper) { valAcc.val -= lower; valAcc.acc += token; } }