Public
Edited
Sep 20, 2023
Importers
Insert cell
Insert cell
function assignNameClass(cls, obj) {
for (const [name, value] of Object.entries(obj)) {
if (Array.isArray(value)) {
for (const elem of value) {
elem.class = cls;
elem.name = name;
const argTypes = Object.values(elem.args).map(t => t.name);
elem.sign = '(' + argTypes.join(', ') + ')';
}
} else {
value.class = cls;
value.name = name;
}
}
return obj;
}
Insert cell
Insert cell
types = assignNameClass('type', {
int: {
check: x => typeof x === 'number' && Math.floor(x) === x,
},
float: {
check: x => typeof x === 'number',
},
vec2: {
check: x => Array.isArray(x) && x.length === 2,
},
ivec2: {
check: x => Array.isArray(x) && x.length === 2,
},
vec3: {
check: x => Array.isArray(x) && x.length === 3,
},
vec4: {
check: x => Array.isArray(x) && x.length === 4,
},
mat2: {
check: x => Array.isArray(x) && x.length === 4,
},
bool: {
check: x => typeof x === 'boolean',
},
function: {
check: x => typeof x === 'function',
},
assignments: {
check: x => typeof x === 'function',
},
polymorphic: {
check: x => Array.isArray(x) && x.every(obj => obj.class === 'function'),
},
})
Insert cell
valueTypes = [types.int, types.float, types.vec2, types.vec3, types.vec4, types.mat2, types.bool];
Insert cell
Insert cell
lib = assignNameClass('function', ({
...libControlStructures,
...libNumericFuncs,
...libNumericOps,
...libBool,
...libComparison,
...libProperies,
...libTrigonometry,
...libTypeConstructors,
}))
Insert cell
Insert cell
libControlStructures = ({
['?:']: valueTypes.map(valueType => ({
args: {
cond: types.bool,
ifTrue: valueType,
ifFalse: valueType,
},
resType: valueType,
js: (cond, ifTrue, ifFalse) => cond ? ifTrue : ifFalse,
})),
if: [{
args: {
cond: types.bool,
ifTrue: types.assignments,
},
resType: types.assignments,
js: (cond, ifTrue) => ctx => {
if (cond) {
return ifTrue(ctx);
} else {
return ctx;
}
},
}, {
args: {
cond: types.bool,
ifTrue: types.assignments,
ifFalse: types.assignments,
},
resType: types.assignments,
js: (cond, ifTrue, ifFalse) => ctx => {
if (cond) {
return ifTrue(ctx);
} else {
return ifFalse(ctx);
}
}
}],
forInRange: [{
args: {
count: types.int,
body: types.assignments,
},
resType: types.assignments,
js: (count, body) => ctx => {
let res = ctx;
for (let i=0; i<count; i++) {
res = body(res);
}
return res;
},
}],
})
Insert cell
Insert cell
libNumericOps = ({
['+']: [{
args: {
a: types.float,
b: types.float,
},
resType: types.float,
js: (a, b) => a + b,
}, {
args: {
a: types.vec2,
b: types.float,
},
resType: types.vec2,
js: ([a0, a1], b) => [a0 + b, a1 + b],
}, {
args: {
a: types.vec3,
b: types.vec3,
},
resType: types.vec3,
js: ([a0, a1, a2], [b0, b1, b2]) => [a0 + b0, a1 + b1, a2 + b2],
}, {
args: {
a: types.vec4,
b: types.vec4,
},
resType: types.vec4,
js: ([a0, a1, a2, a3], [b0, b1, b2, b3]) => [a0 + b0, a1 + b1, a2 + b2, a3 + b3],
}],
['-@']: [{
args: {x: types.float},
resType: types.float,
js: x => -x,
}],
['-']: [{
args: {
a: types.float,
b: types.float,
},
resType: types.float,
js: (a, b) => a - b,
}, {
args: {
a: types.vec2,
b: types.vec2,
},
resType: types.vec2,
js: ([a0, a1], [b0, b1]) => [a0 - b0, a1 - b1],
}, {
args: {
a: types.vec2,
b: types.float,
},
resType: types.vec2,
js: ([a0, a1], b) => [a0 - b, a1 - b],
}, {
args: {
a: types.float,
b: types.vec3,
},
resType: types.vec3,
js: ([a0, a1, a2], b) => [a0 - b, a1 - b, a2 - b],
}, {
args: {
a: types.float,
b: types.vec4,
},
resType: types.vec2,
js: ([a0, a1], b) => [a0 - b, a1 - b],
}],
['*']: [{
args: {
a: types.float,
b: types.float,
},
resType: types.float,
js: (a, b) => a * b,
}, {
args: {
a: types.int,
b: types.int,
},
resType: types.int,
js: (a, b) => a * b,
}, {
args: {
a: types.vec2,
b: types.float,
},
resType: types.vec2,
js: ([a0, a1], b) => [a0 * b, a1 * b],
}, {
args: {
a: types.vec3,
b: types.float,
},
resType: types.vec3,
js: ([a0, a1, a2], b) => [a0 * b, a1 * b, a2 * b],
}, {
args: {
a: types.vec2,
b: types.mat2,
},
resType: types.vec2,
js: ([a0, a1], [b0, b1, b2, b3]) => [a0 * b0 + a1 * b2, a0 * b1 + a1 * b3],
}, {
args: {
a: types.vec3,
b: types.vec3,
},
resType: types.vec3,
js: ([a0, a1, a2], [b0, b1, b2]) => [a0 * b0, a1 * b1, a2 * b2],
}, {
args: {
a: types.float,
b: types.vec4,
},
resType: types.vec4,
js: (a, [b0, b1, b2, b3]) => [a * b0, a * b1, a * b2, a * b3],
}],
['/']: [{
args: {
a: types.float,
b: types.float,
},
resType: types.float,
js: (a, b) => a / b,
}, {
args: {
a: types.vec2,
b: types.float,
},
resType: types.vec2,
js: ([a0, a1], b) => [a0 / b, a1 / b],
}, {
args: {
a: types.vec3,
b: types.float,
},
resType: types.vec3,
js: ([a0, a1, a2], b) => [a0 / b, a1 / b, a2 / b],
}]
})
Insert cell
Insert cell
libComparison = ({
['<']: [{
args: {
a: types.float,
b: types.float,
},
resType: types.bool,
js: (a, b) => a < b,
}],

['>']: [{
args: {
a: types.float,
b: types.float,
},
resType: types.bool,
js: (a, b) => a > b,
}],
['==']: [{
args: {
a: types.float,
b: types.float,
},
resType: types.bool,
js: (a, b) => a == b,
}, {
args: {
a: types.int,
b: types.int,
},
resType: types.bool,
js: (a, b) => a == b,
}, {
args: {
a: types.bool,
b: types.bool,
},
resType: types.bool,
js: (a, b) => a == b,
}]
})
Insert cell
Insert cell
libBool = ({
['||']: [{
args: {
a: types.bool,
b: types.bool,
},
resType: types.bool,
js: (a, b) => a || b,
}],
['&&']: [{
args: {
a: types.bool,
b: types.bool,
},
resType: types.bool,
js: (a, b) => a && b,
}],
['!@']: [{
args: {
a: types.bool,
},
resType: types.bool,
js: a => !a,
}],
})
Insert cell
Insert cell
libProperies = ({
['.xy']: [{
args: {x: types.vec2},
resType: types.vec2,
js: ([x0, x1]) => [x0, x1],
}, {
args: {x: types.vec3},
resType: types.vec2,
js: ([x0, x1, x2]) => [x0, x1],
}, {
args: {x: types.vec4},
resType: types.vec2,
js: ([x0, x1, x2, x3]) => [x0, x1],
}],
['.yx']: [{
args: {x: types.vec2},
resType: types.vec2,
js: ([x0, x1]) => [x1, x0],
}],
['.x']: [{
args: {x: types.vec2},
resType: types.float,
js: ([x0, x1]) => x0,
}, {
args: {x: types.ivec2},
resType: types.int,
js: ([x0, x1]) => x0,
}, {
args: {x: types.vec3},
resType: types.float,
js: ([x0, x1, x2]) => x0,
}],
['.y']: [{
args: {x: types.vec2},
resType: types.float,
js: ([x0, x1]) => x1,
}, {
args: {x: types.ivec2},
resType: types.int,
js: ([x0, x1]) => x1,
}, {
args: {x: types.vec3},
resType: types.float,
js: ([x0, x1, x2]) => x1,
}]
})
Insert cell
Insert cell
libTypeConstructors = ({
float: [{
args: {x: types.bool},
resType: types.float,
js: x => x ? 1 : 0,
}, {
args: {x: types.int},
resType: types.float,
js: x => x,
}],
vec2: [{
args: {a: types.float, b: types.float},
resType: types.vec2,
js: (a, b) => [a, b],
}, {
args: {a: types.ivec2},
resType: types.vec2,
js: ([a0, a1]) => [a0, a1],
}, {
args: {a: types.bool},
resType: types.vec2,
js: (b) => [Number(b), Number(b)],
}],
ivec2: [{
args: {a: types.float, b: types.float},
resType: types.ivec2,
js: (a, b) => [Math.floor(a), Math.floor(b)],
}, {
args: {a: types.vec2},
resType: types.ivec2,
js: ([a0, a1]) => [Math.floor(a0), Math.floor(a1)],
}],

vec3: [{
args: {a: types.float},
resType: types.vec3,
js: a => [a, a, a],
}, {
args: {a: types.bool},
resType: types.vec3,
js: a => [Number(a), Number(a), Number(a)],
}, {
args: {
a: types.float,
b: types.float,
c: types.float,
},
resType: types.vec3,
js: (a, b, c) => [a, b, c],
}],
vec4: [{
args: {
a: types.vec3,
b: types.float,
},
resType: types.vec4,
js: ([a0, a1, a2], b) => [a0, a1, a2, b],
}, {
args: {
a: types.vec2,
b: types.float,
c: types.float,
},
resType: types.vec4,
js: ([a0, a1], b, c) => [a0, a1, b, c],
}, {
args: {
a: types.float,
b: types.float,
c: types.float,
d: types.float,
},
resType: types.vec4,
js: (a, b, c, d) => [a, b, c, d],
}],
mat2: [{
args: {
a0: types.float,
a1: types.float,
a2: types.float,
a3: types.float,
},
resType: types.mat2,
js: (a0, a1, a2, a3) => [a0, a1, a2, a3],
}],
})
Insert cell
Insert cell
libTrigonometry = ({
cos: [{
args: {x: types.float},
resType: types.float,
js: x => Math.cos(x),
}],
sin: [{
args: {x: types.float},
resType: types.float,
js: x => Math.sin(x),
}],
})
Insert cell
Insert cell
libNumericFuncs = ({
mod: [{
args: {
x: types.float,
m: types.float,
},
resType: types.float,
js: (x, m) => (x % m + m) % m,
}],
fract: [{
args: {
x: types.float,
},
resType: types.float,
js: (x) => ((x % 1) + 1) % 1,
}, {
args: {
x: types.vec2,
},
resType: types.vec2,
js: ([x0, x1]) => [((x0 % 1) + 1) % 1, ((x1 % 1) + 1) % 1],
}],
abs: [{
args: {
x: types.float,
},
resType: types.float,
js: x => Math.abs(x),
}, {
args: {
x: types.vec2,
},
resType: types.vec2,
js: ([x0, x1]) => [Math.abs(x0), Math.abs(x1)],
}],
pow: [{
args: {
x: types.float,
deg: types.float,
},
resType: types.float,
js: (x, deg) => Math.pow(x, deg),
}]
})
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