js-slang
Version:
Javascript-based implementations of Source, written in Typescript
104 lines • 2.59 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.improperListLength = exports.flattenImproperList = exports.isPair = exports.isImproperList = exports.arrayToImproperList = exports.arrayToList = exports.flattenList = exports.isList = void 0;
/**
* Low-level check for a list.
* @param value any value
* @returns whether the value is a list
*/
function isList(value) {
if (value === null) {
return true;
}
return Array.isArray(value) && value.length === 2 && isList(value[1]);
}
exports.isList = isList;
/**
* Turn a list into an array.
* @param value a list
* @returns
*/
function flattenList(value) {
if (value === null) {
return [];
}
return [value[0], ...flattenList(value[1])];
}
exports.flattenList = flattenList;
/**
* Convert an array into a list.
* @param arr
* @returns
*/
function arrayToList(arr) {
return arrayToImproperList(arr, null);
}
exports.arrayToList = arrayToList;
/**
* Convert an array into an improper list.
* @param arr
* @param last
* @returns
*/
function arrayToImproperList(arr, last) {
if (arr.length === 0) {
return last;
}
const pair = [arr[0], arrayToImproperList(arr.slice(1), last)];
pair.pair = true;
return pair;
}
exports.arrayToImproperList = arrayToImproperList;
/**
* Check if a value is an improper list.
* We force an improper list to be an array of two elements.
* @param value
* @returns
*/
function isImproperList(value) {
if (value === null) {
return false;
}
return Array.isArray(value) && value.length === 2 && !isList(value[1]);
}
exports.isImproperList = isImproperList;
/**
* Check if a value is a pair.
* @param value
* @returns
*/
function isPair(value) {
return Array.isArray(value) && value.length === 2;
}
exports.isPair = isPair;
/**
* Convert an improper list into an array and a terminator.
* @param value
* @returns
*/
function flattenImproperList(value) {
let items = [];
let working = value;
while (working instanceof Array && working.length === 2) {
items.push(working[0]);
working = working[1];
}
return [items, working];
}
exports.flattenImproperList = flattenImproperList;
/**
* Get the length of an improper list.
* @param value
* @returns
*/
function improperListLength(value) {
let length = 0;
let working = value;
while (isPair(working)) {
length++;
working = working[1];
}
return length;
}
exports.improperListLength = improperListLength;
//# sourceMappingURL=macro-utils.js.map
;