@extra2001/compute-engine
Version:
Symbolic computing and numeric evaluations for JavaScript and Node.js
414 lines (409 loc) • 12.8 kB
JavaScript
/** MathJSON 0.28.0 */
(function(global,factory){typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'],factory):(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.MathJson = {}));})(this, (function (exports) { 'use strict';
var MathJson = (() => {
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/math-json.ts
var math_json_exports = {};
__export(math_json_exports, {
dictionaryFromExpression: () => dictionaryFromExpression,
isFunctionObject: () => isFunctionObject,
isStringObject: () => isStringObject,
isSymbolObject: () => isSymbolObject,
mapArgs: () => mapArgs,
operand: () => operand,
operator: () => operator,
stringValue: () => stringValue,
symbol: () => symbol,
version: () => version
});
// src/common/json5.ts
var JSON5 = class {
static parse(input) {
const parser = new JSON5Parser(input);
const value = parser.parseValue();
parser.skipWhitespace();
if (!parser.isAtEnd()) {
throw parser.error(
`Unexpected token '${parser.currentChar()}' after parsing complete value`
);
}
return value;
}
};
var JSON5Parser = class {
constructor(input) {
this.index = 0;
this.text = input;
}
parseValue() {
this.skipWhitespace();
if (this.isAtEnd()) {
throw this.error("Unexpected end of input");
}
const ch = this.currentChar();
if (ch === "{") return this.parseObject();
if (ch === "[") return this.parseArray();
if (ch === '"' || ch === "'") return this.parseString();
if (ch === "-" || ch === "+" || ch >= "0" && ch <= "9" || ch === ".")
return this.parseNumber();
return this.parseIdentifier();
}
parseObject() {
const obj = {};
this.expectChar("{");
this.skipWhitespace();
if (this.currentChar() === "}") {
this.index++;
return obj;
}
while (true) {
this.skipWhitespace();
let key;
const ch = this.currentChar();
if (ch === '"' || ch === "'") {
key = this.parseString();
} else {
key = this.parseIdentifier();
}
this.skipWhitespace();
this.expectChar(":");
this.skipWhitespace();
const value = this.parseValue();
obj[key] = value;
this.skipWhitespace();
if (this.currentChar() === ",") {
this.index++;
this.skipWhitespace();
if (this.currentChar() === "}") {
this.index++;
break;
}
} else if (this.currentChar() === "}") {
this.index++;
break;
} else {
throw this.error(
`Expected ',' or '}' in object but found '${this.currentChar()}'`
);
}
}
return obj;
}
parseArray() {
const arr = [];
this.expectChar("[");
this.skipWhitespace();
if (this.currentChar() === "]") {
this.index++;
return arr;
}
while (true) {
this.skipWhitespace();
arr.push(this.parseValue());
this.skipWhitespace();
if (this.currentChar() === ",") {
this.index++;
this.skipWhitespace();
if (this.currentChar() === "]") {
this.index++;
break;
}
} else if (this.currentChar() === "]") {
this.index++;
break;
} else {
throw this.error(
`Expected ',' or ']' in array but found '${this.currentChar()}'`
);
}
}
return arr;
}
parseString() {
const quote = this.currentChar();
if (quote !== '"' && quote !== "'") {
throw this.error(`String should start with a quote, got '${quote}'`);
}
this.index++;
let result = "";
while (!this.isAtEnd()) {
const ch = this.currentChar();
if (ch === quote) {
this.index++;
return result;
}
if (ch === "\\") {
this.index++;
if (this.isAtEnd()) {
throw this.error("Unterminated escape sequence in string");
}
const esc = this.currentChar();
switch (esc) {
case "b":
result += "\b";
break;
case "f":
result += "\f";
break;
case "n":
result += "\n";
break;
case "r":
result += "\r";
break;
case "t":
result += " ";
break;
case "v":
result += "\v";
break;
case "\\":
result += "\\";
break;
case "'":
result += "'";
break;
case '"':
result += '"';
break;
case "0":
result += "\0";
break;
case "u": {
this.index++;
const hex = this.text.substr(this.index, 4);
if (!/^[0-9a-fA-F]{4}$/.test(hex)) {
throw this.error(`Invalid Unicode escape sequence: \\u${hex}`);
}
result += String.fromCharCode(parseInt(hex, 16));
this.index += 3;
break;
}
default:
result += esc;
}
this.index++;
} else {
result += ch;
this.index++;
}
}
throw this.error("Unterminated string literal");
}
parseNumber() {
const start = this.index;
if (this.text.startsWith("-Infinity", this.index)) {
this.index += "-Infinity".length;
return -Infinity;
}
if (this.text.startsWith("+Infinity", this.index)) {
this.index += "+Infinity".length;
return Infinity;
}
if (this.text.startsWith("Infinity", this.index)) {
this.index += "Infinity".length;
return Infinity;
}
while (!this.isAtEnd() && /[0-9+\-_.eE]/.test(this.currentChar())) {
this.index++;
}
const token = this.text.slice(start, this.index);
const normalized = token.replace(/_/g, "");
const num = Number(normalized);
if (isNaN(num)) {
throw this.error(`Invalid number: ${token}`);
}
return num;
}
parseIdentifier() {
const start = this.index;
const firstChar = this.currentChar();
if (!/[a-zA-Z$_]/.test(firstChar)) {
throw this.error(`Unexpected token '${firstChar}'`);
}
this.index++;
while (!this.isAtEnd()) {
const ch = this.currentChar();
if (!/[a-zA-Z0-9$_]/.test(ch)) break;
this.index++;
}
const token = this.text.slice(start, this.index);
if (token === "true") return true;
if (token === "false") return false;
if (token === "null") return null;
if (token === "Infinity") return Infinity;
if (token === "NaN") return NaN;
return token;
}
skipWhitespace() {
while (!this.isAtEnd()) {
const ch = this.currentChar();
if (/\s/.test(ch)) {
this.index++;
continue;
}
if (ch === "/") {
const next = this.peekChar(1);
if (next === "/") {
this.index += 2;
while (!this.isAtEnd() && this.currentChar() !== "\n") {
this.index++;
}
continue;
} else if (next === "*") {
this.index += 2;
while (!this.isAtEnd() && !(this.currentChar() === "*" && this.peekChar(1) === "/")) {
this.index++;
}
if (this.isAtEnd()) {
throw this.error("Unterminated multi-line comment");
}
this.index += 2;
continue;
}
}
break;
}
}
expectChar(expected) {
if (this.currentChar() !== expected) {
throw this.error(
`Expected '${expected}' but found '${this.currentChar()}'`
);
}
this.index++;
}
currentChar() {
return this.text[this.index];
}
peekChar(offset) {
return this.text[this.index + offset];
}
isAtEnd() {
return this.index >= this.text.length;
}
error(message) {
return new Error(`${message} at position ${this.index}`);
}
};
// src/math-json/utils.ts
function isSymbolObject(expr) {
return expr !== null && typeof expr === "object" && "sym" in expr;
}
function isStringObject(expr) {
return expr !== null && typeof expr === "object" && "str" in expr;
}
function isFunctionObject(expr) {
return expr !== null && typeof expr === "object" && "fn" in expr;
}
function stringValue(expr) {
if (expr === null || expr === void 0) return null;
if (typeof expr === "object" && "str" in expr) return expr.str;
if (typeof expr !== "string") return null;
if (expr.length < 2) return null;
if (expr.at(0) !== "'" || expr.at(-1) !== "'") return null;
return expr.substring(1, expr.length - 1);
}
function operator(expr) {
if (Array.isArray(expr)) return expr[0];
if (expr === null || expr === void 0) return "";
if (isFunctionObject(expr)) return expr.fn[0];
return "";
}
function operands(expr) {
if (Array.isArray(expr)) return expr.slice(1);
if (expr !== void 0 && isFunctionObject(expr)) return expr.fn.slice(1);
return [];
}
function operand(expr, n) {
if (Array.isArray(expr)) return expr[n] ?? null;
if (expr === null || !isFunctionObject(expr)) return null;
return expr.fn[n] ?? null;
}
function nops(expr) {
if (expr === null || expr === void 0) return 0;
if (Array.isArray(expr)) return Math.max(0, expr.length - 1);
if (isFunctionObject(expr)) return Math.max(0, expr.fn.length - 1);
return 0;
}
function symbol(expr) {
if (typeof expr === "string") {
if (/^[+-]?[0-9\.]/.test(expr)) return null;
if (expr.length >= 2 && expr[0] === "'" && expr[expr.length - 1] === "'")
return null;
return expr;
}
if (expr === null || expr === void 0) return null;
const s = isSymbolObject(expr) ? expr.sym : expr;
if (typeof s !== "string") return null;
return s;
}
function keyValuePair(expr) {
const h = operator(expr);
if (h === "KeyValuePair" || h === "Tuple" || h === "Pair") {
const [k, v] = operands(expr);
const key = stringValue(k);
if (!key) return null;
return [key, v ?? "Nothing"];
}
return null;
}
function dictionaryFromExpression(expr) {
if (expr === null) return null;
if (typeof expr === "object" && !("sym" in expr) && !("num" in expr) && !("str" in expr) && !("fn" in expr)) {
return expr;
}
if (typeof expr === "string" && expr[0] === "{" && expr[expr.length - 1] === "}") {
try {
return JSON5.parse(expr);
} catch {
return null;
}
}
const kv = keyValuePair(expr);
if (kv) return { [kv[0]]: kv[1] };
if (operator(expr) === "Dictionary") {
const result = {};
const ops = operands(expr);
for (let i = 1; i < nops(expr); i++) {
const kv2 = keyValuePair(ops[i]);
if (kv2) result[kv2[0]] = kv2[1];
}
return result;
}
return null;
}
function mapArgs(expr, fn) {
let args = null;
if (Array.isArray(expr)) args = expr;
if (isFunctionObject(expr)) args = expr.fn;
if (args === null) return [];
let i = 1;
const result = [];
while (i < args.length) {
result.push(fn(args[i]));
i += 1;
}
return result;
}
// src/math-json.ts
var version = "{{SDK_VERSION}}";
return __toCommonJS(math_json_exports);
})();
Object.assign(exports, MathJson); Object.defineProperty(exports, '__esModule', { value: true });}));