49 lines
1.9 KiB
JavaScript
49 lines
1.9 KiB
JavaScript
import { inspect } from 'node:util';
|
||
import { symbolDict, symbolFunction, symbolList, symbolProduct, symbolSum } from '../structures/type_constructors.js';
|
||
import { symbolSet } from "../structures/type_constructors.js";
|
||
import { mapRecursiveStructure } from './util.js';
|
||
import { getHumanReadableName } from '../primitives/symbol.js';
|
||
|
||
export function pretty(obj) {
|
||
return inspect(obj, { colors: true, depth: null, breakLength: 120 });
|
||
}
|
||
|
||
// Pretty print Type
|
||
export const prettyT = type => {
|
||
return mapRecursiveStructure(([type, m, seen], map) => {
|
||
if (typeof type === "symbol") {
|
||
// type variable
|
||
return type.description;
|
||
}
|
||
// if (type.params === undefined) {
|
||
// throw new Error("parameter is not a Type ... did you mean to call prettyGenT instead?")
|
||
// }
|
||
if (!m.has(type)) {
|
||
m.add(type); // next time we encounter this type, we'll only render a placeholder
|
||
const params = type.params.map(p => map([p(type), m, seen])());
|
||
// if while visiting the children, we encountered ourselves, add annotation:
|
||
const annot = seen.has(type) ? seen.get(type) : ``;
|
||
return renderType(type.symbol, annot, params);
|
||
}
|
||
if (!seen.has(type)) {
|
||
seen.set(type, `#${seen.size}`);
|
||
}
|
||
return seen.get(type);
|
||
})([type, new Set(), new Map()])();
|
||
};
|
||
|
||
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);
|
||
};
|
||
|
||
// Pretty print GenericType
|
||
export const prettyGenT = genericType => {
|
||
return `∀${[...genericType.typeVars].map(prettyT).sort((a, b) => a.localeCompare(b)).join(",")}: ${prettyT(genericType.type)}`;
|
||
};
|