functionalscript
Version:
FunctionalScript is a purely functional subset of JavaScript
86 lines (83 loc) • 2.2 kB
JavaScript
import { stringToCodePointList } from "../../text/utf16/module.f.js";
import { toArray } from "../../types/list/module.f.js";
const { entries } = Object;
const find = (map) => (fr) => {
for (const [k, v] of entries(map)) {
if (v === fr) {
return k;
}
}
return undefined;
};
const newName = (map, name) => {
let i = 0;
let result = name;
while (result in map) {
result = name + i;
++i;
}
return result;
};
const sequence = (list) => map => {
let result = [];
let set = {};
for (const fr of list) {
const [map1, set1, id] = toDataAdd(map)(fr);
map = map1;
set = { ...set, ...set1 };
result = [...result, id];
}
return [map, set, result];
};
const variant = (fr) => map => {
let set = {};
let rule = {};
for (const [k, v] of entries(fr)) {
const [m1, s, id] = toDataAdd(map)(v);
map = m1;
set = { ...set, ...s };
rule = { ...rule, [k]: id };
}
return [map, set, rule];
};
const data = (dr) => {
switch (typeof dr) {
case 'string': {
return sequence(toArray(stringToCodePointList(dr)));
}
case 'number':
return m => [m, {}, dr];
default:
if (dr instanceof Array) {
return sequence(dr);
}
return variant(dr);
}
};
const toDataAdd = (map) => (fr) => {
{
const id = find(map)(fr);
if (id !== undefined) {
return [map, {}, id];
}
}
const [dr, tmpId] = typeof fr === 'function' ? [fr(), fr.name] : [fr, ''];
const newRule = data(dr);
const id = newName(map, tmpId);
const map1 = { ...map, [id]: fr };
const [map2, set, rule] = newRule(map1);
return [map2, { ...set, [id]: rule }, id];
};
export const toData = (fr) => {
const [, ruleSet, id] = toDataAdd({})(fr);
return [ruleSet, id];
};
// type Dispatch = RangeMapArray<string>;
/**
* Either `{ variantItem: id }` or `id`.
*/
/*
type DispatchRule = SingleProperty<> | string
type Dispatch = RangeMapArray<DispatchRule>
type DispatchMap = { readonly[id in string]: Dispatch }
*/