UNPKG

@mojir/lits

Version:

Lits is a Lisp dialect implemented in TypeScript

1,300 lines (1,270 loc) 1.12 MB
import fs from 'node:fs'; import path from 'node:path'; /****************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ /* global Reflect, Promise, SuppressedError, Symbol */ var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; function __extends(d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } var __assign = function() { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; function __values(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); } function __read(o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; } function __spreadArray(to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); } typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { var e = new Error(message); return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; function getCodeMarker(sourceCodeInfo) { if (!sourceCodeInfo.position || !sourceCodeInfo.code) return ''; var leftPadding = sourceCodeInfo.position.column - 1; var rightPadding = sourceCodeInfo.code.length - leftPadding - 1; return "".concat(' '.repeat(Math.max(leftPadding, 0)), "^").concat(' '.repeat(Math.max(rightPadding, 0))); } function getLitsErrorMessage(message, sourceCodeInfo) { if (!sourceCodeInfo) { return message; } var location = "".concat(sourceCodeInfo.position.line, ":").concat(sourceCodeInfo.position.column); var filePathLine = sourceCodeInfo.filePath ? "\n".concat(sourceCodeInfo.filePath, ":").concat(location) : "\nLocation ".concat(location); var codeLine = "\n".concat(sourceCodeInfo.code); var codeMarker = "\n".concat(getCodeMarker(sourceCodeInfo)); return "".concat(message).concat(filePathLine).concat(codeLine).concat(codeMarker); } var RecurSignal = /** @class */ (function (_super) { __extends(RecurSignal, _super); function RecurSignal(params) { var _this = _super.call(this, "recur, params: ".concat(params)) || this; Object.setPrototypeOf(_this, RecurSignal.prototype); _this.name = 'RecurSignal'; _this.params = params; return _this; } return RecurSignal; }(Error)); var LitsError = /** @class */ (function (_super) { __extends(LitsError, _super); function LitsError(err, sourceCodeInfo) { var _this = this; var message = err instanceof Error ? err.message : "".concat(err); _this = _super.call(this, getLitsErrorMessage(message, sourceCodeInfo)) || this; _this.shortMessage = message; _this.sourceCodeInfo = sourceCodeInfo; Object.setPrototypeOf(_this, LitsError.prototype); _this.name = 'LitsError'; return _this; } LitsError.prototype.getCodeMarker = function () { return this.sourceCodeInfo && getCodeMarker(this.sourceCodeInfo); }; return LitsError; }(Error)); var UserDefinedError = /** @class */ (function (_super) { __extends(UserDefinedError, _super); function UserDefinedError(message, sourceCodeInfo) { var _this = _super.call(this, message, sourceCodeInfo) || this; _this.userMessage = message; Object.setPrototypeOf(_this, UserDefinedError.prototype); _this.name = 'UserDefinedError'; return _this; } return UserDefinedError; }(LitsError)); var AssertionError = /** @class */ (function (_super) { __extends(AssertionError, _super); function AssertionError(message, sourceCodeInfo) { var _this = _super.call(this, message, sourceCodeInfo) || this; Object.setPrototypeOf(_this, AssertionError.prototype); _this.name = 'AssertionError'; return _this; } return AssertionError; }(LitsError)); var UndefinedSymbolError = /** @class */ (function (_super) { __extends(UndefinedSymbolError, _super); function UndefinedSymbolError(symbolName, sourceCodeInfo) { var _this = this; var message = "Undefined symbol '".concat(symbolName, "'."); _this = _super.call(this, message, sourceCodeInfo) || this; _this.symbol = symbolName; Object.setPrototypeOf(_this, UndefinedSymbolError.prototype); _this.name = 'UndefinedSymbolError'; return _this; } return UndefinedSymbolError; }(LitsError)); var specialExpressionTypes = { '??': 0, '&&': 1, '||': 2, 'array': 3, 'cond': 4, '0_def': 5, 'defined?': 6, // '0_defn': 7, 'block': 7, 'doseq': 8, '0_lambda': 9, 'for': 10, // 'function': 10, 'if': 11, 'let': 12, 'loop': 13, 'object': 14, 'recur': 15, 'switch': 16, 'throw': 17, 'try': 18, 'unless': 19, }; var NodeTypes = { Number: 1, String: 2, NormalExpression: 3, SpecialExpression: 4, UserDefinedSymbol: 5, NormalBuiltinSymbol: 6, SpecialBuiltinSymbol: 7, ReservedSymbol: 8, Binding: 9, Spread: 10, }; var NodeTypesSet = new Set(Object.values(NodeTypes)); function getNodeTypeName(type) { return Object.keys(NodeTypes).find(function (key) { return NodeTypes[key] === type; }); } // TODO, is this needed? function isNodeType(type) { return typeof type === 'number' && NodeTypesSet.has(type); } var functionTypes = [ 'UserDefined', 'Partial', 'Comp', 'Constantly', 'Juxt', 'Complement', 'EveryPred', 'SomePred', 'Fnull', 'Builtin', 'SpecialBuiltin', 'NativeJsFunction', ]; var functionTypeSet = new Set(functionTypes); function isFunctionType(type) { return typeof type === 'string' && functionTypeSet.has(type); } var FUNCTION_SYMBOL = '^^fn^^'; var REGEXP_SYMBOL = '^^re^^'; function isLitsFunction$1(func) { if (func === null || typeof func !== 'object') return false; return FUNCTION_SYMBOL in func && 'functionType' in func && isFunctionType(func.functionType); } function isNode(value) { if (!Array.isArray(value) || value.length < 2) return false; return isNodeType(value[0]); } function valueToString(value) { if (isLitsFunction$1(value)) // eslint-disable-next-line ts/no-unsafe-member-access return "<function ".concat(value.name || '\u03BB', ">"); if (isNode(value)) return "".concat(getNodeTypeName(value[0]), "-node"); if (value === null) return 'null'; if (typeof value === 'object' && value instanceof RegExp) return "".concat(value); if (typeof value === 'object' && value instanceof Error) return value.toString(); return JSON.stringify(value); } function getSourceCodeInfo(anyValue, sourceCodeInfo) { var _a; // eslint-disable-next-line ts/no-unsafe-return, ts/no-unsafe-member-access return (_a = anyValue === null || anyValue === void 0 ? void 0 : anyValue.sourceCodeInfo) !== null && _a !== void 0 ? _a : sourceCodeInfo; } function getAssertionError(typeName, value, sourceCodeInfo) { return new LitsError("Expected ".concat(typeName, ", got ").concat(valueToString(value), "."), getSourceCodeInfo(value, sourceCodeInfo)); } function isSymbolNode(node) { var nodeType = node[0]; return NodeTypes.UserDefinedSymbol === nodeType || NodeTypes.NormalBuiltinSymbol === nodeType || NodeTypes.SpecialBuiltinSymbol === nodeType; } function assertSymbolNode(node, sourceCodeInfo) { if (!isSymbolNode(node)) throw getAssertionError('SymbolNode', node, sourceCodeInfo); } function isUserDefinedSymbolNode(node) { return NodeTypes.UserDefinedSymbol === node[0]; } function asUserDefinedSymbolNode(node, sourceCodeInfo) { assertUserDefinedSymbolNode(node, sourceCodeInfo); return node; } function assertUserDefinedSymbolNode(node, sourceCodeInfo) { if (!isUserDefinedSymbolNode(node)) throw getAssertionError('UserDefinedSymbolNode', node, sourceCodeInfo); } function isNormalBuiltinSymbolNode(node) { return NodeTypes.NormalBuiltinSymbol === node[0]; } function isSpecialBuiltinSymbolNode(node) { return NodeTypes.SpecialBuiltinSymbol === node[0]; } function isNormalExpressionNode(node) { return node[0] === NodeTypes.NormalExpression; } function isNormalExpressionNodeWithName(node) { if (!isNormalExpressionNode(node)) { return false; } return isSymbolNode(node[1][0]); } function isSpreadNode(node) { return node[0] === NodeTypes.Spread; } var getUndefinedSymbols = function (ast, contextStack, builtin, evaluateNode) { var e_1, _a; var _b; var nodes = Array.isArray(ast) ? ast : [[NodeTypes.SpecialExpression, [specialExpressionTypes.block, ast.body]]]; var unresolvedSymbols = new Set(); try { for (var nodes_1 = __values(nodes), nodes_1_1 = nodes_1.next(); !nodes_1_1.done; nodes_1_1 = nodes_1.next()) { var subNode = nodes_1_1.value; (_b = findUnresolvedSymbolsInNode(subNode, contextStack, builtin, evaluateNode)) === null || _b === void 0 ? void 0 : _b.forEach(function (symbol) { return unresolvedSymbols.add(symbol); }); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (nodes_1_1 && !nodes_1_1.done && (_a = nodes_1.return)) _a.call(nodes_1); } finally { if (e_1) throw e_1.error; } } return unresolvedSymbols; }; function findUnresolvedSymbolsInNode(node, contextStack, builtin, evaluateNode) { var e_2, _a; var _b, _c; var nodeType = node[0]; switch (nodeType) { case NodeTypes.UserDefinedSymbol: { var symbolNode = node; var lookUpResult = contextStack.lookUp(symbolNode); if (lookUpResult === null) return new Set([symbolNode[1]]); return null; } case NodeTypes.NormalBuiltinSymbol: case NodeTypes.SpecialBuiltinSymbol: case NodeTypes.String: case NodeTypes.Number: case NodeTypes.ReservedSymbol: case NodeTypes.Binding: return null; case NodeTypes.NormalExpression: { var normalExpressionNode = node; var unresolvedSymbols_1 = new Set(); if (isNormalExpressionNodeWithName(normalExpressionNode)) { var _d = __read(normalExpressionNode, 2), _e = __read(_d[1], 1), symbolNode = _e[0]; if (isUserDefinedSymbolNode(symbolNode)) { var lookUpResult = contextStack.lookUp(symbolNode); if (lookUpResult === null) unresolvedSymbols_1.add(symbolNode[1]); } } else { var _f = __read(normalExpressionNode, 2), _g = __read(_f[1], 1), expressionNode = _g[0]; (_b = findUnresolvedSymbolsInNode(expressionNode, contextStack, builtin, evaluateNode)) === null || _b === void 0 ? void 0 : _b.forEach(function (symbol) { return unresolvedSymbols_1.add(symbol); }); } try { for (var _h = __values(normalExpressionNode[1][1]), _j = _h.next(); !_j.done; _j = _h.next()) { var subNode = _j.value; (_c = findUnresolvedSymbolsInNode(subNode, contextStack, builtin, evaluateNode)) === null || _c === void 0 ? void 0 : _c.forEach(function (symbol) { return unresolvedSymbols_1.add(symbol); }); } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (_j && !_j.done && (_a = _h.return)) _a.call(_h); } finally { if (e_2) throw e_2.error; } } return unresolvedSymbols_1; } case NodeTypes.SpecialExpression: { var specialExpressionNode = node; var specialExpressionType = specialExpressionNode[1][0]; var specialExpression = builtin.specialExpressions[specialExpressionType]; var castedGetUndefinedSymbols = specialExpression.getUndefinedSymbols; return castedGetUndefinedSymbols(specialExpressionNode, contextStack, { getUndefinedSymbols: getUndefinedSymbols, builtin: builtin, evaluateNode: evaluateNode, }); } case NodeTypes.Spread: return findUnresolvedSymbolsInNode(node[1], contextStack, builtin, evaluateNode); /* v8 ignore next 2 */ default: throw new LitsError("Unhandled node type: ".concat(nodeType), node[2]); } } function getRangeString(options) { var hasUpperAndLowerBound = (typeof options.gt === 'number' || typeof options.gte === 'number') && (typeof options.lt === 'number' || typeof options.lte === 'number'); if (hasUpperAndLowerBound) { return "".concat(typeof options.gt === 'number' ? "".concat(options.gt, " < n ") : "".concat(options.gte, " <= n ")).concat(typeof options.lt === 'number' ? "< ".concat(options.lt) : "<= ".concat(options.lte)); } else if (typeof options.gt === 'number' || typeof options.gte === 'number') { return "".concat(typeof options.gt === 'number' ? "n > ".concat(options.gt) : "n >= ".concat(options.gte)); } else if (typeof options.lt === 'number' || typeof options.lte === 'number') { return "".concat(typeof options.lt === 'number' ? "n < ".concat(options.lt) : "n <= ".concat(options.lte)); } else { return ''; } } function getSignString(options) { return options.positive ? 'positive' : options.negative ? 'negative' : options.nonNegative ? 'non negative' : options.nonPositive ? 'non positive' : options.nonZero ? 'non zero' : ''; } function getNumberTypeName(options) { if (options.zero) return 'zero'; var sign = getSignString(options); var numberType = options.integer ? 'integer' : 'number'; var finite = options.finite ? 'finite' : ''; var range = getRangeString(options); return [sign, finite, numberType, range].filter(function (x) { return !!x; }).join(' '); } function isNumber(value, options) { if (options === void 0) { options = {}; } if (typeof value !== 'number') return false; if (Number.isNaN(value)) return false; if (options.integer && !Number.isInteger(value)) return false; if (options.finite && !Number.isFinite(value)) return false; if (options.zero && value !== 0) return false; if (options.nonZero && value === 0) return false; if (options.positive && value <= 0) return false; if (options.negative && value >= 0) return false; if (options.nonPositive && value > 0) return false; if (options.nonNegative && value < 0) return false; if (typeof options.gt === 'number' && value <= options.gt) return false; if (typeof options.gte === 'number' && value < options.gte) return false; if (typeof options.lt === 'number' && value >= options.lt) return false; if (typeof options.lte === 'number' && value > options.lte) return false; return true; } function assertNumber(value, sourceCodeInfo, options) { if (options === void 0) { options = {}; } if (!isNumber(value, options)) { throw new LitsError("Expected ".concat(getNumberTypeName(options), ", got ").concat(valueToString(value), "."), getSourceCodeInfo(value, sourceCodeInfo)); } } function asNumber(value, sourceCodeInfo, options) { if (options === void 0) { options = {}; } assertNumber(value, sourceCodeInfo, options); return value; } function isNonUndefined(value) { return value !== undefined; } function asNonUndefined(value, sourceCodeInfo) { assertNonUndefined(value, sourceCodeInfo); return value; } function assertNonUndefined(value, sourceCodeInfo) { if (!isNonUndefined(value)) throw new LitsError('Unexpected undefined', getSourceCodeInfo(value, sourceCodeInfo)); } function isUnknownRecord(value) { return value !== null && typeof value === 'object' && !Array.isArray(value); } function assertUnknownRecord(value, sourceCodeInfo) { if (!isUnknownRecord(value)) { throw new LitsError("Expected ".concat('UnknownRecord', ", got ").concat(valueToString(value), "."), getSourceCodeInfo(value, sourceCodeInfo)); } } function isLitsFunction(value) { if (value === null || typeof value !== 'object') return false; return !!value[FUNCTION_SYMBOL]; } function isAny(value) { // TODO weak test return value !== undefined; } function asAny(value, sourceCodeInfo) { assertAny(value, sourceCodeInfo); return value; } function assertAny(value, sourceCodeInfo) { if (!isAny(value)) throw getAssertionError('not undefined', value, sourceCodeInfo); } function isSeq(value) { return Array.isArray(value) || typeof value === 'string'; } function asSeq(value, sourceCodeInfo) { assertSeq(value, sourceCodeInfo); return value; } function assertSeq(value, sourceCodeInfo) { if (!isSeq(value)) throw getAssertionError('string or array', value, sourceCodeInfo); } function isObj(value) { return !(value === null || typeof value !== 'object' || Array.isArray(value) || value instanceof RegExp || isLitsFunction(value) || isRegularExpression(value)); } function assertObj(value, sourceCodeInfo) { if (!isObj(value)) throw getAssertionError('object', value, sourceCodeInfo); } function isColl(value) { return isSeq(value) || isObj(value); } function asColl(value, sourceCodeInfo) { assertColl(value, sourceCodeInfo); return value; } function assertColl(value, sourceCodeInfo) { if (!isColl(value)) throw getAssertionError('string, array or object', value, sourceCodeInfo); } function isRegularExpression(regexp) { if (regexp === null || typeof regexp !== 'object') return false; return !!regexp[REGEXP_SYMBOL]; } function assertRegularExpression(value, sourceCodeInfo) { if (!isRegularExpression(value)) throw getAssertionError('RegularExpression', value, sourceCodeInfo); } function isStringOrRegularExpression(value) { return isRegularExpression(value) || typeof value === 'string'; } function assertStringOrRegularExpression(value, sourceCodeInfo) { if (!isStringOrRegularExpression(value)) throw getAssertionError('string or RegularExpression', value, sourceCodeInfo); } function isFunctionLike(value) { if (typeof value === 'number') return true; if (isColl(value)) return true; if (isLitsFunction(value)) return true; return false; } function asFunctionLike(value, sourceCodeInfo) { assertFunctionLike(value, sourceCodeInfo); return value; } function assertFunctionLike(value, sourceCodeInfo) { if (!isFunctionLike(value)) throw getAssertionError('FunctionLike', value, sourceCodeInfo); } function arityAcceptsMin(arity, nbrOfParams) { var min = arity.min; if (typeof min === 'number' && nbrOfParams < min) { return false; } return true; } function getCommonArityFromFunctions(params) { return params.reduce(function (acc, param) { if (acc === null) { return null; } var arity = (typeof param === 'number' || isColl(param)) ? toFixedArity(1) : param.arity; var aMin = arity.min, aMax = arity.max; var bMin = acc.min, bMax = acc.max; var min = typeof aMin === 'number' && typeof bMin === 'number' ? Math.max(aMin, bMin) : typeof aMin === 'number' ? aMin : typeof bMin === 'number' ? bMin : undefined; var max = typeof aMax === 'number' && typeof bMax === 'number' ? Math.min(aMax, bMax) : typeof aMax === 'number' ? aMax : typeof bMax === 'number' ? bMax : undefined; if (typeof min === 'number' && typeof max === 'number' && min > max) { return null; } return { min: min, max: max }; }, {}); } function getArityFromFunction(param) { return (typeof param === 'number' || isColl(param)) ? toFixedArity(1) : param.arity; } function assertNumberOfParams(arity, length, sourceCodeInfo) { var min = arity.min, max = arity.max; if (typeof min === 'number' && length < min) { throw new LitsError("Wrong number of arguments, expected at least ".concat(min, ", got ").concat(valueToString(length), "."), sourceCodeInfo); } if (typeof max === 'number' && length > max) { throw new LitsError("Wrong number of arguments, expected at most ".concat(max, ", got ").concat(valueToString(length), "."), sourceCodeInfo); } } function canBeOperator(count) { if (typeof count.max === 'number' && count.max < 2) { return false; } if (typeof count.min === 'number' && count.min > 2) { return false; } return true; } function toFixedArity(arity) { return { min: arity, max: arity }; } var bitwiseNormalExpression = { '<<': { evaluate: function (_a, sourceCodeInfo) { var _b = __read(_a, 2), num = _b[0], count = _b[1]; assertNumber(num, sourceCodeInfo, { integer: true }); assertNumber(count, sourceCodeInfo, { integer: true, nonNegative: true }); return num << count; }, arity: toFixedArity(2), }, '>>': { evaluate: function (_a, sourceCodeInfo) { var _b = __read(_a, 2), num = _b[0], count = _b[1]; assertNumber(num, sourceCodeInfo, { integer: true }); assertNumber(count, sourceCodeInfo, { integer: true, nonNegative: true }); return num >> count; }, arity: toFixedArity(2), }, '>>>': { evaluate: function (_a, sourceCodeInfo) { var _b = __read(_a, 2), num = _b[0], count = _b[1]; assertNumber(num, sourceCodeInfo, { integer: true }); assertNumber(count, sourceCodeInfo, { integer: true, nonNegative: true }); return num >>> count; }, arity: toFixedArity(2), }, 'bit-not': { evaluate: function (_a, sourceCodeInfo) { var _b = __read(_a, 1), num = _b[0]; assertNumber(num, sourceCodeInfo, { integer: true }); return ~num; }, arity: toFixedArity(1), }, '&': { evaluate: function (_a, sourceCodeInfo) { var _b = __read(_a), first = _b[0], rest = _b.slice(1); assertNumber(first, sourceCodeInfo, { integer: true }); return rest.reduce(function (result, value) { assertNumber(value, sourceCodeInfo, { integer: true }); return result & value; }, first); }, arity: { min: 2 }, }, 'bit-and-not': { evaluate: function (_a, sourceCodeInfo) { var _b = __read(_a), first = _b[0], rest = _b.slice(1); assertNumber(first, sourceCodeInfo, { integer: true }); return rest.reduce(function (result, value) { assertNumber(value, sourceCodeInfo, { integer: true }); return result & ~value; }, first); }, arity: { min: 2 }, }, '|': { evaluate: function (_a, sourceCodeInfo) { var _b = __read(_a), first = _b[0], rest = _b.slice(1); assertNumber(first, sourceCodeInfo, { integer: true }); return rest.reduce(function (result, value) { assertNumber(value, sourceCodeInfo, { integer: true }); return result | value; }, first); }, arity: { min: 2 }, }, 'xor': { evaluate: function (_a, sourceCodeInfo) { var _b = __read(_a), first = _b[0], rest = _b.slice(1); assertNumber(first, sourceCodeInfo, { integer: true }); return rest.reduce(function (result, value) { assertNumber(value, sourceCodeInfo, { integer: true }); return result ^ value; }, first); }, arity: { min: 2 }, }, 'bit-flip': { evaluate: function (_a, sourceCodeInfo) { var _b = __read(_a, 2), num = _b[0], index = _b[1]; assertNumber(num, sourceCodeInfo, { integer: true }); assertNumber(index, sourceCodeInfo, { integer: true, nonNegative: true }); var mask = 1 << index; return (num ^= mask); }, arity: toFixedArity(2), }, 'bit-set': { evaluate: function (_a, sourceCodeInfo) { var _b = __read(_a, 2), num = _b[0], index = _b[1]; assertNumber(num, sourceCodeInfo, { integer: true }); assertNumber(index, sourceCodeInfo, { integer: true, nonNegative: true }); var mask = 1 << index; return (num |= mask); }, arity: toFixedArity(2), }, 'bit-clear': { evaluate: function (_a, sourceCodeInfo) { var _b = __read(_a, 2), num = _b[0], index = _b[1]; assertNumber(num, sourceCodeInfo, { integer: true }); assertNumber(index, sourceCodeInfo, { integer: true, nonNegative: true }); var mask = 1 << index; return (num &= ~mask); }, arity: toFixedArity(2), }, 'bit-test': { evaluate: function (_a, sourceCodeInfo) { var _b = __read(_a, 2), num = _b[0], index = _b[1]; assertNumber(num, sourceCodeInfo, { integer: true }); assertNumber(index, sourceCodeInfo, { integer: true, nonNegative: true }); var mask = 1 << index; return !!(num & mask); }, arity: toFixedArity(2), }, }; function isString(value, options) { if (options === void 0) { options = {}; } if (typeof value !== 'string') return false; if (options.nonEmpty && value.length === 0) return false; if (options.char && value.length !== 1) return false; return true; } function assertString(value, sourceCodeInfo, options) { if (options === void 0) { options = {}; } if (!isString(value, options)) { throw getAssertionError("".concat(options.nonEmpty ? 'non empty string' : options.char ? 'character' : 'string'), value, sourceCodeInfo); } } function asString(value, sourceCodeInfo, options) { if (options === void 0) { options = {}; } assertString(value, sourceCodeInfo, options); return value; } function isStringOrNumber(value) { return typeof value === 'string' || typeof value === 'number'; } function asStringOrNumber(value, sourceCodeInfo) { assertStringOrNumber(value, sourceCodeInfo); return value; } function assertStringOrNumber(value, sourceCodeInfo) { if (!isStringOrNumber(value)) throw getAssertionError('string or number', value, sourceCodeInfo); } function collHasKey(coll, key) { if (!isColl(coll)) return false; if (typeof coll === 'string' || Array.isArray(coll)) { if (!isNumber(key, { integer: true })) return false; return key >= 0 && key < coll.length; } return !!Object.getOwnPropertyDescriptor(coll, key); } function compare(a, b, sourceCodeInfo) { assertStringOrNumber(a, sourceCodeInfo); assertStringOrNumber(b, sourceCodeInfo); if (typeof a === 'string' && typeof b === 'string') { return a < b ? -1 : a > b ? 1 : 0; } if (typeof a === 'number' && typeof b === 'number') { return Math.sign((a) - (b)); } throw new LitsError("Cannot compare values of different types: ".concat(typeof a, " and ").concat(typeof b), sourceCodeInfo); } function deepEqual(a, b, sourceCodeInfo) { if (a === b) return true; if (typeof a === 'number' && typeof b === 'number') return approxEqual(a, b); if (Array.isArray(a) && Array.isArray(b)) { if (a.length !== b.length) return false; for (var i = 0; i < a.length; i += 1) { if (!deepEqual(asAny(a[i], sourceCodeInfo), asAny(b[i], sourceCodeInfo), sourceCodeInfo)) return false; } return true; } if (isRegularExpression(a) && isRegularExpression(b)) return a.s === b.s && a.f === b.f; if (isUnknownRecord(a) && isUnknownRecord(b)) { var aKeys = Object.keys(a); var bKeys = Object.keys(b); if (aKeys.length !== bKeys.length) return false; for (var i = 0; i < aKeys.length; i += 1) { var key = asString(aKeys[i], sourceCodeInfo); if (!deepEqual(a[key], b[key], sourceCodeInfo)) return false; } return true; } return false; } function toNonNegativeInteger(num) { return Math.max(0, Math.ceil(num)); } function toAny(value) { return (value !== null && value !== void 0 ? value : null); } function clone(value) { if (isObj(value)) { return Object.entries(value).reduce(function (result, entry) { var _a = __read(entry, 2), key = _a[0], val = _a[1]; result[key] = clone(val); return result; }, {}); } if (Array.isArray(value)) // eslint-disable-next-line ts/no-unsafe-return return value.map(function (item) { return clone(item); }); return value; } function cloneColl(value) { return clone(value); } function joinSets() { var e_1, _a; var results = []; for (var _i = 0; _i < arguments.length; _i++) { results[_i] = arguments[_i]; } var result = new Set(); try { for (var results_1 = __values(results), results_1_1 = results_1.next(); !results_1_1.done; results_1_1 = results_1.next()) { var symbols = results_1_1.value; symbols.forEach(function (symbol) { return result.add(symbol); }); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (results_1_1 && !results_1_1.done && (_a = results_1.return)) _a.call(results_1); } finally { if (e_1) throw e_1.error; } } return result; } function addToSet(target, source) { source.forEach(function (symbol) { return target.add(symbol); }); } var EPSILON = 1e-10; function approxEqual(a, b, epsilon) { if (epsilon === void 0) { epsilon = EPSILON; } if (a === b) { return true; } var diff = Math.abs(a - b); if (a === 0 || b === 0 || diff < epsilon) { // Use absolute error for values near zero return diff < epsilon; } var absA = Math.abs(a); var absB = Math.abs(b); // Use relative error for larger values return diff / (absA + absB) < epsilon; } function approxZero(value) { return Math.abs(value) < EPSILON; } function smartTrim(str, minIndent) { var _a, _b; if (minIndent === void 0) { minIndent = 0; } var lines = str.split('\n'); while ((_a = lines[0]) === null || _a === void 0 ? void 0 : _a.match(/^\s*$/)) { lines.shift(); // Remove leading empty lines } while ((_b = lines[lines.length - 1]) === null || _b === void 0 ? void 0 : _b.match(/^\s*$/)) { lines.pop(); // Remove trailing empty lines } var indent = lines.reduce(function (acc, line) { if (line.match(/^\s*$/)) return acc; // Skip empty lines var lineIndent = line.match(/^\s*/)[0].length; return Math.min(acc, lineIndent); }, Infinity); return lines.map(function (line) { return ' '.repeat(minIndent) + line.slice(indent); }).join('\n').trimEnd(); } // isArray not needed, use Array.isArary function asArray(value, sourceCodeInfo) { assertArray(value, sourceCodeInfo); return value; } function assertArray(value, sourceCodeInfo) { if (!Array.isArray(value)) throw getAssertionError('array', value, sourceCodeInfo); } function isStringArray(value) { return Array.isArray(value) && value.every(function (v) { return typeof v === 'string'; }); } function assertStringArray(value, sourceCodeInfo) { if (!isStringArray(value)) throw getAssertionError('array of strings', value, sourceCodeInfo); } function isCharArray(value) { return Array.isArray(value) && value.every(function (v) { return typeof v === 'string' && v.length === 1; }); } function assertCharArray(value, sourceCodeInfo) { if (!isCharArray(value)) throw getAssertionError('array of strings', value, sourceCodeInfo); } function mapObjects(_a) { var colls = _a.colls, contextStack = _a.contextStack, executeFunction = _a.executeFunction, fn = _a.fn, sourceCodeInfo = _a.sourceCodeInfo; assertObj(colls[0], sourceCodeInfo); var keys = Object.keys(colls[0]); var params = {}; colls.forEach(function (obj) { assertObj(obj, sourceCodeInfo); var objKeys = Object.keys(obj); if (objKeys.length !== keys.length) { throw new LitsError("All objects must have the same keys. Expected: ".concat(keys.join(', '), ". Found: ").concat(objKeys.join(', ')), sourceCodeInfo); } if (!objKeys.every(function (key) { return keys.includes(key); })) { throw new LitsError("All objects must have the same keys. Expected: ".concat(keys.join(', '), ". Found: ").concat(objKeys.join(', ')), sourceCodeInfo); } Object.entries(obj).forEach(function (_a) { var _b = __read(_a, 2), key = _b[0], value = _b[1]; if (!params[key]) params[key] = []; params[key].push(value); }); }); return keys.reduce(function (result, key) { result[key] = executeFunction(fn, params[key], contextStack, sourceCodeInfo); return result; }, {}); } function cloneAndGetMeta(originalColl, keys, sourceCodeInfo) { var coll = cloneColl(originalColl); var butLastKeys = keys.slice(0, keys.length - 1); var innerCollMeta = butLastKeys.reduce(function (result, key) { var resultColl = result.coll; var newResultColl; if (Array.isArray(resultColl)) { assertNumber(key, sourceCodeInfo); newResultColl = asColl(resultColl[key], sourceCodeInfo); } else { assertObj(resultColl, sourceCodeInfo); assertString(key, sourceCodeInfo); if (!collHasKey(result.coll, key)) resultColl[key] = {}; newResultColl = asColl(resultColl[key], sourceCodeInfo); } return { coll: newResultColl, parent: resultColl }; }, { coll: coll, parent: {} }); return { coll: coll, innerCollMeta: innerCollMeta }; } function get(coll, key) { if (isObj(coll)) { if (typeof key === 'string' && collHasKey(coll, key)) return toAny(coll[key]); } else { if (isNumber(key, { nonNegative: true, integer: true }) && key >= 0 && key < coll.length) return toAny(coll[key]); } return undefined; } function update(coll, key, fn, params, contextStack, executeFunction, sourceCodeInfo) { if (isObj(coll)) { assertString(key, sourceCodeInfo); var result = __assign({}, coll); result[key] = executeFunction(fn, __spreadArray([result[key]], __read(params), false), contextStack, sourceCodeInfo); return result; } else { assertNumber(key, sourceCodeInfo); var intKey_1 = toNonNegativeInteger(key); assertNumber(intKey_1, sourceCodeInfo, { lte: coll.length }); if (Array.isArray(coll)) { var result = coll.map(function (elem, index) { if (intKey_1 === index) return executeFunction(fn, __spreadArray([elem], __read(params), false), contextStack, sourceCodeInfo); return elem; }); if (intKey_1 === coll.length) result[intKey_1] = executeFunction(fn, __spreadArray([undefined], __read(params), false), contextStack, sourceCodeInfo); return result; } else { var result = coll.split('').map(function (elem, index) { if (intKey_1 === index) { return asString(executeFunction(fn, __spreadArray([elem], __read(params), false), contextStack, sourceCodeInfo), sourceCodeInfo, { char: true, }); } return elem; }); if (intKey_1 === coll.length) { result[intKey_1] = asString(executeFunction(fn, __spreadArray([undefined], __read(params), false), contextStack, sourceCodeInfo), sourceCodeInfo, { char: true, }); } return result.join(''); } } } function assoc(coll, key, value, sourceCodeInfo) { assertColl(coll, sourceCodeInfo); assertStringOrNumber(key, sourceCodeInfo); if (Array.isArray(coll) || typeof coll === 'string') { assertNumber(key, sourceCodeInfo, { integer: true }); assertNumber(key, sourceCodeInfo, { gte: 0 }); assertNumber(key, sourceCodeInfo, { lte: coll.length }); if (typeof coll === 'string') { assertString(value, sourceCodeInfo, { char: true }); return "".concat(coll.slice(0, key)).concat(value).concat(coll.slice(key + 1)); } var copy_1 = __spreadArray([], __read(coll), false); copy_1[key] = value; return copy_1; } assertString(key, sourceCodeInfo); var copy = __assign({}, coll); copy[key] = value; return copy; } var collectionNormalExpression = { 'filter': { evaluate: function (_a, sourceCodeInfo, contextStack, _b) { var _c = __read(_a, 2), coll = _c[0], fn = _c[1]; var executeFunction = _b.executeFunction; assertColl(coll, sourceCodeInfo); assertFunctionLike(fn, sourceCodeInfo); if (Array.isArray(coll)) { var result = coll.filter(function (elem) { return executeFunction(fn, [elem], contextStack, sourceCodeInfo); }); return result; } if (isString(coll)) { return coll .split('') .filter(function (elem) { return executeFunction(fn, [elem], contextStack, sourceCodeInfo); }) .join(''); } return Object.entries(coll) .filter(function (_a) { var _b = __read(_a, 2), value = _b[1]; return executeFunction(fn, [value], contextStack, sourceCodeInfo); }) .reduce(function (result, _a) { var _b = __read(_a, 2), key = _b[0], value = _b[1]; result[key] = value; return result; }, {}); }, arity: toFixedArity(2), }, 'filteri': { evaluate: function (_a, sourceCodeInfo, contextStack, _b) { var _c = __read(_a, 2), coll = _c[0], fn = _c[1]; var executeFunction = _b.executeFunction; assertColl(coll, sourceCodeInfo); assertFunctionLike(fn, sourceCodeInfo); if (Array.isArray(coll)) { var result = coll.filter(function (elem, index) { return executeFunction(fn, [elem, index], contextStack, sourceCodeInfo); }); return result; } if (isString(coll)) { return coll .split('') .filter(function (elem, index) { return executeFunction(fn, [elem, index], contextStack, sourceCodeInfo); }) .join(''); } return Object.entries(coll) .filter(function (_a) { var _b = __read(_a, 2), key = _b[0], value = _b[1]; return executeFunction(fn, [value, key], contextStack, sourceCodeInfo); }) .reduce(function (result, _a) { var _b = __read(_a, 2), key = _b[0], value = _b[1]; result[key] = value; return result; }, {}); }, arity: toFixedArity(2), }, 'map': { evaluate: function (params, sourceCodeInfo, contextStack, _a) { var executeFunction = _a.executeFunction; var fn = asFunctionLike(params.at(-1), sourceCodeInfo); if (isObj(params[0])) { return mapObjects({ colls: params.slice(0, -1), fn: fn, sourceCodeInfo: sourceCodeInfo, contextStack: contextStack, executeFunction: executeFunction, }); } var seqs = params.slice(0, -1); assertSeq(seqs[0], sourceCodeInfo); var isStr = typeof seqs[0] === 'string'; var len = seqs[0].length; seqs.slice(1).forEach(function (seq) { if (isStr) { assertString(seq, sourceCodeInfo); } else { assertArray(seq, sourceCodeInfo); } len = Math.min(len, seq.length); }); var paramArray = []; var _loop_1 = function (i) { paramArray.push(seqs.map(function (seq) { return seq[i]; })); }; for (var i = 0; i < len; i++) { _loop_1(i); } var mapped = paramArray.map(function (p) { return executeFunction(fn, p, contextStack, sourceCodeInfo); }); if (!isStr) { return mapped; } mapped.forEach(function (char) { return assertString(char, sourceCodeInfo); }); return mapped.join(''); }, arity: { min: 2 }, }, 'mapi': { evaluate: function (_a, sourceCodeInfo, contextStack, _b) { var _c = __read(_a, 2), coll = _c[0], fn = _c[1]; var executeFunction = _b.executeFunction; assertColl(coll, sourceCodeInfo); assertFunctionLike(fn, sourceCodeInfo); if (Array.isArray(coll)) { return coll.map(function (elem, index) { return executeFunction(fn, [elem, index], contextStack, sourceCodeInfo); }); } if (isString(coll)) { return coll .split('') .map(function (elem, index) { return executeFunction(fn, [elem, index], contextStack, sourceCodeInfo); }) .join(''); } return Object.entries(coll) .reduce(function (acc, _a) { var _b = __read(_a, 2), key = _b[0], value = _b[1]; acc[key] = executeFunction(fn, [value, key], contextStack, sourceCodeInfo); return acc; }, {}); }, arity: toFixedArity(2), }, 'reduce': { evaluate: function (_a, sourceCodeInfo, contextStack, _b) { var _c = __read(_a, 3), coll = _c[0], fn = _c[1], initial = _c[2]; var executeFunction = _b.executeFunction; assertColl(coll, sourceCodeInfo); assertFunctionLike(fn, sourceCodeInfo); assertAny(initial, sourceCodeInfo); if (typeof coll === 'string') { assertString(initial, sourceCodeInfo); if (coll.length === 0) return initial; return coll.split('').reduce(function (result, elem) { return executeFunction(fn, [result, elem], contextStack, sourceCodeInfo); }, initial); } else if (Array.isArray(coll)) { if (coll.length === 0) return initial; return coll.reduce(function (result, elem) { return executeFunction(fn, [result, elem], contextStack, sourceCodeInfo); }, initial); } else { if (Object.keys(coll).length === 0) return initial; return Object.entries(coll).reduce(function (result, _a) { var _b = __read(_a, 2), elem = _b[1]; return executeFunction(fn, [result, elem], contextStack, sourceCodeInfo); }, initial); } }, arity: toFixedArity(3), }, 'reducei': { evaluate: function (_a, sourceCodeInfo, contextStack, _b) { var _c = __read(_a, 3), coll = _c[0], fn = _c[1], initial = _c[2]; var executeFunction = _b.executeFunction; assertColl(coll, sourceCodeInfo); assertFunctionLike(fn, sourceCodeInfo); assertAny(initial, sourceCodeInfo); if (typeof coll === 'string') { assertString(initial, sourceCodeInfo); if (coll.length === 0) return initial; return coll.split('').reduce(function (result, elem, index) { return executeFunction(fn, [result, elem, index], contextStack, sourceCodeInfo); }, initial); } else if (Array.isArray(coll)) { if (coll.length === 0) return initial; return coll.reduce(function (result, elem, index) { return executeFunction(fn, [result, elem, index], contextStack, sourceCodeInfo); }, initial); } else { if (Object.keys(coll).length === 0) return initial; return Object.entries(coll).reduce(function (result, _a) { var _b = __read(_a, 2), key = _b[0], elem = _b[1]; return executeFunction(fn, [result, elem, key], contextStack, sourceCodeInfo); }, initial); } }, arity: toFixedArity(3), }, 'reduce-right': { evaluate: function (_a, sourceCodeInfo, contextStack, _b) { var _c = __read(_a, 3), coll = _c[0], fn = _c[1], initial = _c[2]; var executeFunction = _b.executeFunction; assertColl(coll, sourceCodeInfo); assertFunctionLike(fn, sourceCodeInfo); assertAny(initial, sourceCodeInfo); if (typeof coll === 'string') { if (coll.length === 0) return initial; return coll.split('').reduceRight(function (result, elem) { return executeFunction(fn, [result, elem], contextStack, sourceCodeInfo); }, initial); } else if (Array.isArray(coll)) { if (coll.length === 0) return initial; return coll.reduceRight(function (result, elem) { return executeFunction(fn, [result, elem], contextStack, sourceCodeInfo); }, initial); } else { if (Object.keys(coll).length === 0) return initial; return Object.entries(coll).reduceRight(function (result, _a) { var _b = __read(_a, 2), elem = _b[1]; return executeFunction(fn, [result, elem], contextStack, sourceCodeInfo); }, initial); } }, arity