import type { defined, error, NumberLiteral } from "../../../../dev/utils/src/main.js" import type { Comparator, InvertedComparators, MaxComparator, MinComparator } from "../../../nodes/primitive/range.js" import type { Scanner } from "../shift/scanner.js" import type { StringifiablePrefixOperator, writeMultipleLeftBoundsMessage, writeOpenRangeMessage, writeUnclosedGroupMessage, writeUnmatchedGroupCloseMessage, writeUnpairableComparatorMessage } from "./shared.js" export type StaticState = { root: unknown branches: BranchState groups: BranchState[] finalizer: Scanner.FinalizingLookahead | error | undefined scanned: string unscanned: string } type StaticOpenLeftBound = { limit: NumberLiteral; comparator: MinComparator } export type AutocompletePrefix = `${StringifiablePrefixOperator} ` type BranchState = { prefixes: StringifiablePrefixOperator[] range: StaticOpenLeftBound | undefined "&": unknown "|": unknown } export namespace state { export type initialize = from<{ root: undefined branches: initialBranches groups: [] finalizer: undefined scanned: "" unscanned: def }> export type error = from<{ root: undefined branches: initialBranches groups: [] finalizer: `!${message}` scanned: "" unscanned: "" }> type initialBranches = branchesFrom<{ prefixes: [] range: undefined "&": undefined "|": undefined }> type updateScanned< previousScanned extends string, previousUnscanned extends string, updatedUnscanned extends string > = previousUnscanned extends `${infer justScanned}${updatedUnscanned}` ? `${previousScanned}${justScanned}` : previousScanned export type setRoot< s extends StaticState, root, unscanned extends string > = from<{ root: root branches: s["branches"] groups: s["groups"] finalizer: s["finalizer"] scanned: updateScanned unscanned: unscanned }> export type addPrefix< s extends StaticState, prefix extends StringifiablePrefixOperator, unscanned extends string > = from<{ root: s["root"] branches: { prefixes: [...s["branches"]["prefixes"], prefix] range: s["branches"]["range"] "&": s["branches"]["&"] "|": s["branches"]["|"] } groups: s["groups"] finalizer: s["finalizer"] scanned: updateScanned unscanned: unscanned }> export type reduceBranch< s extends StaticState, token extends "|" | "&", unscanned extends string > = s["branches"]["range"] extends {} ? openRangeError : from<{ root: undefined branches: { prefixes: [] range: undefined "&": token extends "&" ? mergeToIntersection : undefined "|": token extends "|" ? mergeToUnion : s["branches"]["|"] } groups: s["groups"] finalizer: s["finalizer"] scanned: updateScanned unscanned: unscanned }> export type reduceLeftBound< s extends StaticState, limit extends NumberLiteral, comparator extends Comparator, unscanned extends string > = comparator extends "<" | "<=" ? s["branches"]["range"] extends {} ? state.error< writeMultipleLeftBoundsMessage< s["branches"]["range"]["limit"], s["branches"]["range"]["comparator"], limit, InvertedComparators[comparator] > > : from<{ root: undefined branches: { prefixes: s["branches"]["prefixes"] range: { limit: limit comparator: InvertedComparators[comparator] } "&": s["branches"]["&"] "|": s["branches"]["|"] } groups: s["groups"] finalizer: s["finalizer"] scanned: updateScanned< s["scanned"], s["unscanned"], unscanned > unscanned: unscanned }> : state.error> export type reduceRange< s extends StaticState, minLimit extends NumberLiteral, minComparator extends MinComparator, maxComparator extends MaxComparator, maxLimit extends NumberLiteral, unscanned extends string > = state.from<{ root: [minLimit, minComparator, [s["root"], maxComparator, maxLimit]] branches: { prefixes: s["branches"]["prefixes"] range: undefined "&": s["branches"]["&"] "|": s["branches"]["|"] } groups: s["groups"] finalizer: s["finalizer"] scanned: updateScanned unscanned: unscanned }> export type reduceSingleBound< s extends StaticState, comparator extends Comparator, limit extends NumberLiteral, unscanned extends string > = state.from<{ root: [s["root"], comparator, limit] branches: { prefixes: s["branches"]["prefixes"] range: undefined "&": s["branches"]["&"] "|": s["branches"]["|"] } groups: s["groups"] finalizer: s["finalizer"] scanned: updateScanned unscanned: unscanned }> type mergeToUnion = s["branches"]["|"] extends undefined ? mergeToIntersection : [s["branches"]["|"], "|", mergeToIntersection] type mergeToIntersection = s["branches"]["&"] extends undefined ? mergePrefixes : [s["branches"]["&"], "&", mergePrefixes] type mergePrefixes< s extends StaticState, remaining extends unknown[] = s["branches"]["prefixes"] > = remaining extends [infer head, ...infer tail] ? [head, mergePrefixes] : s["root"] type popGroup = [ ...stack, top ] export type finalizeGroup< s extends StaticState, unscanned extends string > = s["branches"]["range"] extends {} ? openRangeError : s["groups"] extends popGroup ? from<{ groups: stack branches: top root: mergeToUnion finalizer: s["finalizer"] scanned: updateScanned unscanned: unscanned }> : state.error> export type reduceGroupOpen< s extends StaticState, unscanned extends string > = from<{ groups: [...s["groups"], s["branches"]] branches: initialBranches root: undefined finalizer: s["finalizer"] scanned: updateScanned unscanned: unscanned }> export type finalize< s extends StaticState, finalizer extends Scanner.FinalizingLookahead > = s["groups"] extends [] ? s["branches"]["range"] extends {} ? openRangeError : from<{ root: mergeToUnion groups: s["groups"] branches: initialBranches finalizer: finalizer scanned: s["scanned"] unscanned: s["unscanned"] }> : state.error> type openRangeError> = state.error> export type previousOperator = s["branches"]["range"] extends {} ? s["branches"]["range"]["comparator"] : s["branches"]["prefixes"] extends [ ...unknown[], infer tail extends string ] ? tail : s["branches"]["&"] extends {} ? "&" : s["branches"]["|"] extends {} ? "|" : undefined export type scanTo = from<{ root: s["root"] branches: s["branches"] groups: s["groups"] finalizer: s["finalizer"] scanned: updateScanned unscanned: unscanned }> export type from = s export type branchesFrom = b }