Skip to content

Commit

Permalink
Improve astToString, add tests for astToString
Browse files Browse the repository at this point in the history
  • Loading branch information
Hsiwe committed Nov 5, 2023
1 parent 6b443b3 commit f6a0bdf
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 10 deletions.
18 changes: 18 additions & 0 deletions dev/test/astUtils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { describe, it} from "mocha";
import type { astToString } from "../../src/parse/ast/utils.js";
import { attest } from "../attest/main.js";

describe('astToString', () => {
it('no parentheses if nested ast is an array', () => {
const t = {} as unknown as astToString<[["number", "[]"], "|", "number"]>
attest(t).typed as "'number[]|number'"
});
it('parentheses if nested ast is an infix expression', () => {
const t = {} as unknown as astToString<[["0", "|", "1"], "|", "string"]>
attest(t).typed as "'(0|1)|string'"
});
it('defaults to "..." if input is bad', () => {
const t = {} as unknown as astToString<["0", "///", "1"]>
attest(t).typed as "'...'"
});
});
33 changes: 23 additions & 10 deletions src/parse/ast/utils.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
import type { Literalable } from "../../utils/generics.js"
import type { List, Literalable } from "../../utils/generics.js"
import type { Scanner } from "../string/shift/scanner.js"
import type { InfixExpression, PostfixExpression } from "./ast.js"

export type astToString<ast> = `'${astToStringRecurse<ast, "">}'`

type astToStringRecurse<ast, result extends string> = ast extends [
infer head,
...infer tail
]
? astToStringRecurse<tail, `${result}${astToStringRecurse<head, "">}`>
export type astToString<ast> = `'${astToStringRecurse<ast>}'`;

type astToStringRecurse<ast> =
ast extends PostfixExpression<infer operator, infer operand>
? operator extends "[]"
? `${groupAst<operand>}[]`
: never
: ast extends InfixExpression<infer operator, infer l, infer r>
? operator extends "&" | "|" | "%" | Scanner.Comparator
? `${groupAst<l>}${operator}${groupAst<r>}`
: never
: ast extends Literalable
? `${result}${ast extends bigint ? `${ast}n` : ast}`
: "..."
? `${ast extends bigint ? `${ast}n` : ast}`
: "..."


type groupAst<ast> = ast extends List
? ast[1] extends "[]"
? astToStringRecurse<ast>
: `(${astToStringRecurse<ast>})`
: astToStringRecurse<ast>

0 comments on commit f6a0bdf

Please sign in to comment.