glisp
Version:
A simple lisp interpreter in JS.
1,206 lines (918 loc) • 32.1 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('ramda'), require('immutable'), require('mathjs'), require('iterall')) :
typeof define === 'function' && define.amd ? define(['exports', 'ramda', 'immutable', 'mathjs', 'iterall'], factory) :
(factory((global.GLISP = global.GLISP || {}),global.R,global.Immutable,global.math,global.iterall));
}(this, function (exports,R,I,M,iterall) { 'use strict';
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
return typeof obj;
} : function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj;
};
var defineProperty = function (obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
};
var _extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
var slicedToArray = function () {
function sliceIterator(arr, i) {
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"]) _i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
return function (arr, i) {
if (Array.isArray(arr)) {
return arr;
} else if (Symbol.iterator in Object(arr)) {
return sliceIterator(arr, i);
} else {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
};
}();
var toArray$1 = function (arr) {
return Array.isArray(arr) ? arr : Array.from(arr);
};
var toConsumableArray = function (arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
return arr2;
} else {
return Array.from(arr);
}
};
function isNumberString(string) {
return !Number.isNaN(parseFloat(string)) && !Number.isNaN(Number(string));
}
function isBignumberString(string) {
return string.endsWith('M') && isNumberString(string.slice(0, -1));
}
function createBignumber(string) {
return M.bignumber(string.replace(/M$/, ''));
}
function stripQuotes(string) {
return string.replace(/(^"|"$)/g, '');
}
function isFractionString(x) {
var _String$split = String(x).split('/');
var _String$split2 = toArray$1(_String$split);
var numerator = _String$split2[0];
var denominator = _String$split2[1];
var rest = _String$split2.slice(2);
return rest.length === 0 && isNumberString(numerator) && isNumberString(denominator);
}
function getMatchingStartingParens(x) {
return {
')': ['('],
'}': ['#{', '{'],
']': ['[']
}[x] || [];
}
function isEndingParen(x) {
return ['}', ')', ']'].includes(x);
}
function isStartingParen(x) {
return ['#{', '{', '(', '['].includes(x);
}
function serializeArray(x) {
return '[' + x.join(', ') + ']';
}
function conj(collection, item) {
if (I.List.isList(collection)) {
return collection.push(item);
}
if (I.Set.isSet(collection)) {
return collection.add(item);
}
if (I.OrderedSet.isOrderedSet(collection)) {
return collection.add(item);
}
if (I.Map.isMap(collection)) {
var _item = slicedToArray(item, 2);
var key = _item[0];
var value = _item[1];
return collection.set(key, value);
}
if (I.OrderedMap.isOrderedMap(collection)) {
var _item2 = slicedToArray(item, 2);
var _key = _item2[0];
var _value = _item2[1];
return collection.set(_key, _value);
}
if (I.Stack.isStack(collection)) {
return collection.push(item);
}
throw new Error('Collection is not an Immutable object');
}
function create(prototype) {
for (var _len = arguments.length, props = Array(_len > 1 ? _len - 1 : 0), _key2 = 1; _key2 < _len; _key2++) {
props[_key2 - 1] = arguments[_key2];
}
return Object.assign.apply(Object, [Object.create(prototype)].concat(props));
}
function isEven(x) {
return x % 2 === 0;
}
function isOdd(x) {
return x % 2 === 1;
}
function transformFnToMacro(fn) {
Object.defineProperty(fn, 'isMacro', {
value: true
});
return fn;
}
function isMacro(fn) {
return fn.isMacro;
}
function canExecuteForm(form) {
return I.Stack.isStack(form) && form.size > 0;
}
var reduce = R.curry(function (reducer, initial, collection) {
var reduced = initial;
iterall.forEach(collection, function (item) {
reduced = reducer(reduced, item);
});
return reduced;
});
var conjunct = R.curry(function (fn, args) {
var _args = toArray$1(args);
var first = _args[0];
var rest = _args.slice(1);
return reduce(function (_ref, current) {
var _ref2 = slicedToArray(_ref, 2);
var result = _ref2[0];
var old = _ref2[1];
return [result && fn(old, current), current];
}, [true, first], rest)[0];
});
var disjunct = R.curry(function (fn, args) {
var _args2 = toArray$1(args);
var first = _args2[0];
var rest = _args2.slice(1);
return reduce(function (_ref3, current) {
var _ref4 = slicedToArray(_ref3, 2);
var result = _ref4[0];
var old = _ref4[1];
return [result || fn(old, current), current];
}, [false, first], rest)[0];
});
function toArray(collection) {
return reduce(function (array, element) {
return [].concat(toConsumableArray(array), [element]);
}, [], collection);
}
function error() {
for (var _len2 = arguments.length, message = Array(_len2), _key3 = 0; _key3 < _len2; _key3++) {
message[_key3] = arguments[_key3];
}
return new Error(message.join(' '));
}
var mergeKvp = R.curry(function (next, keys, values) {
var kvPairs = zip(toArray(keys), toArray(values), function () {
return void 0;
});
return R.reduce(merge, {}, kvPairs);
function merge(running, _ref5) {
var _ref6 = slicedToArray(_ref5, 2);
var k = _ref6[0];
var v = _ref6[1];
return _extends({}, running, next(running, [k, v]));
}
});
function executableForm(name) {
var _I$Stack;
for (var _len3 = arguments.length, body = Array(_len3 > 1 ? _len3 - 1 : 0), _key4 = 1; _key4 < _len3; _key4++) {
body[_key4 - 1] = arguments[_key4];
}
return (_I$Stack = I.Stack).of.apply(_I$Stack, [Symbol.for(name)].concat(body));
}
function zip(keys, values, factory) {
return keys.map(function (key, i) {
return [key, i >= values.length ? factory() : values[i]];
});
}
function isGlobalRef(symbol) {
return String(symbol).startsWith('Symbol(js/');
}
function isMethodCall(form) {
var fnName = form.first();
return (typeof fnName === 'undefined' ? 'undefined' : _typeof(fnName)) === 'symbol' && String(fnName).startsWith('Symbol(.');
}
function getGlobal() {
if (typeof window !== 'undefined') {
return window;
}
if (typeof global !== 'undefined') {
return global;
}
throw new Error('Could not find global object.');
}
function getSymbolName(symbol) {
return (/Symbol\(([^)]*)\)/.exec(String(symbol))[1]
);
}
function getMethodName(symbol) {
return getSymbolName(symbol).replace(/^\./, '');
}
function getGlobalRefName(symbol) {
return getSymbolName(symbol).replace(/^js\//, '');
}
function is(one, two) {
if ([one, two].every(isGLISPNumber)) {
return M.equal(one, two);
}
return I.is(one, two);
}
function isGLISPNumber(x) {
if (R.is(Number, x)) {
return true;
}
if (x) {
return ['Fraction', 'BigNumber'].includes(x.type);
}
return false;
}
var Util = Object.freeze({
isNumberString: isNumberString,
isBignumberString: isBignumberString,
createBignumber: createBignumber,
stripQuotes: stripQuotes,
isFractionString: isFractionString,
getMatchingStartingParens: getMatchingStartingParens,
isEndingParen: isEndingParen,
isStartingParen: isStartingParen,
serializeArray: serializeArray,
conj: conj,
create: create,
isEven: isEven,
isOdd: isOdd,
transformFnToMacro: transformFnToMacro,
isMacro: isMacro,
canExecuteForm: canExecuteForm,
reduce: reduce,
conjunct: conjunct,
disjunct: disjunct,
toArray: toArray,
error: error,
mergeKvp: mergeKvp,
executableForm: executableForm,
zip: zip,
isGlobalRef: isGlobalRef,
isMethodCall: isMethodCall,
getGlobal: getGlobal,
getSymbolName: getSymbolName,
getMethodName: getMethodName,
getGlobalRefName: getGlobalRefName,
is: is
});
function tokenize(program) {
var _R$reduce = R.reduce(buildTokens, [I.List(), ''], program);
var _R$reduce2 = slicedToArray(_R$reduce, 2);
var tokens = _R$reduce2[0];
var buffer = _R$reduce2[1];
return tokens.push(buffer).filter(R.complement(isComment)).filter(Boolean).toJS();
}
function buildTokens(_ref, token) {
var _ref2 = slicedToArray(_ref, 2);
var tokens = _ref2[0];
var buffer = _ref2[1];
if (isString(buffer)) {
if (token === '"' && R.last(buffer) !== '\\') {
return [tokens.push(buffer + token), ''];
}
if (token === '"' && R.last(buffer) === '\\') {
return [tokens, buffer.substring(0, buffer.length - 1) + token];
}
return [tokens, buffer + token];
}
if (isComment(buffer)) {
if (token === '\n') {
return [tokens.push(buffer), ''];
}
return [tokens, buffer + token];
}
if (token === '~') {
return [tokens.push(buffer), token];
}
if (buffer === '~') {
if (token === '@') {
return [tokens.push('~@'), ''];
}
return [tokens.push('~'), token];
}
if (token === '#') {
return [tokens.push(buffer), token];
}
if (buffer === '#' && token === '{') {
return [tokens.push('#{'), ''];
}
if (['{', '}', '[', ']', '(', ')', '\'', '`'].includes(token)) {
return [tokens.push(buffer, token), ''];
}
if (isWhitespace(token)) {
return [tokens.push(buffer), ''];
}
return [tokens, buffer + token];
}
function isWhitespace(string) {
return (/(\s|,)+/.test(string)
);
}
function isComment(string) {
return string.startsWith(';');
}
function isString(string) {
return string.startsWith('"');
}
var ErrorFactories = {
DetectedUnendedParens: function DetectedUnendedParens(stack) {
return new Error('Detected unclosed starting parens ' + serializeStack(stack));
},
DetectedIllegalEndingParen: function DetectedIllegalEndingParen(start, end) {
return new Error('Starting paren ' + start + ' is followed by an illegal instance of ' + end);
},
DetectedNoStartingParens: function DetectedNoStartingParens(end, expectedParens) {
return new Error('Detected ending paren ' + end + ' but no matching ' + serializeArray(expectedParens));
}
};
function createParenMap(tokens) {
var stack = [];
var map = {};
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = tokens.entries()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var _step$value = slicedToArray(_step.value, 2);
var index = _step$value[0];
var token = _step$value[1];
if (isStartingParen(token)) {
stack.push({ index: index, paren: token });
} else if (isEndingParen(token)) {
var endingParen = token;
var matchingStartingParens = getMatchingStartingParens(endingParen);
if (stack.length === 0) {
throw ErrorFactories.DetectedNoStartingParens(endingParen, matchingStartingParens);
}
var top = stack.pop();
if (!matchingStartingParens.includes(top.paren)) {
throw ErrorFactories.DetectedIllegalEndingParen(top.paren, endingParen);
}
map[top.index] = index;
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
if (stack.length !== 0) {
throw ErrorFactories.DetectedUnendedParens(stack);
}
return map;
}
function serializeStack(stack) {
return serializeArray(stack.map(serializeArray));
}
function createAtom(x) {
if (x === 'true') {
return true;
}
if (x === 'false') {
return false;
}
if (isFractionString(x)) {
return M.fraction(x);
}
if (isBignumberString(x)) {
return createBignumber(x);
}
if (isNumberString(x)) {
return Number(x);
}
if (isActualString(x)) {
return stripQuotes(x);
}
return Symbol.for(x);
}
function isActualString(string) {
return string.startsWith('"') && string.endsWith('"');
}
function createAst(tokens) {
var endingParen = createParenMap(tokens);
return build(0)[0];
// TODO: Re-implement so JavaScript can do tail call optimization
function build(i) {
var token = tokens[i];
var end = endingParen[i];
if (token === '(') {
return [buildSeq(I.Stack(), i, end, i + 1).reverse(), end + 1];
}
if (token === '[') {
return [buildSeq(I.List(), i, end, i + 1), end + 1];
}
if (token === '#{') {
return [buildSeq(I.Set(), i, end, i + 1), end + 1];
}
if (token === '{') {
return [buildMap(I.Map(), i, end, i + 1), end + 1];
}
// TODO: Re-implement so reader macros aren't inlined
if (['\'', '`', '~'].includes(token)) {
if (i + 1 === tokens.length) {
throw new Error(token + ' must be followed by a form, found none.');
}
}
if (token === '\'' || token === '`') {
var _build = build(i + 1);
var _build2 = slicedToArray(_build, 2);
var form = _build2[0];
var next = _build2[1];
return [I.Stack.of(createAtom('quote'), form), next];
}
if (token === '~') {
var _build3 = build(i + 1);
var _build4 = slicedToArray(_build3, 2);
var _form = _build4[0];
var _next = _build4[1];
return [I.Stack.of(createAtom('unquote'), _form), _next];
}
return [createAtom(token), i + 1];
}
function buildSeq(seq, start, end, i) {
if (end === i) {
return seq;
}
var _build5 = build(i);
var _build6 = slicedToArray(_build5, 2);
var object = _build6[0];
var next = _build6[1];
return buildSeq(conj(seq, object), start, end, next);
}
function buildMap(map, start, end, i) {
if (end === i) {
return map;
}
var _build7 = build(i);
var _build8 = slicedToArray(_build7, 2);
var key = _build8[0];
var valueIndex = _build8[1];
if (valueIndex >= end) {
throw new Error('Map expects an even number of arguments');
}
var _build9 = build(valueIndex);
var _build10 = slicedToArray(_build9, 2);
var value = _build10[0];
var next = _build10[1];
return buildMap(conj(map, [key, value]), start, end, next);
}
}
function parse(program) {
return createAst(tokenize(program));
}
function def(env, args) {
var _args = slicedToArray(args, 2);
var name = _args[0];
var value = _args[1];
if (args.size !== 2) {
throw new Error('expected def to be called with 2 args, but called with ' + args.size);
}
env[name] = evaluate(env, value);
return env[name];
}
function $do(env, args) {
/**
* Immutable.Stack.prototype.map's iterates over the stack from bottom to top.
* To evaluate the expressions top to bottom, we reverse the stack.
* To return the result of the last expression, we return .first().
*/
return args.reverse().map(evaluate(env)).first();
}
var destructureIterables = mergeKvp(function (env, _ref) {
var _ref2 = slicedToArray(_ref, 2);
var k = _ref2[0];
var v = _ref2[1];
return destructure(k, v);
});
function destructure(bindingKey, bindingValue) {
if ((typeof bindingKey === 'undefined' ? 'undefined' : _typeof(bindingKey)) === 'symbol') {
return defineProperty({}, bindingKey, bindingValue);
}
if (I.List.isList(bindingKey)) {
if (!iterall.isCollection(bindingValue)) {
throw error('Expected binding to support an iteration protocol, but got ' + bindingValue);
}
if (isVariadic$1(bindingKey)) {
var argKeys = bindingKey.butLast().butLast();
var restKey = bindingKey.last();
var bindingValueSeq = I.Seq(bindingValue);
var argValues = bindingValueSeq.slice(0, argKeys.size);
var restValue = bindingValueSeq.slice(argKeys.size);
return _extends({}, destructureIterables(argKeys, argValues), destructure(restKey, restValue));
}
return destructureIterables(bindingKey, bindingValue);
}
throw error('Failed to destructure (' + bindingKey + ', ' + bindingValue + ')');
}
function isVariadic$1(iterable) {
var bindingKey = I.List(iterable);
var variadicSymbol = Symbol.for('&');
if (bindingKey.size >= 1 && bindingKey.last() === variadicSymbol) {
throw error('Unexpected \'&\' as last item in binding key', bindingKey);
}
if (bindingKey.size >= 2 && bindingKey.get(bindingKey.size - 2) === variadicSymbol) {
if (bindingKey.butLast().butLast().contains(variadicSymbol)) {
throw error('Detected two \'&\' in binding key', bindingKey);
}
return true;
}
return false;
}
function fn(env, args) {
if (args.size === 0) {
throw new Error('Expected function declaration to have an arguments list, but found none.');
}
var _args = toArray$1(args);
var argNames = _args[0];
var body = _args.slice(1);
if (!I.List.isList(argNames)) {
throw error('Expected function arguments to be a List, but got ' + argNames);
}
return function func() {
for (var _len = arguments.length, argValues = Array(_len), _key = 0; _key < _len; _key++) {
argValues[_key] = arguments[_key];
}
var actualArgs = I.List(argValues);
validateArguments(argNames, actualArgs);
var fnEnv = create(env, destructure(argNames, actualArgs));
var result = evaluate(fnEnv, executableForm.apply(Util, ['do'].concat(toConsumableArray(body))));
return result;
};
}
function validateArguments(argNames, argValues) {
var argCount = getArgumentCount(argNames);
if (isVariadic(argNames)) {
if (argValues.size < argCount) {
throw error('Variadic function was declared with ' + argCount + ' arguments,', 'but only called with ' + argValues.size + ' arguments');
}
} else {
if (argValues.size !== argCount) {
throw error('fn declared with ' + argCount + ' arguments was called with ' + argValues.size + ' arguments');
}
}
}
function getArgumentCount(args) {
var index = args.indexOf(Symbol.for('&'));
return index === -1 ? args.size : index;
}
function isVariadic(args) {
return args.indexOf(Symbol.for('&')) !== -1;
}
function $if(env, args) {
var _args = slicedToArray(args, 3);
var test = _args[0];
var conseq = _args[1];
var alt = _args[2];
return evaluate(env, test) ? evaluate(env, conseq) : evaluate(env, alt);
}
function $let(env, args) {
var _args = toArray$1(args);
var bindings = _args[0];
var body = _args.slice(1);
if (bindings.size % 2 !== 0) {
throw new Error('let bindings should be of even length');
}
var bindingKeys = bindings.filter(function (_, i) {
return isEven(i);
});
var bindingValues = bindings.filter(function (_, i) {
return isOdd(i);
});
// console.log({ bindingKeys, bindingValues });
var bindingEnv = buildLetBindingEnv(env, bindingKeys, bindingValues);
var letEnvironment = create(env, bindingEnv);
return evaluate(letEnvironment, executableForm.apply(Util, ['do'].concat(toConsumableArray(body))));
}
function buildLetBindingEnv(outerEnv) {
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
return mergeKvp.apply(Util, [function (env, _ref) {
var _ref2 = slicedToArray(_ref, 2);
var key = _ref2[0];
var value = _ref2[1];
var innerEnv = create(outerEnv, env);
var evaluatedValue = evaluate(innerEnv, value);
// console.log({ key, evaluatedValue });
return destructure(key, evaluatedValue);
}].concat(args));
}
function $macro(env, args) {
var fn$$ = fn(env, args);
return transformFnToMacro(fn$$);
}
function quote(env, args) {
if (args.size !== 1) {
throw new Error('quote expects 1 arg, but was called with ' + args.size + ' args');
}
var _args = slicedToArray(args, 1);
var item = _args[0];
return unquote(env, item);
}
function unquote(env, form) {
if (!I.Iterable.isIterable(form)) {
return form;
}
if (isUnquoteForm(form)) {
if (form.size !== 2) {
throw new Error('unquote expects 1 arg, but was called with ' + (form.size - 1) + ' args');
}
var argToUnquote = form.get(1);
return evaluate(env, argToUnquote);
}
if (I.Map.isMap(form) || I.OrderedMap.isOrderedMap(form)) {
return form.mapEntries(function (_ref) {
var _ref2 = slicedToArray(_ref, 2);
var key = _ref2[0];
var value = _ref2[1];
return [unquote(env, key), unquote(env, value)];
});
}
return form.map(function (item) {
return unquote(env, item);
});
}
function isUnquoteForm(form) {
return canExecuteForm(form) && form.first() === Symbol.for('unquote');
}
function method(env, form) {
if (form.size < 2) {
throw new Error('Method calls must be made with an object as the first argument, found none.');
}
var _form$rest$map = form.rest().map(evaluate(env));
var _form$rest$map2 = toArray$1(_form$rest$map);
var object = _form$rest$map2[0];
var args = _form$rest$map2.slice(1);
if (R.isNil(object)) {
throw new Error('Unexpected method call on ' + object);
}
var prop = getMethodName(form.first());
if (!R.is(Function, object[prop])) {
throw new Error('Expected "' + prop + '" in object ' + object + ' to be a function, instead found ' + object[prop]);
}
return object[prop].apply(object, toConsumableArray(args));
}
function $throw(env, forms) {
if (forms.size !== 1) {
throw new Error('(throw ,,,) expects exactly one argument');
}
var error = evaluate(env, forms.first());
if (!(error instanceof Error)) {
throw new Error('(throw ...) expects the throw object to be an Error instance');
}
throw error;
}
function executeForm(env, form) {
if (form.first() === Symbol.for('let')) {
return $let(env, form.rest());
}
if (form.first() === Symbol.for('do')) {
return $do(env, form.rest());
}
if (form.first() === Symbol.for('def')) {
return def(env, form.rest());
}
if (form.first() === Symbol.for('if')) {
return $if(env, form.rest());
}
if (form.first() === Symbol.for('fn')) {
return fn(env, form.rest());
}
if (form.first() === Symbol.for('quote')) {
return quote(env, form.rest());
}
if (form.first() === Symbol.for('throw')) {
return $throw(env, form.rest());
}
if (form.first() === Symbol.for('unquote')) {
throw new Error('\'unquote\' call must be inside a \'quote\' call');
}
if (form.first() === Symbol.for('macro')) {
return $macro(env, form.rest());
}
if (isMethodCall(form)) {
return method(env, form);
}
/** Procedure call */
var _form = toArray$1(form);
var fnForm = _form[0];
var args = _form.slice(1);
var fn$$ = evaluate(env, fnForm);
if (typeof fn$$ !== 'function') {
throw new Error('Tried to call ' + String(fn$$) + ' as a function.');
}
if (isMacro(fn$$)) {
return evaluate(env, fn$$.apply(undefined, toConsumableArray(args)));
}
return fn$$.apply(undefined, toConsumableArray(args.map(evaluate(env))));
}
var evaluate = R.curry(function (env, form) {
if ((typeof form === 'undefined' ? 'undefined' : _typeof(form)) === 'symbol') {
return getSymbolValue(env, form);
}
if (canExecuteForm(form)) {
return executeForm(env, form);
}
return evaluateColl(env, form);
});
function evaluateColl(env, form) {
if (shouldMap(form)) {
return form.map(evaluate(env));
}
if (shouldMapEntries(form)) {
return form.mapEntries(function (_ref) {
var _ref2 = slicedToArray(_ref, 2);
var k = _ref2[0];
var v = _ref2[1];
return [evaluate(env, k), evaluate(env, v)];
});
}
return form;
}
function getSymbolValue(env, symbol) {
if (isGlobalRef(symbol)) {
var Global = getGlobal();
var propName = getGlobalRefName(symbol);
if (!(propName in Global)) {
throw new Error('Could not locate ' + propName + ' on global object.');
}
return Global[propName];
}
if (!(symbol in env)) {
throw new Error('Trying to access ' + String(symbol) + ' but none found in scope.');
}
return env[symbol];
}
var shouldMap = or(I.List.isList, I.Set.isSet, I.OrderedSet.isOrderedSet, I.Seq.isSeq, I.Stack.isStack);
var shouldMapEntries = or(I.OrderedMap.isOrderedMap, I.Map.isMap);
function or() {
for (var _len = arguments.length, fns = Array(_len), _key = 0; _key < _len; _key++) {
fns[_key] = arguments[_key];
}
return function (x) {
return reduce(function (old, fn) {
return old || fn(x);
}, false, fns);
};
}
var _ROOT_ENV;
var ROOT_ENV = (_ROOT_ENV = {}, defineProperty(_ROOT_ENV, Symbol.for('+'), function () {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return args.reduce(function (x, y) {
return M.add(x, y);
});
}), defineProperty(_ROOT_ENV, Symbol.for('-'), function () {
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
return args.reduce(function (x, y) {
return M.subtract(x, y);
});
}), defineProperty(_ROOT_ENV, Symbol.for('*'), function () {
for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
args[_key3] = arguments[_key3];
}
return args.reduce(function (x, y) {
return M.multiply(x, y);
});
}), defineProperty(_ROOT_ENV, Symbol.for('/'), function () {
for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
args[_key4] = arguments[_key4];
}
return args.reduce(function (x, y) {
return M.divide(x, y);
});
}), defineProperty(_ROOT_ENV, Symbol.for('!'), function (x) {
return !x;
}), defineProperty(_ROOT_ENV, Symbol.for('='), function () {
for (var _len5 = arguments.length, args = Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
args[_key5] = arguments[_key5];
}
return conjunct(function (x, y) {
return is(x, y);
}, args);
}), defineProperty(_ROOT_ENV, Symbol.for('<'), function () {
for (var _len6 = arguments.length, args = Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
args[_key6] = arguments[_key6];
}
return conjunct(function (x, y) {
return M.smaller(x, y);
}, args);
}), defineProperty(_ROOT_ENV, Symbol.for('>'), function () {
for (var _len7 = arguments.length, args = Array(_len7), _key7 = 0; _key7 < _len7; _key7++) {
args[_key7] = arguments[_key7];
}
return conjunct(function (x, y) {
return M.larger(x, y);
}, args);
}), defineProperty(_ROOT_ENV, Symbol.for('and'), function () {
for (var _len8 = arguments.length, args = Array(_len8), _key8 = 0; _key8 < _len8; _key8++) {
args[_key8] = arguments[_key8];
}
return conjunct(function (x, y) {
return x && y;
}, args);
}), defineProperty(_ROOT_ENV, Symbol.for('or'), function () {
for (var _len9 = arguments.length, args = Array(_len9), _key9 = 0; _key9 < _len9; _key9++) {
args[_key9] = arguments[_key9];
}
return disjunct(function (x, y) {
return x || y;
}, args);
}), defineProperty(_ROOT_ENV, Symbol.for('mod'), M.mod), defineProperty(_ROOT_ENV, Symbol.for('abs'), M.abs), defineProperty(_ROOT_ENV, Symbol.for('floor'), M.floor), defineProperty(_ROOT_ENV, Symbol.for('ceil'), M.ceil), defineProperty(_ROOT_ENV, Symbol.for('gcd'), M.gcd), defineProperty(_ROOT_ENV, Symbol.for('round'), M.round), defineProperty(_ROOT_ENV, Symbol.for('pow'), M.pow), defineProperty(_ROOT_ENV, Symbol.for('conj'), conj), defineProperty(_ROOT_ENV, Symbol.for('List'), function () {
var _I$List;
return (_I$List = I.List).of.apply(_I$List, arguments);
}), defineProperty(_ROOT_ENV, Symbol.for('List?'), function (x) {
return I.List.isList(x);
}), defineProperty(_ROOT_ENV, Symbol.for('Set'), function () {
var _I$Set;
return (_I$Set = I.Set).of.apply(_I$Set, arguments);
}), defineProperty(_ROOT_ENV, Symbol.for('Set?'), function (x) {
return I.Set.isSet(x);
}), defineProperty(_ROOT_ENV, Symbol.for('Stack'), function () {
var _I$Stack;
return (_I$Stack = I.Stack).of.apply(_I$Stack, arguments);
}), defineProperty(_ROOT_ENV, Symbol.for('Stack?'), function (x) {
return I.Stack.isStack(x);
}), defineProperty(_ROOT_ENV, Symbol.for('Map'), function () {
var _I$Map;
return (_I$Map = I.Map).of.apply(_I$Map, arguments);
}), defineProperty(_ROOT_ENV, Symbol.for('Map?'), function (x) {
return I.Map.isMap(x);
}), defineProperty(_ROOT_ENV, Symbol.for('Seq'), function () {
var _I$Seq;
return (_I$Seq = I.Seq).of.apply(_I$Seq, arguments);
}), defineProperty(_ROOT_ENV, Symbol.for('Seq?'), function (x) {
return I.Seq.isSeq(x);
}), defineProperty(_ROOT_ENV, Symbol.for('aset'), function (object, key, value) {
object[key] = value;return object;
}), defineProperty(_ROOT_ENV, Symbol.for('aget'), function (object, key) {
return object[key];
}), defineProperty(_ROOT_ENV, Symbol.for('fromJS'), I.fromJS), _ROOT_ENV);
function run(code) {
return evaluate(create(ROOT_ENV), parse(code));
}
exports.run = run;
exports.RootEnv = ROOT_ENV;
exports.evaluate = evaluate;
exports.parse = parse;
exports.tokenize = tokenize;
Object.defineProperty(exports, '__esModule', { value: true });
}));