Published
Edited
Jan 17, 2020
Importers
Insert cell
md`# dType for WASM`
Insert cell
dT = dTSetTypes(dTSetMethods({
enums: {controls: {}},
enum_choices: {types: []},
composites: {},
controls: {tuple: {}, array: {}},
t: {},
settings: {
refURL: "http://dTypesite.org/package/#"
},
BN,
}))
Insert cell
{
const max = 2n ** (64n - 1n) - 1n;
const max2 = BigInt.asIntN(64, max);
const view = new BigInt64Array(4);
console.log(BigInt.asUintN(64, max**4n));
//return ;
new Float32Array();
1024985n.toString(16)
return view;
}
Insert cell
function dTSetMethods (dT) {
function getLocal(vObj, ndxs, temp){
if (ndxs.length === 0) return temp
return getLocal(vObj, ndxs.slice(1), vObj.value[ndxs[0]])
}

dT.t.getFn = function(fnName, type) {
if (type.substring(0,4) == "enum") {
return dT.enums.controls[fnName]
}
return dT.controls[type][fnName]
}

dT.t.apply = function(typed, fnName, folder, options) {
console.log("apply", typed, fnName, folder, options)
let name
if (!typed.name) {
typed.name = "."
}
let type =typed.type
let value = typed.value
let temp = {}
let ndx = 0
let fn, ans = [], out = {value: [], type: []};

if (!(typeof type == "string")) {
if (value instanceof Array)
if (value.length !== Object.keys(type).length) {
return false
}
// Used only for showControl...
if (dT.controls.tuple[fnName]) {
console.log('apply tuple options', fnName, options);
folder = dT.controls.tuple[fnName](typed, folder, options)
}
Object.keys(type).forEach((i, nndx) => {
const onChangeSub = typedSub => {
if (options.onChange) {
typed.value[nndx] = typedSub.value;
const typecpy = JSON.parse(JSON.stringify(typed.type));
typecpy[i] = typedSub.type;
options.onChange(Object.assign({}, typed, {type: typecpy}));
}
}
const optionscpy = Object.assign({}, options, {onChange: onChangeSub});
temp = {}
temp.value = value instanceof Array ? value[ndx] : null
temp.type = type[i]
temp.name = i
console.log('apply tuple item options', fnName, optionscpy);
ans[i] = dT.t.apply(temp, fnName, folder, optionscpy)
out.value[ndx]=ans[i].value
out.type[i]=ans[i].type
ndx++
});
return out;
}

let arrT = dT.t.getArrayType({type:type})
console.log(arrT)
if (arrT) {
ans = []

typed.value = typed.value || [null];
value = typed.value;

const addInner = (ind, innerElem) => {
innerElem = innerElem ? innerElem.value : JSON.parse(JSON.stringify(typed.value[0]));
typed.value.splice(ind, 0, innerElem);
options.onChange(typed);
options.onReinitialize();
}

if (dT.controls.array[fnName]) {
console.log('array fnName', fnName, folder);

const onChangeSub = (typedSub, index) => {
if (options.onChange) {
if (!typedSub) {
options.onChange(null);
} else {
options.onChange(typedSub, index);
}
}
}
let optionscpy = Object.assign({}, options, {onChange: onChangeSub});

if (!optionscpy.arrOptions) {
optionscpy.arrOptions = {
addInner,
add: false,
remove: false,
index: null,
}
}
optionscpy.arrOptions.addInner = addInner;

folder = dT.controls.array[fnName](typed, folder, optionscpy)
}

value.forEach((val, i) => {

const onChangeSub = (typedSub, index) => {
if (!typedSub) {
typed.value.splice(i, 1);
if (options.onChange) options.onChange(typed);
} else if (!index && index !== 0) {
typed.value[i] = typedSub.value;
if (options.onChange) options.onChange(typed);
} else {
addInner(index, typedSub);
}
}
const optionscpy = Object.assign({}, options, {onChange: onChangeSub});

optionscpy.arrOptions = {
add: true,
remove: true,
index: i,
}

ans[i] = dT.t.apply({value: value[i], type: arrT, name: typed.name + i}, fnName, folder, optionscpy)

out.value.push(ans[i].value)
});
out.type = ans[0].type+"[]"
return out;
}

let compT = dT.t.getComposite(typed.type)
if (compT) {
const onChangeSub = (typedSub) => {
if (options.onChange) {
options.onChange(typedSub);
}
}
const optionscpy = Object.assign({}, options, {onChange: onChangeSub});

return dT.t.apply({value:value, type: compT, name: typed.name}, fnName, folder, optionscpy)
}

const onChangeSub = (typedSub, index) => {
if (options.onChange) {
options.onChange(typedSub, index);
}
}
const optionscpy = Object.assign({}, options, {onChange: onChangeSub});

let a = dT.t.getFn(fnName, type)(typed, folder, optionscpy)
return a
}

dT.t.setType = function (name, test, supertypes= []){
dT[name] = _.NullaryType
(name)
(dT.settings.refURL+name)
(supertypes)
(test)
if (!(dT.enum_choices.types[name]))
dT.enum_choices.types = dT.enum_choices.types.concat([name])
dT.enums.types = _.EnumType
("types")
(dT.settings.refURL+"types")
(dT.enum_choices.types);
return dT[name]
}

dT.t.setComposite = function (name, tuple){
dT.composites[name] = tuple
dT.controls[name] = dT.controls["tuple"]
if (!(dT.enum_choices.types[name]))
dT.enum_choices.types = dT.enum_choices.types.concat([name])
dT.enums.types = _.EnumType
("types")
(dT.settings.refURL+"types")
(dT.enum_choices.types);
return dT[name]
}

dT.t.getComposite = function (name){
return dT.composites[name]
}


dT.t.setEnum = function (name, choices){
dT.enums[name] = _.EnumType
(name)
(dT.settings.refURL+name)
(choices);
dT.enum_choices[name]=choices;
if (!(dT.enum_choices.types["enum:"+name]))
dT.enum_choices.types = dT.enum_choices.types.concat(["enum:"+name])
dT.enums.types = _.EnumType
("types")
(dT.settings.refURL+"types")
(dT.enum_choices.types);
return dT.enums[name]
}

dT.t.bnType = function (name, min, max){
let test = x => x.gte(min) &&
x.lte(max)
let supertypes = [dT["bn"]]
dT.controls[name] = Object.assign({},dT.controls["bn"])
dT.controls[name].min(min)
dT.controls[name].max(max)
return dT.t.setType(name, test, supertypes)

}

dT.t.bbnType = function (name, min, max){
let test = x => x.gte(min) &&
x.lte(max)
let supertypes = [dT["bn"]]
dT.controls[name] = Object.assign({},dT.controls["bn"],dT.controls["bbn"])
dT.controls[name].min(min)
dT.controls[name].max(max)
return dT.t.setType(name, test, supertypes)

}
dT.t.biType = function (name, min, max){
let test = x => x >= min &&
x <= max
let supertypes = []
dT.controls[name] = Object.assign({},dT.controls["i32"]) // ,dT.controls["bn"]
dT.controls[name].min(min)
dT.controls[name].max(max)
return dT.t.setType(name, test, supertypes)

}

dT.t.byteType = function (name, len){
const re = `0x[a-fA-F0-9]{${len*2}}`
let reg = RegExp(`(?:^${re}$)`)
let test = x => reg.test(x)
let supertypes = [dT["string"]]
dT.controls[name] = {
min: function(min){if (min) this._min = min; return this._min;},
max: function(max){if (max) this._max = max; return this._max;},
random: function(){ return {value: "0x"+("00".repeat(len).replace(/0/g,function(){return (~~(Math.random()*16)).toString(16);})), type:name}},
}
dT.controls[name] = Object.assign({}, dT.controls["string"], dT.controls[name])
dT.controls[name].min("0x"+"00".repeat(len*2))
dT.controls[name].max("0x"+"ff".repeat(len*2))
return dT.t.setType(name, test, supertypes)
}

dT.t.getType = function(typed){
let type = typed.type
if (type.substring(0,4) == "enum") {
return dT.enums[type.substring(5)]
}
if (type.substring(type.length-2) == "[]") {
return _.Array (dT.t.getType({value: null, type: type.substring(0, type.length-2)}))
}
return dT[type];
}

dT.t.getArrayType = function(typed){
let type = typed.type
if (type.substring(type.length-2) == "[]")
return type.substring(0,type.length-2);
return false;
}

dT.t.getComponent = function(typed, key){
let type = typed.type
let value = typed.value
if (type === "tuple") return value[key]
let arrT = dT.t.getArrayType(typed)
if (arrT) {
return {value: value[key], type: arrT, name: typed.name+key}
}
}


dT.t.getRange = function(typed){
let type = typed.type, min, max
if (type.substring(0,4) == "enum") {
min = new dT.BN(0)
max = new dT.BN(dT.enum_choices[type.substring(5)].length-1)
} else {
min = dT.controls[type].min()
max = dT.controls[type].max()
}
return {min: min, max: max}
}
return dT
}
Insert cell
function dTSetTypes(dT) {
dT["bn"] = _.NullaryType
("bn")
(dT.settings.refURL+"bn")
([])
(x => dT.BN.isBN(x))

dT.controls["bn"] = {
min: function(min){if (min !== undefined) this._min = min; return this._min;},
max: function(max){if (max !== undefined) this._max = max; return this._max;},
random: function(typed){
let type = typed.type
let range = dT.t.getRange(typed)
let val = range.max.sub(new dT.BN(Math.random()*Number.MAX_SAFE_INTEGER).mul(range.max.sub(range.min)).div(new dT.BN(Number.MAX_SAFE_INTEGER)))
return ({value: val, type: type})
},
}
dT.controls["i32"] = {
min: function(min){if (min !== undefined) this._min = min; return this._min;},
max: function(max){if (max !== undefined) this._max = max; return this._max;},
random: function(typed){
return ({value: 0n, type: "i32"});
}
// random: function(typed){
// let type = typed.type
// let range = dT.t.getRange(typed)
// let val = range.max.sub(new dT.BN(Math.random()*Number.MAX_SAFE_INTEGER).mul(range.max.sub(range.min)).div(new dT.BN(Number.MAX_SAFE_INTEGER)))
// return ({value: val, type: type})
// },
}
dT.controls["u32"] = dT.controls["i32"]
dT.controls["i64"] = dT.controls["i32"]
dT.controls["u64"] = dT.controls["i64"]
dT.controls["f64"] = dT.controls["i64"]
dT.controls["f32"] = dT.controls["i32"]

dT.controls["bbn"] = {}

dT["string"] = _.NullaryType
("string")
(dT.settings.refURL+"string")
([])
(x => typeof(x) === "string")

dT.controls["string"] = {
random: function(typed){
let val = (Math.random()+1).toString(36).substring(Math.random()*23);
typed.value = val
return typed
},

}

dT.controls["natural"] = {
min: function(min){if (min !== undefined) this._min = min; return this._min;},
max: function(max){if (max !== undefined) this._max = max; return this._max;},
random: function(typed){
let type = typed.type
let range = dT.t.getRange(typed)
let val = range.max.sub(Math.random()*Number.MAX_SAFE_INTEGER * range.max.sub(range.min) / Number.MAX_SAFE_INTEGER)
return ({value: val, type: type})
},
}


dT.enums.controls = {
random: function(typed){
let type = typed.type
let range = dT.t.getRange(typed)
let val = new dT.BN(Math.random()*Number.MAX_SAFE_INTEGER).mul(range.max.sub(range.min)).div(new dT.BN(Number.MAX_SAFE_INTEGER))
val = val.toNumber()
val = dT.enum_choices[type.substring(5)][val]
typed.value = val
return typed
}
}

dT.controls.tuple = {
random: function(typed) {
let ndx = 0, temp, ans = [], out = {value: [], type: {}};

Object.keys(typed.type).forEach(i => {
temp = {}
temp.value = typed.value instanceof Array ? typed.value[ndx] : null;
temp.type = typed.type[i]
temp.name = i
ans[i] = dT.t.apply(temp, "random")
out.value[ndx] = ans[i].value
out.type[i] = ans[i].type
ndx++
})
return out
}
}

dT.t.setComposite("type_component", { label:"string", Component:"enum:types", dimensions:"uint8[]"})


dT.controls.array = {
random: (typed)=>{typed},
}


dT["tuple"] = _.Array (_.Unknown)
dT.t.setType("integer", x=> Math.floor(x) == x , [])
dT.t.setType("natural", x=> x >=0 , [dT["integer"]])
let min = 0, max = Number.MAX_SAFE_INTEGER
dT.t.setType("ctrlrange", x=> x >= min && x <= max, [dT["natural"]])
dT.controls["ctrlrange"] = {
min: function(min){if (min) this._min = min; return this._min;},
max: function(max){if (max) this._max = max; return this._max;}
}
dT.controls["ctrlrange"].min(min)
dT.controls["ctrlrange"].max(max)
dT.t.setType("ctrllinear", x=> x >= min && x <= Math.PI, [])
dT.controls["ctrllinear"] = {
min: function(min){if (min) this._min = min; return this._min;},
max: function(max){if (max) this._max = max; return this._max;}
}
dT.controls["ctrllinear"].min(min)
dT.controls["ctrllinear"].max(Math.PI)

dT.t.setEnum("functions", [
"x=>x",
"x=>x(x)",
"(x,y)=>x",
"(x,y)=>y",
"(x,...y)=>y",
"(x,y,z)=>x(y(z))",
"(x,y,z)=>[x, z, y]",
"(x,y)=>[x, y, y]",
"x=>Math.sin(x)",
"x=>Math.cos(x)",
"x=>x*2",
"x=>x*x",
"(x,y)=>y.map(x)",
"x=>x+1",
"x=>x-1",
"x=>1/x",
"x=>0-x",

"x=>Math.sin(x)",
"x=>Math.cos(x)",
"x=>Math.tan(x)",
"x=>Math.sqrt(x)",
"x=>Math.exp(x)",
"x=>Math.log(x)",
"x=>Math.abs(x)",
"x=>Math.floor(x)",
])

dT.controls.bool = {
random: function(typed){
let type = typed.type
let val = new dT.BN(Math.round(Math.random()))
typed.value = val
return typed
}
}

dT.controls.jsfunction = {
random: function(typed){
return typed
}
}

dT.typemap = [
["object", _.Object],
["function", _.Any],
["bytes20", "string"],
["address", "bytes20"],
["byte", "bytes1"],
["uint", "uint256"],
["int", "int256"],
["bool", "uint8"],
["tuple", _.Any], // may be better defined? _.RecordType
["any", _.Any],
["jsfunction", _.AnyFunction],
]
dT.t.biType("i32", -(BigInt(2) ** BigInt(32-1)-BigInt(1)), BigInt(2) ** BigInt(32-1)-BigInt(1))
dT.t.biType("u32", BigInt(0), BigInt(2) ** BigInt(32)-BigInt(1))
dT.t.biType("i64", -(BigInt(2) ** BigInt(64-1)-BigInt(1)), BigInt(2) ** BigInt(64-1)-BigInt(1))
dT.t.biType("u64", BigInt(0), BigInt(2) ** BigInt(64)-BigInt(1))

dT.t.extendTypes = function() {
S.map (((y) => {
if (y < 7) {
dT.t.bnType( "uint"+y*8, new dT.BN(0), new dT.BN(2).pow(new dT.BN(y*8)))
dT.t.bnType( "int"+y*8, new dT.BN(2).pow(new dT.BN(y*8-1)).neg(), new dT.BN(2).pow(new dT.BN(y*8-1)))
} else {
dT.t.bbnType( "uint"+y*8, new dT.BN(0), new dT.BN(2).pow(new dT.BN(y*8)))
dT.t.bbnType( "int"+y*8, new dT.BN(2).pow(new dT.BN(y*8-1)).neg(), new dT.BN(2).pow(new dT.BN(y*8-1)))
}
dT.t.byteType("bytes"+y, y)
})) (S.range (1) (33));

dT.typemap.map(x=>{
if (x[1] in dT.controls) {
dT.t.setType(x[0], x=>true,[dT[x[1]]])
dT.controls[x[0]] = Object.assign(
{},
dT.controls[x[1]],
dT.controls[x[0]] || {},
);
} else {
dT.t.setType(x[0], x=>true,[x[1]])
}
})
}

dT.t.extendTypes();
return dT
}
Insert cell
md `## Imports`
Insert cell
guify = require('guify@0.12.0/lib/guify.min.js');
Insert cell
S = require ('sanctuary');
Insert cell
_ = require ('sanctuary-def');
Insert cell
BN = require('https://bundle.run/bn.js');
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more