37 lines
1.5 KiB
JavaScript
37 lines
1.5 KiB
JavaScript
import { inspect } from 'node:util';
|
||
import { symbolDict, symbolFunction, symbolList, symbolProduct, symbolSum, symbolSet } from '../structures/type_constructors.js';
|
||
import { getHumanReadableName } from '../primitives/symbol.js';
|
||
import { getSymbol } from '../primitives/type.js';
|
||
|
||
export function pretty(obj) {
|
||
return inspect(obj, { colors: true, depth: null, breakLength: 120 });
|
||
}
|
||
|
||
// Pretty print Type
|
||
export const _prettyT = (depth, tags) => type => {
|
||
if (typeof type === 'number' && type < depth) {
|
||
// we've already seen this type, so we'll tag it
|
||
// we mutate tags in-place so our parent type can see it
|
||
const hashTag = `#${tags.size}`;
|
||
// upper level will be tagged:
|
||
tags.set(type, hashTag);
|
||
// and this level is entirely replaced by tag:
|
||
return hashTag;
|
||
}
|
||
const params = type.params.map(p => _prettyT(depth+1, tags)(p(depth)));
|
||
const annot = tags.get(depth) || '';
|
||
return renderType(getSymbol(type), annot, params);
|
||
}
|
||
|
||
export const prettyT = type => _prettyT(0, new Map())(type);
|
||
|
||
const renderType = (symbol, annot, params) => {
|
||
return {
|
||
[symbolList] : `${annot}[${params[0]}]`,
|
||
[symbolSet] : `${annot}{${params[0]}}`,
|
||
[symbolFunction]: `${annot}(${params[0]} -> ${params[1]})`,
|
||
[symbolSum] : `${annot}(${params[0]} + ${params[1]})`,
|
||
[symbolProduct] : `${annot}(${params[0]} ⨯ ${params[1]})`,
|
||
[symbolDict] : `${annot}(${params[0]} => ${params[1]})`,
|
||
}[symbol] || getHumanReadableName(symbol);
|
||
};
|