69 lines
2 KiB
JavaScript
69 lines
2 KiB
JavaScript
import { fnType, lsType } from "../type_registry.js";
|
|
import {Type, Function} from "../metacircular.js";
|
|
import {Int, Byte} from "../primitives/symbols.js";
|
|
|
|
// 'normal' implementation
|
|
const emptyList = {l:[]};
|
|
const get = ls => i => ls.l[i];
|
|
const put = ls => i => elem => ({l: ls.l.with(Number(i), elem)});
|
|
// const push = ls => elem => ({l:ls.l.concat([elem])});
|
|
|
|
const byteListImpl = {
|
|
// specialization
|
|
emptyList: new Uint8Array(),
|
|
get: ls => i => ls[i],
|
|
put: ls => i => elem => {
|
|
res = new Uint8Array(ls); // creates copy
|
|
res[i] = elem;
|
|
return res;
|
|
}
|
|
}
|
|
|
|
export const makeListModule = elementType => {
|
|
// List<elementType> type depends on elementType
|
|
// generating it another time, will give the same type (structurally equivalent):
|
|
const ListOfElement = lsType(elementType);
|
|
|
|
const getFnType1 = fnType({in: Int , out: elementType});
|
|
const getFnType = fnType({in: ListOfElement, out: getFnType1});
|
|
|
|
const putFnType2 = fnType({in: elementType , out: ListOfElement});
|
|
const putFnType1 = fnType({in: Int , out: putFnType2});
|
|
const putFnType = fnType({in: ListOfElement, out: putFnType1});
|
|
|
|
// const pushFnType1 = fnType({in: elementType , out: ListOfElement});
|
|
// const pushFnType = fnType({in: ListOfElement, out: pushFnType1});
|
|
|
|
const common = [
|
|
{i: ListOfElement, t: Type},
|
|
|
|
{i: getFnType , t: Function},
|
|
{i: getFnType1 , t: Function},
|
|
|
|
{i: putFnType , t: Function},
|
|
{i: putFnType1, t: Function},
|
|
{i: putFnType2, t: Function},
|
|
|
|
// {i: pushFnType , t: Function},
|
|
// {i: pushFnType1, t: Function},
|
|
];
|
|
|
|
if (elementType === Byte) {
|
|
// specialization: use Uint8Array instead of JS array
|
|
return [
|
|
...common,
|
|
{i: byteListImpl.emptyList , t: ListOfElement},
|
|
{i: byteListImpl.get , t: getFnType},
|
|
{i: byteListImpl.put , t: putFnType},
|
|
];
|
|
}
|
|
else {
|
|
return [
|
|
...common,
|
|
{i: emptyList , t: ListOfElement},
|
|
{i: get , t: getFnType},
|
|
{i: put , t: putFnType},
|
|
// {i: push , t: pushFnType},
|
|
];
|
|
}
|
|
};
|