Fixing pretty print ast. adding a few more builtins :( getting further with inspector

This commit is contained in:
Dustin Swan 2026-02-10 16:46:31 -07:00
parent 30234875fe
commit 8bc05efa1e
No known key found for this signature in database
GPG key ID: 30D46587E2100467
9 changed files with 272 additions and 82 deletions

View file

@ -109,7 +109,11 @@ export type List = {
export type Record = {
kind: 'record'
fields: { [key: string]: AST }
entries: Array<
| { kind: 'field', key: string, value: AST }
| { kind: 'spread', expr: AST }
>
// fields: { [key: string]: AST }
line?: number
column?: number
start?: number
@ -190,61 +194,77 @@ export type AST =
| Rebind
export function prettyPrint(ast: AST, indent = 0): string {
const i = ' '.repeat(indent);
const i = ' '.repeat(indent);
switch (ast.kind) {
case 'literal': {
const val = ast.value;
switch (val.kind) {
case 'int':
case 'float':
return `${i}${val.value}`;
case 'string':
return `${i}"${val.value}"`;
if (val.kind === 'string') {
return `${i}"${val.value}"`;
}
return `${i}${val.value}`;
}
case 'variable':
return `${i}${ast.name}`;
case 'constructor':
return `${i}${ast.name}`;
return ast.name;
case 'apply':
const func = prettyPrint(ast.func, 0);
const args = ast.args.map(a => prettyPrint(a, 0)).join(' ');
return `${i}(${func} ${args})`
return `(${func} ${args})`
case 'let':
return `${i}let ${ast.name} = \n${prettyPrint(ast.value, indent + 1)}\n${i}in\n${prettyPrint(ast.body, indent + 1)}`
return `${ast.name} = ${prettyPrint(ast.value, indent + 1)};\n${i}${prettyPrint(ast.body, indent)}`
case 'list':
const elems = ast.elements.map(e => prettyPrint(e, 0)).join(', ');
return `${i}[${elems}]`;
return `[${elems}]`;
case 'record':
const fields = Object.entries(ast.fields)
.map(([k, v]) => `${k} = ${prettyPrint(v, 0)}`)
.join(', ');
return `${i}{${fields}}`;
const parts = ast.entries.map(entry =>
entry.kind === 'spread'
? `...${prettyPrint(entry.expr, )}`
: `${entry.key} = ${prettyPrint(entry.value, 0)}`
);
return `{ ${parts.join(', ') }`;
case 'lambda':
const params = ast.params.join(', ');
return `${i}(${params}) => ${prettyPrint(ast.body)}`
case 'lambda': {
const params = ast.params.join(' ');
const body = prettyPrint(ast.body, indent + 1);
const isComplex = ast.body.kind === 'match' || ast.body.kind === 'let';
if (isComplex) {
return `${params} \\\n${body}`
}
return `${params} \\ ${body}`
}
case 'record-access':
return `${i}${prettyPrint(ast.record)}.${ast.field}`;
return `${prettyPrint(ast.record, 0)}.${ast.field}`;
case 'record-update':
const updates = Object.entries(ast.updates).map(([k, v]) => `${k} = ${prettyPrint(v, 0)}`).join(', ');
return `${i}${prettyPrint(ast.record)} { ${updates} }`
case 'record-update': {
const updates = Object.entries(ast.updates)
.map(([k, v]) => `${k} = ${prettyPrint(v, 0)}`)
.join(', ');
return `${prettyPrint(ast.record, 0)}.{ ${updates} }`
}
case 'match':
const expr = prettyPrint(ast.expr, 0);
const cases = ast.cases
.map(c => ` | ${prettyPrintPattern(c.pattern)} -> ${prettyPrint(c.result, 0)}`)
.map(c => `${i}| ${prettyPrintPattern(c.pattern)} \\ ${prettyPrint(c.result, indent + 1)}`)
.join('\n');
return `${i}match ${expr}\n${cases}`;
return `${expr}\n${cases}`;
case 'rebind':
return `${prettyPrint(ast.target, 0)} := ${prettyPrint(ast.value, 0)}`;
case 'list-spread':
return `...${prettyPrint(ast.spread, 0)}`;
case 'definition':
return `${ast.name} = ${prettyPrint(ast.body, indent)}`;
default:
return `Unknown AST kind: ${i}${(ast as any).kind}`
@ -273,6 +293,12 @@ function prettyPrintPattern(pattern: Pattern): string {
const elems = pattern.elements.map(prettyPrintPattern).join(', ');
return `[${elems}]`;
case 'list-spread':
const head = pattern.head.map(prettyPrintPattern).join(', ');
return head.length > 0
? `[${head}, ...${pattern.spread}]`
: `[...${pattern.spread}]`;
case 'record':
const fields = Object.entries(pattern.fields)
.map(([k, p]) => `${k} = ${prettyPrintPattern(p)}`)