js-slang
Version:
Javascript-based implementations of Source, written in Typescript
103 lines • 2.39 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.isList = isList;
exports.flattenList = flattenList;
exports.arrayToList = arrayToList;
exports.arrayToImproperList = arrayToImproperList;
exports.isImproperList = isImproperList;
exports.isPair = isPair;
exports.flattenImproperList = flattenImproperList;
exports.improperListLength = improperListLength;
/**
* 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]);
}
/**
* Turn a list into an array.
* @param value a list
* @returns
*/
function flattenList(value) {
if (value === null) {
return [];
}
return [value[0], ...flattenList(value[1])];
}
/**
* Convert an array into a list.
* @param arr
* @returns
*/
function arrayToList(arr) {
return arrayToImproperList(arr, null);
}
/**
* 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;
}
/**
* 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]);
}
/**
* Check if a value is a pair.
* @param value
* @returns
*/
function isPair(value) {
return Array.isArray(value) && value.length === 2;
}
/**
* 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];
}
/**
* 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;
}
//# sourceMappingURL=macro-utils.js.map