list of byte encoded as JS Uint8Array + demo more readable
This commit is contained in:
parent
574651ccb7
commit
3d08485a08
6 changed files with 102 additions and 37 deletions
|
|
@ -1,14 +1,17 @@
|
||||||
import {Int, Bool, Double} from "../primitives/symbols.js";
|
import {Int, Bool, Double, Byte} from "../primitives/symbols.js";
|
||||||
import { makeListModule } from "../structures/list_common.js";
|
import { makeListModule } from "../structures/list_common.js";
|
||||||
import { makeProductType } from "../structures/product.js";
|
import { makeProductType } from "../structures/product.js";
|
||||||
import { makeSumType } from "../structures/sum.js";
|
import { makeSumType } from "../structures/sum.js";
|
||||||
import { getListType, prodType, sumType } from "../type_registry.js";
|
import { getListType, prodType, sumType } from "../type_registry.js";
|
||||||
|
|
||||||
const ListOfInt = getListType(Int);
|
const ListOfDouble = getListType(Double);
|
||||||
const ListOfIntModule = makeListModule(Int);
|
const ListOfDoubleModule = makeListModule(Double);
|
||||||
|
|
||||||
const ListOfListOfInt = getListType(ListOfInt);
|
const ListOfListOfDouble = getListType(ListOfDouble);
|
||||||
const ListOfListOfIntModule = makeListModule(ListOfInt);
|
const ListOfListOfDoubleModule = makeListModule(ListOfDouble);
|
||||||
|
|
||||||
|
const ListOfByte = getListType(Byte);
|
||||||
|
const ListOfByteModule = makeListModule(Byte);
|
||||||
|
|
||||||
export const ModuleValues = [
|
export const ModuleValues = [
|
||||||
{i: 0n, t: Int},
|
{i: 0n, t: Int},
|
||||||
|
|
@ -16,12 +19,15 @@ export const ModuleValues = [
|
||||||
{i: false, t: Bool},
|
{i: false, t: Bool},
|
||||||
{i: 3.14159265359, t: Double},
|
{i: 3.14159265359, t: Double},
|
||||||
|
|
||||||
{i: {l:[42n, 43n]} , t: ListOfInt},
|
{i: {l:[4.2, 7.6]} , t: ListOfDouble},
|
||||||
{i: {l:[{l:[42n, 43n]}, {l:[999n]}]}, t: ListOfListOfInt},
|
{i: {l:[{l:[4.2, 7.6]}, {l:[4.3]}]}, t: ListOfListOfDouble},
|
||||||
|
|
||||||
|
{i: new Uint8Array([1,2,3]), t: ListOfByte},
|
||||||
|
|
||||||
// i'm lazy
|
// i'm lazy
|
||||||
...ListOfIntModule,
|
...ListOfDoubleModule,
|
||||||
...ListOfListOfIntModule,
|
...ListOfListOfDoubleModule,
|
||||||
|
...ListOfByteModule,
|
||||||
|
|
||||||
|
|
||||||
...makeProductType(Int, Bool),
|
...makeProductType(Int, Bool),
|
||||||
|
|
|
||||||
16
main.js
16
main.js
|
|
@ -29,14 +29,20 @@ class Context {
|
||||||
const inType = getIn(fnType);
|
const inType = getIn(fnType);
|
||||||
const outType = getOut(fnType);
|
const outType = getOut(fnType);
|
||||||
console.log();
|
console.log();
|
||||||
|
if (fn.name !== "") {
|
||||||
console.log("--".repeat(indent), fn, ':', fnType);
|
console.log("--".repeat(indent), fn, ':', fnType);
|
||||||
|
}
|
||||||
for (const i of this.instances.getdefault(inType)) {
|
for (const i of this.instances.getdefault(inType)) {
|
||||||
const result = fn(i);
|
try {
|
||||||
console.log("--".repeat(indent+1), i, '->', result);
|
const result = fn(i);
|
||||||
if (this.types.getdefault(outType).includes(Function)) {
|
console.log("--".repeat(indent+1), i, '->', result);
|
||||||
if (indent < 5) {
|
if (this.types.getdefault(outType).includes(Function)) {
|
||||||
callFunctionOnEveryValue(result, outType, indent+2);
|
if (indent < 5) {
|
||||||
|
callFunctionOnEveryValue(result, outType, indent+2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log("--".repeat(indent+1), i, `-> (exception: ${e})`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
15
primitives/byte.js
Normal file
15
primitives/byte.js
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { fnType } from "../type_registry.js";
|
||||||
|
import {Type, Function} from "../metacircular.js";
|
||||||
|
import {Byte, Bool} from "./symbols.js";
|
||||||
|
|
||||||
|
const eqByte = x => y => x === y;
|
||||||
|
|
||||||
|
const Byte_to_Bool = fnType({in: Byte, out: Bool});
|
||||||
|
const Byte_to_Byte_to_Bool = fnType({in: Byte, out: Byte_to_Bool});
|
||||||
|
|
||||||
|
export const ModuleByte = [
|
||||||
|
{i: Byte , t: Type },
|
||||||
|
{i: Byte_to_Bool , t: Function },
|
||||||
|
{i: Byte_to_Byte_to_Bool , t: Function },
|
||||||
|
{i: eqByte , t: Byte_to_Byte_to_Bool },
|
||||||
|
];
|
||||||
|
|
@ -3,3 +3,4 @@
|
||||||
export const Bool = Symbol('Bool');
|
export const Bool = Symbol('Bool');
|
||||||
export const Int = Symbol('Int');
|
export const Int = Symbol('Int');
|
||||||
export const Double = Symbol('Double');
|
export const Double = Symbol('Double');
|
||||||
|
export const Byte = Symbol('Byte');
|
||||||
|
|
@ -1,32 +1,69 @@
|
||||||
import { fnType, getListType } from "../type_registry.js";
|
import { fnType, getListType } from "../type_registry.js";
|
||||||
import {Type, Function} from "../metacircular.js";
|
import {Type, Function} from "../metacircular.js";
|
||||||
import {Int} from "../primitives/symbols.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 => {
|
export const makeListModule = elementType => {
|
||||||
// List<elementType> type depends on elementType
|
// List<elementType> type depends on elementType
|
||||||
// generating it another time, will give the same type (structurally equivalent):
|
// generating it another time, will give the same type (structurally equivalent):
|
||||||
const ListOfElement = getListType(elementType);
|
const ListOfElement = getListType(elementType);
|
||||||
|
|
||||||
const emptyList = {l:[]};
|
const getFnType1 = fnType({in: Int , out: elementType});
|
||||||
|
const getFnType = fnType({in: ListOfElement, out: getFnType1});
|
||||||
|
|
||||||
const get = ls => i => ls.l[i];
|
const putFnType2 = fnType({in: elementType , out: ListOfElement});
|
||||||
const getBoundType = fnType({in: Int, out: elementType});
|
const putFnType1 = fnType({in: Int , out: putFnType2});
|
||||||
const getType = fnType({in: ListOfElement, out: getBoundType});
|
const putFnType = fnType({in: ListOfElement, out: putFnType1});
|
||||||
|
|
||||||
const push = ls => elem => ({l:ls.l.concat([elem])});
|
// const pushFnType1 = fnType({in: elementType , out: ListOfElement});
|
||||||
const pushBoundType = fnType({in: elementType, out: ListOfElement});
|
// const pushFnType = fnType({in: ListOfElement, out: pushFnType1});
|
||||||
const pushType = fnType({in: ListOfElement, out: pushBoundType});
|
|
||||||
|
|
||||||
return [
|
const common = [
|
||||||
{i: ListOfElement, t: Type},
|
{i: ListOfElement, t: Type},
|
||||||
{i: emptyList , t: ListOfElement},
|
|
||||||
|
|
||||||
{i: get , t: getType},
|
{i: getFnType , t: Function},
|
||||||
{i: getType , t: Function},
|
{i: getFnType1 , t: Function},
|
||||||
{i: getBoundType , t: Function},
|
|
||||||
|
|
||||||
{i: push , t: pushType},
|
{i: putFnType , t: Function},
|
||||||
{i: pushType , t: Function},
|
{i: putFnType1, t: Function},
|
||||||
{i: pushBoundType, 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},
|
||||||
|
];
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@ import { Function } from "../metacircular.js";
|
||||||
|
|
||||||
// In JS, all products are encoded in the same way:
|
// In JS, all products are encoded in the same way:
|
||||||
const constructor = left => right => ({left, right});
|
const constructor = left => right => ({left, right});
|
||||||
const left = product => product.left;
|
const getLeft = product => product.left;
|
||||||
const right = product => product.right;
|
const getRight = product => product.right;
|
||||||
|
|
||||||
// Given two types A and B, create the type (A × B).
|
// Given two types A and B, create the type (A × B).
|
||||||
export const makeProductType = (leftType, rightType) => {
|
export const makeProductType = (leftType, rightType) => {
|
||||||
|
|
@ -14,11 +14,11 @@ export const makeProductType = (leftType, rightType) => {
|
||||||
const rightFnType = fnType({in: productType, out: rightType});
|
const rightFnType = fnType({in: productType, out: rightType});
|
||||||
|
|
||||||
const constructorBoundType = fnType({in: rightType, out: productType});
|
const constructorBoundType = fnType({in: rightType, out: productType});
|
||||||
const constructorType = fnType({in: leftType, out: constructorBoundType});
|
const constructorType = fnType({in: leftType , out: constructorBoundType});
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{i: left , t: leftFnType},
|
{i: getLeft , t: leftFnType},
|
||||||
{i: right , t: rightFnType},
|
{i: getRight , t: rightFnType},
|
||||||
{i: leftFnType , t: Function},
|
{i: leftFnType , t: Function},
|
||||||
{i: rightFnType, t: Function},
|
{i: rightFnType, t: Function},
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue