|
|
|
@ -178,6 +178,8 @@ const infixOps: { [key: string]: string } = {
|
|
|
|
pow: '^', eq: '==', neq: '!=', gt: '>', lt: '<', gte: '>=', lte: '<='
|
|
|
|
pow: '^', eq: '==', neq: '!=', gt: '>', lt: '<', gte: '>=', lte: '<='
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const isInfix = (a: AST) => a.kind === 'apply' && a.func.kind === 'variable' && a.args.length === 2 && infixOps[a.func.name];
|
|
|
|
|
|
|
|
|
|
|
|
export function prettyPrint(ast: AST, indent = 0): string {
|
|
|
|
export function prettyPrint(ast: AST, indent = 0): string {
|
|
|
|
const i = ' '.repeat(indent);
|
|
|
|
const i = ' '.repeat(indent);
|
|
|
|
|
|
|
|
|
|
|
|
@ -201,25 +203,33 @@ export function prettyPrint(ast: AST, indent = 0): string {
|
|
|
|
|
|
|
|
|
|
|
|
case 'apply':
|
|
|
|
case 'apply':
|
|
|
|
// infix ops
|
|
|
|
// infix ops
|
|
|
|
if (ast.func.kind === 'variable' && ast.args.length === 2 && infixOps[ast.func.name]) {
|
|
|
|
if (isInfix(ast)) {
|
|
|
|
const left = prettyPrint(ast.args[0], indent);
|
|
|
|
const wrapIfNeeded = (a: AST) => {
|
|
|
|
const right = prettyPrint(ast.args[1], indent);
|
|
|
|
const printed = prettyPrint(a, indent);
|
|
|
|
return `${left} ${infixOps[ast.func.name]} ${right}`;
|
|
|
|
if (a.kind === 'apply' || a.kind === 'lambda' || a.kind === 'match' || a.kind === 'let') {
|
|
|
|
|
|
|
|
return `(${printed})`;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return `${printed}`;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const left = wrapIfNeeded(ast.args[0]);
|
|
|
|
|
|
|
|
const right = wrapIfNeeded(ast.args[1]);
|
|
|
|
|
|
|
|
return `${left} ${infixOps[(ast.func as Variable).name]} ${right}`;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const func = prettyPrint(ast.func, indent);
|
|
|
|
const func = prettyPrint(ast.func, indent);
|
|
|
|
const args = ast.args.map(a => {
|
|
|
|
const args = ast.args.map(a => {
|
|
|
|
const printed = prettyPrint(a, indent);
|
|
|
|
const printed = prettyPrint(a, indent);
|
|
|
|
if (a.kind === 'lambda' || a.kind === 'match' || a.kind === 'let' || a.kind === 'rebind') {
|
|
|
|
if (a.kind === 'lambda' || a.kind === 'match' || a.kind === 'let' || a.kind === 'rebind' || a.kind === 'apply') {
|
|
|
|
return `(${printed})`;
|
|
|
|
return `(${printed})`;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return printed;
|
|
|
|
return printed;
|
|
|
|
}).join(' ');
|
|
|
|
}).join(' ');
|
|
|
|
|
|
|
|
|
|
|
|
if (ast.func.kind === 'variable' || ast.func.kind === 'constructor') {
|
|
|
|
if (ast.func.kind === 'lambda' || ast.func.kind === 'match' || ast.func.kind === 'let') {
|
|
|
|
return `${func} ${args}`
|
|
|
|
return `(${func} ${args})`
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return `(${func} ${args})`
|
|
|
|
return `${func} ${args}`
|
|
|
|
|
|
|
|
|
|
|
|
case 'let':
|
|
|
|
case 'let':
|
|
|
|
const sep = indent === 0 ? '\n\n' : '\n';
|
|
|
|
const sep = indent === 0 ? '\n\n' : '\n';
|
|
|
|
|