{"version":3,"sources":["../src/error-formatter.ts","../src/index.ts","../src/either.ts","../src/errors.ts","../src/state.ts","../src/parser.ts","../src/combinators.ts","../src/hints.ts","../src/utils.ts"],"sourcesContent":["import type { ParseError, ParseErrorBundle } from \"./errors\";\n\nexport type ErrorFormat = \"plain\" | \"ansi\" | \"html\" | \"json\";\n\nexport type ErrorFormatterOptions = {\n  maxContextLines?: number;\n  showHints?: boolean;\n  colorize?: boolean;\n  showContext?: boolean;\n  tabSize?: number;\n};\n\n/**\n * Formats ParseErrorBundle into human-readable error messages with multiple output formats.\n * Supports plain text, ANSI colors, HTML, and JSON formats.\n */\nexport class ErrorFormatter {\n  private _format: ErrorFormat;\n  private options: ErrorFormatterOptions;\n\n  constructor(\n    format: ErrorFormat = \"plain\",\n    options: ErrorFormatterOptions = {}\n  ) {\n    this._format = format;\n    // Set default options\n    this.options = {\n      maxContextLines: 3,\n      showHints: true,\n      colorize: true,\n      showContext: true,\n      tabSize: 2,\n      ...options\n    };\n  }\n\n  /**\n   * Format a ParseErrorBundle into a string based on the configured format.\n   *\n   * @param bundle - The error bundle to format\n   * @returns Formatted error message string\n   */\n  format(bundle: ParseErrorBundle): string {\n    switch (this._format) {\n      case \"ansi\":\n        return this.formatAnsi(bundle);\n      case \"html\":\n        return this.formatHtml(bundle);\n      case \"json\":\n        return this.formatJson(bundle);\n      default:\n        return this.formatPlain(bundle);\n    }\n  }\n\n  /**\n   * Format error with ANSI color codes for terminal output.\n   */\n  private formatAnsi(bundle: ParseErrorBundle): string {\n    const primary = bundle.primary;\n    const lines = bundle.source.split(\"\\n\");\n    const errorLine = lines[primary.span.line - 1] || \"\";\n\n    const parts: string[] = [];\n\n    // Error header with location\n    parts.push(\n      `\\x1b[31mError\\x1b[0m at line ${primary.span.line}, column ${primary.span.column}:`\n    );\n\n    // Show context lines if enabled\n    if (this.options.showContext && this.options.maxContextLines! > 0) {\n      const contextLines = this.getContextLines(\n        lines,\n        primary.span.line - 1,\n        this.options.maxContextLines!\n      );\n      parts.push(...contextLines.map(line => `  ${line}`));\n    } else {\n      // Just show the error line\n      parts.push(`  ${errorLine}`);\n    }\n\n    // Add pointer arrow (accounting for line prefix)\n    const linePrefix = `  >   ${primary.span.line.toString().padStart(0, \" \")} | `;\n    const adjustedColumn = primary.span.column + linePrefix.length - 2; // -2 for the \"  \" we add\n    const pointer = this.createPointer(adjustedColumn, primary.span.length);\n    parts.push(`  ${pointer}`);\n\n    // Error message\n    parts.push(this.formatErrorMessage(primary));\n\n    // Add hints if available\n    const hints = this.getHints(primary);\n    if (this.options.showHints && hints.length > 0) {\n      parts.push(\"\");\n      for (const hint of hints) {\n        parts.push(`  \\x1b[36mDid you mean: ${hint}?\\x1b[0m`);\n      }\n    }\n\n    // Add context stack if available\n    if (\n      this.options.showContext &&\n      primary.context &&\n      primary.context.length > 0\n    ) {\n      parts.push(\"\");\n      parts.push(`  \\x1b[90mContext: ${primary.context.join(\" > \")}\\x1b[0m`);\n    }\n\n    return parts.join(\"\\n\");\n  }\n\n  /**\n   * Format error as plain text without colors.\n   */\n  private formatPlain(bundle: ParseErrorBundle): string {\n    const primary = bundle.primary;\n    const lines = bundle.source.split(\"\\n\");\n    const errorLine = lines[primary.span.line - 1] || \"\";\n\n    const parts: string[] = [];\n\n    // Error header\n    parts.push(\n      `Error at line ${primary.span.line}, column ${primary.span.column}:`\n    );\n\n    // Show context lines\n    if (this.options.showContext && this.options.maxContextLines! > 0) {\n      const contextLines = this.getContextLines(\n        lines,\n        primary.span.line - 1,\n        this.options.maxContextLines!\n      );\n      parts.push(...contextLines.map(line => `  ${line}`));\n    } else {\n      parts.push(`  ${errorLine}`);\n    }\n\n    // Add pointer (accounting for line prefix)\n    const linePrefix = `  >   ${primary.span.line.toString()} | `;\n    const adjustedColumn = primary.span.column + linePrefix.length - 2; // -2 for the \"  \" we add\n    const pointer = this.createPointer(\n      adjustedColumn,\n      primary.span.length,\n      false\n    );\n    parts.push(`  ${pointer}`);\n\n    // Error message\n    parts.push(this.formatErrorMessage(primary, false));\n\n    // Add hints\n    const hints = this.getHints(primary);\n    if (this.options.showHints && hints.length > 0) {\n      parts.push(\"\");\n      for (const hint of hints) {\n        parts.push(`  Did you mean: ${hint}?`);\n      }\n    }\n\n    // Add context\n    if (\n      this.options.showContext &&\n      primary.context &&\n      primary.context.length > 0\n    ) {\n      parts.push(\"\");\n      parts.push(`  Context: ${primary.context.join(\" > \")}`);\n    }\n\n    return parts.join(\"\\n\");\n  }\n\n  /**\n   * Format error as HTML with styling.\n   */\n  private formatHtml(bundle: ParseErrorBundle): string {\n    const primary = bundle.primary;\n    const lines = bundle.source.split(\"\\n\");\n    const errorLine = lines[primary.span.line - 1] || \"\";\n\n    const parts: string[] = [];\n\n    parts.push('<div class=\"parse-error\">');\n\n    // Error header\n    parts.push(\n      `  <div class=\"error-header\">Error at line ${primary.span.line}, column ${primary.span.column}:</div>`\n    );\n\n    // Code context\n    parts.push('  <div class=\"error-context\">');\n    if (this.options.showContext && this.options.maxContextLines! > 0) {\n      const contextLines = this.getContextLines(\n        lines,\n        primary.span.line - 1,\n        this.options.maxContextLines!\n      );\n      for (const line of contextLines) {\n        parts.push(\n          `    <div class=\"context-line\">${this.escapeHtml(line)}</div>`\n        );\n      }\n    } else {\n      parts.push(\n        `    <div class=\"error-line\">${this.escapeHtml(errorLine)}</div>`\n      );\n    }\n\n    // Pointer (accounting for line prefix in plain text representation)\n    const pointer = this.createPointer(\n      primary.span.column,\n      primary.span.length,\n      false\n    );\n    parts.push(`    <div class=\"error-pointer\">${pointer}</div>`);\n    parts.push(\"  </div>\");\n\n    // Error message\n    parts.push(\n      `  <div class=\"error-message\">${this.escapeHtml(this.formatErrorMessage(primary, false))}</div>`\n    );\n\n    // Hints\n    const hints = this.getHints(primary);\n    if (this.options.showHints && hints.length > 0) {\n      parts.push('  <div class=\"error-hints\">');\n      for (const hint of hints) {\n        parts.push(\n          `    <div class=\"hint\">Did you mean: <span class=\"suggestion\">${this.escapeHtml(hint)}</span>?</div>`\n        );\n      }\n      parts.push(\"  </div>\");\n    }\n\n    // Context\n    if (\n      this.options.showContext &&\n      primary.context &&\n      primary.context.length > 0\n    ) {\n      parts.push(\n        `  <div class=\"error-context-stack\">Context: ${primary.context.map(c => `<span class=\"context-item\">${this.escapeHtml(c)}</span>`).join(\" &gt; \")}</div>`\n      );\n    }\n\n    parts.push(\"</div>\");\n\n    return parts.join(\"\\n\");\n  }\n\n  /**\n   * Format error as JSON for programmatic consumption.\n   */\n  private formatJson(bundle: ParseErrorBundle): string {\n    const primary = bundle.primary;\n    const lines = bundle.source.split(\"\\n\");\n\n    const contextLines =\n      this.options.showContext ?\n        this.getContextLines(\n          lines,\n          primary.span.line - 1,\n          this.options.maxContextLines!\n        )\n      : [lines[primary.span.line - 1] || \"\"];\n\n    return JSON.stringify(\n      {\n        error: {\n          type: primary.tag,\n          message: this.getPlainErrorMessage(primary),\n          location: {\n            line: primary.span.line,\n            column: primary.span.column,\n            offset: primary.span.offset,\n            length: primary.span.length\n          },\n          context: { lines: contextLines, stack: primary.context || [] },\n          hints: this.getHints(primary),\n          source: bundle.source\n        },\n        allErrors: bundle.errors.map(err => ({\n          type: err.tag,\n          location: {\n            line: err.span.line,\n            column: err.span.column,\n            offset: err.span.offset,\n            length: err.span.length\n          },\n          context: err.context || [],\n          ...(err.tag === \"Expected\" && { items: err.items, found: err.found }),\n          ...(err.tag === \"Unexpected\" && { found: err.found }),\n          ...(err.tag === \"Fatal\" && { message: err.message })\n        }))\n      },\n      null,\n      this.options.tabSize\n    );\n  }\n\n  /**\n   * Format the error message based on error type.\n   */\n  private formatErrorMessage(\n    error: ParseError,\n    useColors: boolean = true\n  ): string {\n    const red = useColors ? \"\\x1b[31m\" : \"\";\n    const yellow = useColors ? \"\\x1b[33m\" : \"\";\n    const reset = useColors ? \"\\x1b[0m\" : \"\";\n\n    switch (error.tag) {\n      case \"Expected\":\n        const foundText = error.found ? `, found ${error.found}` : \"\";\n        return `  ${yellow}Expected:${reset} ${error.items.join(\" or \")}${foundText}`;\n      case \"Unexpected\":\n        return `  ${red}Unexpected:${reset} ${error.found}`;\n      case \"Custom\":\n        return `  ${error.message}`;\n      case \"Fatal\":\n        return `  ${red}Fatal:${reset} ${error.message}`;\n    }\n  }\n\n  /**\n   * Get plain error message without formatting.\n   */\n  private getPlainErrorMessage(error: ParseError): string {\n    switch (error.tag) {\n      case \"Expected\":\n        const foundText = error.found ? `, found ${error.found}` : \"\";\n        return `Expected: ${error.items.join(\" or \")}${foundText}`;\n      case \"Unexpected\":\n        return `Unexpected: ${error.found}`;\n      case \"Custom\":\n        return error.message;\n      case \"Fatal\":\n        return `Fatal: ${error.message}`;\n    }\n  }\n\n  /**\n   * Create a pointer/caret pointing to the error location.\n   */\n  private createPointer(\n    column: number,\n    length: number = 1,\n    useColors: boolean = true\n  ): string {\n    const spaces = \" \".repeat(Math.max(0, column - 1));\n    const carets = \"^\".repeat(Math.max(1, length));\n    const red = useColors ? \"\\x1b[31m\" : \"\";\n    const reset = useColors ? \"\\x1b[0m\" : \"\";\n    return `${spaces}${red}${carets}${reset}`;\n  }\n\n  /**\n   * Get context lines around the error location.\n   */\n  private getContextLines(\n    allLines: string[],\n    errorLineIndex: number,\n    maxLines: number\n  ): string[] {\n    const contextRadius = Math.floor(maxLines / 2);\n    const startLine = Math.max(0, errorLineIndex - contextRadius);\n    const endLine = Math.min(\n      allLines.length - 1,\n      errorLineIndex + contextRadius\n    );\n\n    const contextLines: string[] = [];\n    for (let i = startLine; i <= endLine; i++) {\n      const lineNum = i + 1;\n      const lineContent = allLines[i] || \"\";\n      const isErrorLine = i === errorLineIndex;\n      const prefix = isErrorLine ? \">\" : \" \";\n      const paddedLineNum = lineNum.toString().padStart(3, \" \");\n      contextLines.push(`${prefix} ${paddedLineNum} | ${lineContent}`);\n    }\n\n    return contextLines;\n  }\n\n  /**\n   * Escape HTML entities.\n   */\n  private escapeHtml(text: string): string {\n    return text\n      .replace(/&/g, \"&amp;\")\n      .replace(/</g, \"&lt;\")\n      .replace(/>/g, \"&gt;\")\n      .replace(/\"/g, \"&quot;\")\n      .replace(/'/g, \"&#39;\");\n  }\n\n  /**\n   * Create a new formatter with different options.\n   */\n  withOptions(options: Partial<ErrorFormatterOptions>): ErrorFormatter {\n    return new ErrorFormatter(this._format, { ...this.options, ...options });\n  }\n\n  /**\n   * Create a new formatter with a different format.\n   */\n  withFormat(format: ErrorFormat): ErrorFormatter {\n    return new ErrorFormatter(format, this.options);\n  }\n\n  /**\n   * Get hints from an error, handling the union type safely.\n   */\n  private getHints(error: ParseError): string[] {\n    // if (error.tag === \"Custom\" && error.hints) {\n    //   return error.hints;\n    // }\n    if (error.tag === \"Unexpected\" && error.hints) {\n      return error.hints;\n    }\n    return [];\n  }\n}\n\n/**\n * Convenience functions for quick formatting.\n */\nexport const formatError = {\n  plain: (bundle: ParseErrorBundle, options?: ErrorFormatterOptions) =>\n    new ErrorFormatter(\"plain\", options).format(bundle),\n  ansi: (bundle: ParseErrorBundle, options?: ErrorFormatterOptions) =>\n    new ErrorFormatter(\"ansi\", options).format(bundle),\n  html: (bundle: ParseErrorBundle, options?: ErrorFormatterOptions) =>\n    new ErrorFormatter(\"html\", options).format(bundle),\n  json: (bundle: ParseErrorBundle, options?: ErrorFormatterOptions) =>\n    new ErrorFormatter(\"json\", options).format(bundle)\n};\n","export * from \"./combinators\";\n// export * from \"./debug\";\nexport * from \"./either\";\nexport * from \"./error-formatter\";\nexport * from \"./hints\";\nexport * from \"./parser\";\nexport * from \"./errors\";\nexport * from \"./state\";\nexport * from \"./types\";\nexport * from \"./utils\";\n","export type Either<R, L> = Left<L, R> | Right<R, L>;\n\nexport class Left<L, R = never> {\n  readonly _tag = \"Left\";\n  constructor(public readonly left: L) {}\n  *[Symbol.iterator](): Generator<Either<R, L>, R, any> {\n    return yield this;\n  }\n}\n\nexport class Right<R, L = any> {\n  readonly _tag = \"Right\";\n  constructor(public readonly right: R) {}\n  *[Symbol.iterator](): Generator<Either<R, L>, R, any> {\n    return yield this;\n  }\n}\n\nexport const Either = {\n  left<L, R = never>(l: L): Either<R, L> {\n    return new Left(l);\n  },\n\n  right<R, L = never>(r: R): Either<R, L> {\n    return new Right(r);\n  },\n\n  isLeft<R, L>(either: Either<R, L>): either is Left<L, R> {\n    return either._tag === \"Left\";\n  },\n\n  isRight<R, L>(either: Either<R, L>): either is Right<R, L> {\n    return either._tag === \"Right\";\n  },\n\n  match<R, L, T>(onLeft: (left: L) => T, onRight: (right: R) => T) {\n    return (either: Either<R, L>): T => {\n      if (Either.isLeft(either)) {\n        return onLeft(either.left);\n      }\n      return onRight(either.right);\n    };\n  },\n\n  gen<R, L>(f: () => Generator<Either<any, L>, R, any>): Either<R, L> {\n    const iterator = f();\n    let current = iterator.next();\n\n    while (!current.done) {\n      const either = current.value;\n      if (Either.isLeft(either)) {\n        return either;\n      }\n      current = iterator.next(either.right);\n    }\n\n    return Either.right(current.value);\n  }\n};\n","/**\n * Represents a location span in source code with position and size information.\n * @example\n * ```typescript\n * const span: Span = {\n *   offset: 10,\n *   length: 5,\n *   line: 2,\n *   column: 3\n * };\n * ```\n */\nexport type Span = {\n  /** Byte offset from the start of the source */\n  offset: number;\n  /** Length of the span in bytes */\n  length: number;\n  /** Line number (1-indexed) */\n  line: number;\n  /** Column number (1-indexed) */\n  column: number;\n};\n\n/**\n * Creates a Span from parser state and optional length.\n * @param state - Parser state containing position information\n * @param length - Length of the span (defaults to 0)\n * @returns A new Span object\n * @example\n * ```typescript\n * const state = { pos: { offset: 10, line: 2, column: 3 } };\n * const span = Span(state, 5);\n * // Returns: { offset: 10, length: 5, line: 2, column: 3 }\n * ```\n */\nexport function Span(\n  state: { pos: { offset: number; line: number; column: number } },\n  length: number = 0\n): Span {\n  return {\n    offset: state.pos.offset,\n    length,\n    line: state.pos.line,\n    column: state.pos.column\n  };\n}\n\ntype ExpectedParseError = {\n  tag: \"Expected\";\n  span: Span;\n  items: string[];\n  context: string[];\n  found?: string;\n};\n\ntype UnexpectedParseError = {\n  tag: \"Unexpected\";\n  span: Span;\n  found: string;\n  context: string[];\n  hints?: string[];\n};\n\ntype CustomParseError = {\n  tag: \"Custom\";\n  span: Span;\n  message: string;\n  hints?: string[];\n  context: string[];\n};\n\ntype FatalParseError = {\n  tag: \"Fatal\";\n  span: Span;\n  message: string;\n  context: string[];\n};\n\n/**\n * Union type representing all possible parsing errors.\n * Each error type has a discriminant tag for pattern matching.\n * @example\n * ```typescript\n * function handleError(error: ParseError) {\n *   switch (error.tag) {\n *     case \"Expected\":\n *       console.log(`Expected ${error.items.join(\" or \")}`);\n *       break;\n *     case \"Unexpected\":\n *       console.log(`Unexpected ${error.found}`);\n *       break;\n *     // ... handle other cases\n *   }\n * }\n * ```\n */\nexport type ParseError =\n  | CustomParseError\n  | ExpectedParseError\n  | UnexpectedParseError\n  | FatalParseError;\n\n/**\n * Factory functions for creating different types of ParseError objects.\n * Provides a convenient API for constructing errors without manually setting tags.\n * @example\n * ```typescript\n * const span = Span(state);\n *\n * // Create an expected error\n * const expectedError = ParseError.expected({\n *   span,\n *   items: [\"identifier\", \"keyword\"],\n *   context: [\"function declaration\"],\n *   found: \"number\"\n * });\n *\n * // Create a custom error\n * const customError = ParseError.custom({\n *   span,\n *   message: \"Invalid syntax\",\n *   context: [\"expression\"],\n *   hints: [\"Try using parentheses\"]\n * });\n * ```\n */\nexport const ParseError = {\n  /** Creates an ExpectedParseError for when specific tokens were expected */\n  expected: (params: Omit<ExpectedParseError, \"tag\">): ExpectedParseError => ({\n    tag: \"Expected\",\n    ...params\n  }),\n  /** Creates an UnexpectedParseError for when an unexpected token was found */\n  unexpected: (\n    params: Omit<UnexpectedParseError, \"tag\">\n  ): UnexpectedParseError => ({\n    tag: \"Unexpected\",\n    ...params\n  }),\n  /** Creates a CustomParseError with a custom message */\n  custom: (params: Omit<CustomParseError, \"tag\">): CustomParseError => ({\n    tag: \"Custom\",\n    ...params\n  }),\n  /** Creates a FatalParseError that cannot be recovered from */\n  fatal: (params: Omit<FatalParseError, \"tag\">): FatalParseError => ({\n    tag: \"Fatal\",\n    ...params\n  })\n};\n\n/**\n * A collection of parsing errors with formatting and analysis capabilities.\n * Automatically determines the primary (furthest) error for reporting.\n * @example\n * ```typescript\n * const errors = [\n *   ParseError.expected({ span: spanAt10, items: [\"(\"], context: [] }),\n *   ParseError.unexpected({ span: spanAt15, found: \")\", context: [] })\n * ];\n * const bundle = new ParseErrorBundle(errors, sourceCode);\n *\n * console.log(bundle.toString()); // Shows the furthest error\n * console.log(bundle.format(\"ansi\")); // Formatted with colors\n * ```\n */\nexport class ParseErrorBundle {\n  /**\n   * Creates a new ParseErrorBundle.\n   * @param errors - Array of parsing errors\n   * @param source - The original source code being parsed\n   * @returns {ParseErrorBundle} A new ParseErrorBundle instance containing the errors and source\n   */\n  constructor(\n    public errors: ParseError[],\n    public source: string\n  ) {}\n\n  /**\n   * Gets the primary error (the one that occurred furthest in the input).\n   * This is typically the most relevant error to show to the user.\n   * @returns {ParseError} The error with the highest offset position\n   */\n  get primary(): ParseError {\n    return this.errors.reduce((furthest, current) =>\n      current.span.offset > furthest.span.offset ? current : furthest\n    );\n  }\n\n  /**\n   * Gets all errors that occurred at the same position as the primary error.\n   * Useful when multiple parse attempts failed at the same location.\n   * @returns {ParseError[]} Array of errors at the furthest position\n   */\n  get primaryErrors(): ParseError[] {\n    const maxOffset = this.primary.span.offset;\n    return this.errors.filter(err => err.span.offset === maxOffset);\n  }\n\n  /**\n   * Converts the primary error to a simple string representation.\n   * @returns {string} A human-readable error message\n   */\n  toString(): string {\n    const err = this.primary;\n    switch (err.tag) {\n      case \"Expected\":\n        return `Expected ${err.items.join(\" or \")}${err.found ? `, found ${err.found}` : \"\"}`;\n      case \"Unexpected\":\n        return `Unexpected ${err.found}`;\n      case \"Custom\":\n        return err.message;\n      case \"Fatal\":\n        return `Fatal: ${err.message}`;\n    }\n  }\n\n  /**\n   * Formats the error bundle using the specified formatter.\n   * @param format - The output format (\"plain\", \"ansi\", \"html\", or \"json\")\n   * @returns {string} Formatted error message with context and highlighting\n   */\n  format(format: \"plain\" | \"ansi\" | \"html\" | \"json\" = \"plain\"): string {\n    const { ErrorFormatter } = require(\"./error-formatter\");\n    return new ErrorFormatter(format).format(this);\n  }\n}\n","import type { Either } from \"./either\";\nimport type { ParseErrorBundle, Span } from \"./errors\";\n\nexport type Spanned<T> = [value: T, span: Span];\n\n/**\n * Represents the output of a parser operation, containing both the updated state\n * and the parsing result (either success or error).\n * @template T - The type of the successfully parsed value\n * @example\n * ```typescript\n * const output: ParserOutput<string> = {\n *   state: newState,\n *   result: Either.right(\"parsed value\")\n * };\n * ```\n */\nexport type ParserOutput<T> = {\n  /** The parser state after the operation */\n  state: ParserState;\n  /** Either a successful result of type T or a ParseErrorBundle */\n  result: Either<T, ParseErrorBundle>;\n};\n\n/**\n * Factory function for creating ParserOutput objects.\n * @template T - The type of the successfully parsed value\n * @param state - The parser state after the operation\n * @param result - Either a successful result or error bundle\n * @returns A new ParserOutput object\n * @example\n * ```typescript\n * import { Either } from \"./either\";\n *\n * const successOutput = ParserOutput(newState, Either.right(\"success\"));\n * const errorOutput = ParserOutput(oldState, Either.left(errorBundle));\n * ```\n */\nexport const ParserOutput = <T>(\n  state: ParserState,\n  result: Either<T, ParseErrorBundle>\n): ParserOutput<T> => ({\n  state,\n  result\n});\n\n/**\n * Represents a position within source code with line, column, and byte offset.\n * All values are 1-indexed for human readability.\n * @example\n * ```typescript\n * const position: SourcePosition = {\n *   line: 3,      // Third line\n *   column: 15,   // 15th character on that line\n *   offset: 42    // 42nd character from start of input\n * };\n * ```\n */\nexport type SourcePosition = {\n  /** Line number (1-indexed) */\n  line: number;\n  /** Column number (1-indexed) */\n  column: number;\n  /** Byte offset from start of input (0-indexed) */\n  offset: number;\n};\n\nexport class SourcePosition_ {\n  constructor(\n    public line: number,\n    public column: number,\n    public offset: number\n  ) {}\n}\n\n/**\n * Represents the complete state of a parser at any point during parsing.\n * Contains the input being parsed, current position, and optional debugging/context information.\n * @example\n * ```typescript\n * const state: ParserState = {\n *   remaining: \"hello world\",\n *   pos: { line: 1, column: 1, offset: 0 },\n *   source: \"hello world\",\n *   debug: true,\n *   labelStack: [\"expression\", \"identifier\"],\n *   committed: false\n * };\n * ```\n */\nexport type ParserState = {\n  /** The portion of input that hasn't been consumed yet */\n  remaining: string;\n  /** Current position in the source code */\n  pos: SourcePosition;\n  /** The complete original input string */\n  source: string;\n  /** Whether debug mode is enabled for detailed error reporting */\n  debug?: boolean;\n  /** Stack of parsing context labels for error reporting */\n  labelStack?: string[];\n  /** Whether the parser has committed to this parse path */\n  committed?: boolean;\n};\n\n/**\n * Utility object containing static methods for creating and manipulating parser state.\n */\nexport const State = {\n  /**\n   * Creates a new parser state from an input string.\n   *\n   * @param input - The input string to parse\n   * @returns A new parser state initialized at the start of the input\n   */\n  fromInput(input: string): ParserState {\n    return {\n      remaining: input,\n      source: input,\n      pos: { line: 1, column: 1, offset: 0 }\n    };\n  },\n\n  /**\n   * Creates a new state by consuming n characters from the current state.\n   *\n   * @param state - The current parser state\n   * @param n - Number of characters to consume\n   * @returns A new state with n characters consumed and position updated\n   * @throws Error if attempting to consume more characters than remaining\n   */\n  consume(state: ParserState, n: number): ParserState {\n    if (n === 0) return state;\n    if (n > state.remaining.length) {\n      throw new Error(\"Cannot consume more characters than remaining\");\n    }\n\n    const consumed = state.remaining.slice(0, n);\n    let { line, column, offset } = state.pos;\n\n    for (const char of consumed) {\n      if (char === \"\\n\") {\n        line++;\n        column = 1;\n      } else {\n        column++;\n      }\n      offset++;\n    }\n\n    return {\n      ...state,\n      remaining: state.remaining.slice(n),\n      pos: { line, column, offset }\n    };\n  },\n\n  /**\n   * Creates a new state by consuming a specific string from the current state.\n   *\n   * @param state - The current parser state\n   * @param str - The string to consume\n   * @returns A new state with the string consumed and position updated\n   * @throws Error if the input doesn't start with the specified string\n   */\n  consumeString(state: ParserState, str: string): ParserState {\n    if (!state.remaining.startsWith(str)) {\n      throw new Error(\n        `Cannot consume \"${str}\" - input \"${state.remaining}\" doesn't start with it`\n      );\n    }\n    return State.consume(state, str.length);\n  },\n\n  /**\n   * Creates a new state by moving to a specific offset position in the source.\n   * Resets to the beginning and then consumes to the target position.\n   * @param state - The current parser state\n   * @param moveBy - Number of characters to move forward from current position\n   * @returns A new state at the target position\n   */\n  move(state: ParserState, moveBy: number) {\n    return State.consume(\n      {\n        ...state,\n        remaining: state.source,\n        pos: { line: 1, column: 1, offset: 0 }\n      },\n      state.pos.offset + moveBy\n    );\n  },\n\n  /**\n   * Creates a new state by consuming characters while a predicate is true.\n   *\n   * @param state - The current parser state\n   * @param predicate - Function that tests each character\n   * @returns A new state with matching characters consumed\n   */\n  consumeWhile(\n    state: ParserState,\n    predicate: (char: string) => boolean\n  ): ParserState {\n    let i = 0;\n    while (i < state.remaining.length && predicate(state.remaining[i])) {\n      i++;\n    }\n    return State.consume(state, i);\n  },\n\n  /**\n   * Gets the next n characters from the input without consuming them.\n   *\n   * @param state - The current parser state\n   * @param n - Number of characters to peek (default: 1)\n   * @returns The next n characters as a string\n   */\n  peek(state: ParserState, n: number = 1): string {\n    return state.remaining.slice(0, n);\n  },\n\n  /**\n   * Checks if the parser has reached the end of input.\n   *\n   * @param state - The current parser state\n   * @returns True if at end of input, false otherwise\n   */\n  isAtEnd(state: ParserState): boolean {\n    return state.remaining.length === 0;\n  },\n\n  /**\n   * Creates a human-readable string representation of the current parser position.\n   * @param state - The current parser state\n   * @returns A formatted string showing line, column, and offset\n   * @example\n   * ```typescript\n   * const posStr = State.printPosition(state);\n   * // Returns: \"line 5, column 12, offset 89\"\n   * ```\n   */\n  printPosition(state: ParserState): string {\n    return `line ${state.pos.line}, column ${state.pos.column}, offset ${state.pos.offset}`;\n  }\n};\n","// import { debug } from \"./debug\";\nimport { Either } from \"./either\";\nimport { ParseError, ParseErrorBundle, Span } from \"./errors\";\nimport { ParserOutput, type ParserState, type Spanned, State } from \"./state\";\n\n/**\n * Parser is the core type that represents a parser combinator.\n *\n * A parser is a function that takes an input state and produces either:\n * - A successful parse result with the remaining input state\n * - An error describing why the parse failed\n *\n * Parsers can be composed using various combinators to build complex parsers\n * from simple building blocks.\n *\n * @template T The type of value this parser produces when successful\n */\nexport class Parser<T> {\n  /**\n   * Creates a new Parser instance.\n   *\n   * @param run - The parsing function that takes a parser state and returns a parse result\n   */\n  constructor(\n    /**\n     * @internal\n     */\n    public run: (state: ParserState) => ParserOutput<T>\n  ) {}\n\n  // Monad/Applicative\n\n  /**\n   * Creates a successful parser output with the given value and state.\n   *\n   * This is a low-level helper used internally to construct successful parse results.\n   * It doesn't consume any input and returns the value with the current state unchanged.\n   *\n   * @param value - The value to wrap in a successful result\n   * @param state - The current parser state\n   * @returns {ParserOutput<T>} A successful parser output containing the value\n   * @template T The type of the successful value\n   * @internal\n   */\n  static succeed<T>(value: T, state: ParserState): ParserOutput<T> {\n    return ParserOutput(state, Either.right(value));\n  }\n\n  /**\n   * Creates a parser that always succeeds with the given value without consuming any input.\n   *\n   * This is the basic way to inject a value into the parser context. The parser will\n   * succeed immediately with the provided value and won't advance the parser state.\n   *\n   * @param a - The value to lift into the parser context\n   * @returns {Parser<A>} A parser that always succeeds with the given value\n   * @template A The type of the value being lifted\n   *\n   * @example\n   * ```ts\n   * const always42 = Parser.lift(42)\n   * always42.parse(\"any input\") // succeeds with 42\n   *\n   * // Useful for providing default values\n   * const parseNumberOrDefault = number.or(Parser.lift(0))\n   *\n   * // Can be used to inject values in parser chains\n   * const parser = parser(function* () {\n   *   const name = yield* identifier\n   *   const separator = yield* Parser.lift(\":\")\n   *   const value = yield* number\n   *   return { name, separator, value }\n   * })\n   * ```\n   */\n  static lift = <A>(a: A): Parser<A> =>\n    new Parser(state => Parser.succeed(a, state));\n\n  /**\n   * Lifts a binary function into the parser context, applying it to the results of two parsers.\n   *\n   * This is the applicative functor's version of `map` for functions of two arguments.\n   * It runs both parsers in sequence and applies the function to their results if both succeed.\n   *\n   * @param ma - The first parser\n   * @param mb - The second parser\n   * @param f - A function that takes the results of both parsers and produces a new value\n   * @returns {Parser<C>} A parser that applies the function to the results of both input parsers\n   * @template A The type of value produced by the first parser\n   * @template B The type of value produced by the second parser\n   * @template C The type of value produced by applying the function\n   *\n   * @example\n   * ```ts\n   * // Combine two parsed values with a function\n   * const parsePoint = Parser.liftA2(\n   *   number,\n   *   number.trimLeft(comma),\n   *   (x, y) => ({ x, y })\n   * )\n   * parsePoint.parse(\"10, 20\") // succeeds with { x: 10, y: 20 }\n   *\n   * // Build a data structure from multiple parsers\n   * const parsePerson = Parser.liftA2(\n   *   identifier,\n   *   number.trimLeft(colon),\n   *   (name, age) => ({ name, age })\n   * )\n   * parsePerson.parse(\"John:30\") // succeeds with { name: \"John\", age: 30 }\n   * ```\n   */\n  static liftA2 = <A, B, C>(\n    ma: Parser<A>,\n    mb: Parser<B>,\n    f: (a: A, b: B) => C\n  ): Parser<C> => ma.zip(mb).map(args => f(...args));\n\n  /**\n   * Applies a parser that produces a function to a parser that produces a value.\n   *\n   * This is the applicative functor's application operator. It allows you to apply\n   * functions within the parser context, enabling powerful composition patterns.\n   *\n   * @param ma - A parser that produces a value\n   * @param mf - A parser that produces a function from that value type to another type\n   * @returns {Parser<B>} A parser that applies the parsed function to the parsed value\n   * @template A The type of the input value\n   * @template B The type of the output value after function application\n   *\n   * @example\n   * ```ts\n   * // Parse a function name and apply it\n   * const parseFn = choice([\n   *   string(\"double\").map(() => (x: number) => x * 2),\n   *   string(\"square\").map(() => (x: number) => x * x)\n   * ])\n   * const result = Parser.ap(number, parseFn.trimLeft(space))\n   * result.parse(\"5 double\") // succeeds with 10\n   * result.parse(\"5 square\") // succeeds with 25\n   *\n   * // Chain multiple applications\n   * const add = (x: number) => (y: number) => x + y\n   * const parseAdd = Parser.lift(add)\n   * const addParser = Parser.ap(\n   *   number,\n   *   Parser.ap(number.trimLeft(plus), parseAdd)\n   * )\n   * addParser.parse(\"3 + 4\") // succeeds with 7\n   * ```\n   */\n  static ap = <A, B>(ma: Parser<A>, mf: Parser<(_: A) => B>): Parser<B> =>\n    mf.zip(ma).map(([f, a]) => f(a));\n\n  // Error handling\n\n  /**\n   * Creates a failed parser output with the given error information.\n   *\n   * This is a low-level helper for constructing parse errors. It creates a custom\n   * error with the provided message and optional expected/found information.\n   *\n   * @param error - Error details including message and optional expected/found values\n   * @param state - The parser state where the error occurred\n   * @returns {ParserOutput<never>} A failed parser output containing the error\n   * @internal\n   */\n  static fail(\n    error: { message: string; expected?: string[]; found?: string },\n    state: ParserState\n  ): ParserOutput<never> {\n    const span = Span({\n      pos: {\n        offset: state.pos.offset,\n        line: state.pos.line,\n        column: state.pos.column\n      }\n    });\n\n    const parseErr = ParseError.custom({\n      span,\n      message: error.message,\n      context: state?.labelStack ?? [],\n      hints: []\n    });\n\n    const bundle = new ParseErrorBundle(\n      [parseErr],\n      // state?.source ?? state.remaining\n      state.source\n    );\n\n    return ParserOutput(state, Either.left(bundle));\n  }\n\n  /**\n   * Creates a parser that always fails with a fatal error.\n   *\n   * Fatal errors are non-recoverable and prevent backtracking in choice combinators.\n   * Use this when you've determined that the input is definitely malformed and trying\n   * other alternatives would be meaningless.\n   *\n   * @param message - The error message to display\n   * @returns {Parser<never>} A parser that always fails with a fatal error\n   *\n   * @example\n   * ```ts\n   * const number = regex(/-?[0-9]+/).map(Number);\n   * const parsePositive = number.flatMap(n =>\n   *   n > 0 ? Parser.lift(n) : Parser.fatal(\"Expected positive number\")\n   * )\n   * ```\n   */\n  static fatal = (message: string): Parser<never> =>\n    new Parser(state =>\n      ParserOutput(\n        state,\n        Either.left(\n          new ParseErrorBundle(\n            [\n              ParseError.fatal({\n                span: Span(state),\n                message,\n                context: state?.labelStack ?? []\n              })\n            ],\n            // state?.source ?? state.remaining\n            state.source\n          )\n        )\n      )\n    );\n\n  /**\n   * Runs the parser on the given input string and returns the full parser output.\n   *\n   * This method provides access to both the parse result and the final parser state,\n   * which includes information about the remaining unparsed input and position.\n   *\n   * @param input - The string to parse\n   * @returns {ParserOutput<T>} A parser output containing both the result (success or error) and final state\n   *\n   * @example\n   * ```ts\n   * const parser = string(\"hello\");\n   * const output = parser.parse(\"hello world\");\n   * // output.result contains Either.right(\"hello\")\n   * // output.state contains remaining input \" world\" and position info\n   * ```\n   */\n  parse(input: string): ParserOutput<T> {\n    const { result, state } = this.run(State.fromInput(input) as any);\n    return ParserOutput(state, result);\n  }\n\n  /**\n   * Runs the parser on the given input and returns either the parsed value or error bundle.\n   *\n   * This is a convenience method that unwraps the Either result, making it easier\n   * to handle the common case where you just need the value or error without the\n   * full parser state information.\n   *\n   * @param input - The string to parse\n   * @returns {T | ParseErrorBundle} The successfully parsed value of type T, or a ParseErrorBundle on failure\n   *\n   * @example\n   * ```ts\n   * const parser = number();\n   * const result = parser.parseOrError(\"42\");\n   * if (result instanceof ParseErrorBundle) {\n   *   console.error(result.format());\n   * } else {\n   *   console.log(result); // 42\n   * }\n   * ```\n   */\n  parseOrError(input: string): T | ParseErrorBundle {\n    const { result } = this.run(State.fromInput(input));\n    if (Either.isRight(result)) {\n      return result.right;\n    }\n    return result.left;\n  }\n\n  /**\n   * Runs the parser on the given input and returns the parsed value or throws an error.\n   *\n   * This method is useful when you're confident the parse will succeed or want to\n   * handle parse errors as exceptions. The thrown error is a ParseErrorBundle which\n   * contains detailed information about what went wrong.\n   *\n   * @param input - The string to parse\n   * @returns {T} The successfully parsed value of type T\n   * @throws {ParseErrorBundle} Thrown when parsing fails\n   *\n   * @example\n   * ```ts\n   * const parser = number();\n   * try {\n   *   const value = parser.parseOrThrow(\"42\");\n   *   console.log(value); // 42\n   * } catch (error) {\n   *   if (error instanceof ParseErrorBundle) {\n   *     console.error(error.format());\n   *   }\n   * }\n   * ```\n   */\n  parseOrThrow(input: string): T {\n    const { result } = this.parse(input);\n\n    if (Either.isLeft(result)) {\n      throw result.left;\n    }\n    return result.right;\n  }\n\n  /**\n   * Transforms the result of this parser by applying a function to the parsed value.\n   *\n   * This is the functor map operation. If the parser succeeds, the function is applied\n   * to the result. If the parser fails, the error is propagated unchanged. The input\n   * is not consumed if the transformation fails.\n   *\n   * @param f - A function that transforms the parsed value\n   * @returns {Parser<B>} A new parser that produces the transformed value\n   * @template B The type of the transformed value\n   *\n   * @example\n   * ```ts\n   * // Parse a number and double it\n   * const doubled = number().map(n => n * 2);\n   * doubled.parse(\"21\") // succeeds with 42\n   *\n   * // Parse a string and get its length\n   * const stringLength = quoted('\"').map(s => s.length);\n   * stringLength.parse('\"hello\"') // succeeds with 5\n   *\n   * // Chain multiple transformations\n   * const parser = identifier()\n   *   .map(s => s.toUpperCase())\n   *   .map(s => ({ name: s }));\n   * parser.parse(\"hello\") // succeeds with { name: \"HELLO\" }\n   * ```\n   */\n  map<B>(f: (a: T) => B): Parser<B> {\n    return new Parser<B>(state => {\n      const { result, state: newState } = this.run(state);\n      if (Either.isLeft(result)) {\n        return ParserOutput(\n          state,\n          result as unknown as Either<B, ParseErrorBundle>\n        );\n      }\n      // return Parser.succeed(f(result.right), newState);\n      return ParserOutput(newState, Either.right(f(result.right)));\n    });\n  }\n\n  /**\n   * Chains this parser with another parser that depends on the result of this one.\n   *\n   * This is the monadic bind operation (also known as chain or andThen). It allows\n   * you to create a parser whose behavior depends on the result of a previous parse.\n   * This is essential for context-sensitive parsing where later parsing decisions\n   * depend on earlier results.\n   *\n   * @param f - A function that takes the parsed value and returns a new parser\n   * @returns {Parser<B>} A new parser that runs the second parser after the first succeeds\n   * @template B The type of value produced by the resulting parser\n   *\n   * @example\n   * ```ts\n   * // Parse a number and then that many 'a' characters\n   * const parser = number().flatMap(n =>\n   *   string('a'.repeat(n))\n   * );\n   * parser.parse(\"3aaa\") // succeeds with \"aaa\"\n   *\n   * // Parse a type annotation and return appropriate parser\n   * const typeParser = identifier().flatMap(type => {\n   *   switch(type) {\n   *     case \"int\": return number();\n   *     case \"string\": return quoted('\"');\n   *     default: return Parser.fail({ message: `Unknown type: ${type}` });\n   *   }\n   * });\n   *\n   * // Validate parsed values\n   * const positiveNumber = number().flatMap(n =>\n   *   n > 0\n   *     ? Parser.lift(n)\n   *     : Parser.fail({ message: \"Expected positive number\" })\n   * );\n   * ```\n   */\n  flatMap<B>(f: (a: T) => Parser<B>): Parser<B> {\n    return new Parser<B>(state => {\n      const { result, state: newState } = this.run(state);\n      if (Either.isLeft(result)) {\n        return {\n          state: newState,\n          result: result as unknown as Either<B, ParseErrorBundle>\n        };\n      }\n      const nextParser = f(result.right);\n      return nextParser.run(newState);\n    });\n  }\n\n  /**\n   * Creates a parser that always succeeds with the given value without consuming input.\n   *\n   * This is an alias for `Parser.lift` that follows the monadic naming convention.\n   * It's the \"return\" or \"pure\" operation for the Parser monad, injecting a plain\n   * value into the parser context.\n   *\n   * @param a - The value to wrap in a successful parser\n   * @returns {Parser<A>} A parser that always succeeds with the given value\n   * @template A The type of the value being lifted\n   *\n   * @example\n   * ```ts\n   * // Always succeed with a constant value\n   * const always42 = Parser.pure(42);\n   * always42.parse(\"any input\") // succeeds with 42\n   *\n   * // Use in flatMap to wrap values\n   * const parser = number().flatMap(n =>\n   *   n > 0 ? Parser.pure(n) : Parser.fail({ message: \"Must be positive\" })\n   * );\n   * ```\n   */\n  static pure = <A>(a: A): Parser<A> =>\n    new Parser(state => Parser.succeed(a, state));\n\n  /**\n   * Creates a new parser that lazily evaluates the given function.\n   * This is useful for creating recursive parsers.\n   *\n   * @param fn - A function that returns a parser\n   * @returns {Parser<T>} A new parser that evaluates the function when parsing\n   * @template T The type of value produced by the parser\n   *\n   * @example\n   * ```ts\n   * // Create a recursive parser for nested parentheses\n   * const parens: Parser<string> = Parser.lazy(() =>\n   *   between(\n   *     char('('),\n   *     char(')'),\n   *     parens\n   *   )\n   * )\n   * ```\n   */\n  static lazy<T>(fn: () => Parser<T>): Parser<T> {\n    return new Parser(state => {\n      const parser = fn();\n      return parser.run(state);\n    });\n  }\n\n  /**\n   * Combines this parser with another parser, returning both results as a tuple.\n   *\n   * This is a fundamental sequencing operation that runs two parsers in order.\n   * If either parser fails, the entire operation fails. The results are returned\n   * as a tuple containing both parsed values.\n   *\n   * @param parserB - The second parser to run after this one\n   * @returns {Parser<[T, B]>} A parser that produces a tuple of both results\n   * @template B The type of value produced by the second parser\n   *\n   * @example\n   * ```ts\n   * // Parse a coordinate pair\n   * const coordinate = number().zip(number().trimLeft(comma));\n   * coordinate.parse(\"10, 20\") // succeeds with [10, 20]\n   *\n   * // Parse a key-value pair\n   * const keyValue = identifier().zip(number().trimLeft(colon));\n   * keyValue.parse(\"age:30\") // succeeds with [\"age\", 30]\n   *\n   * // Combine multiple parsers\n   * const triple = number()\n   *   .zip(number().trimLeft(comma))\n   *   .zip(number().trimLeft(comma))\n   *   .map(([[a, b], c]) => [a, b, c]);\n   * triple.parse(\"1, 2, 3\") // succeeds with [1, 2, 3]\n   * ```\n   */\n  zip<B>(parserB: Parser<B>): Parser<[T, B]> {\n    return new Parser(state => {\n      const { result: a, state: stateA } = this.run(state);\n      if (Either.isLeft(a)) {\n        return {\n          result: a as unknown as Either<[T, B], ParseErrorBundle>,\n          state: stateA\n        };\n      }\n      const { result: b, state: stateB } = parserB.run(stateA);\n      if (Either.isLeft(b)) {\n        return {\n          result: b as unknown as Either<[T, B], ParseErrorBundle>,\n          state: stateB\n        };\n      }\n      return Parser.succeed([a.right, b.right], stateB);\n    });\n  }\n\n  /**\n   * Sequences this parser with another, keeping only the second result.\n   *\n   * This is useful when you need to parse something but only care about what\n   * comes after it. The first parser must succeed for the second to run, but\n   * its result is discarded.\n   *\n   * @param parserB - The parser whose result will be kept\n   * @returns {Parser<B>} A parser that produces only the second result\n   * @template B The type of value produced by the second parser\n   *\n   * @example\n   * ```ts\n   * // Parse a value after a label\n   * const labeledValue = string(\"value:\").then(number());\n   * labeledValue.parse(\"value:42\") // succeeds with 42\n   *\n   * // Skip whitespace before parsing\n   * const trimmedNumber = whitespace().then(number());\n   * trimmedNumber.parse(\"   123\") // succeeds with 123\n   *\n   * // Parse the body after a keyword\n   * const functionBody = keyword(\"function\").then(identifier()).then(block());\n   * ```\n   */\n  then<B>(parserB: Parser<B>): Parser<B> {\n    return this.zip(parserB).map(([_, b]) => b);\n  }\n\n  /**\n   * Alias for `then` - sequences parsers and keeps the right result.\n   *\n   * This alias follows the naming convention from applicative functors where\n   * \"zipRight\" means to combine two values but keep only the right one.\n   *\n   * @see {@link then} for details and examples\n   */\n  zipRight = this.then;\n\n  /**\n   * Sequences this parser with another, keeping only the first result.\n   *\n   * This is useful when you need to parse something that must be present but\n   * whose value you don't need. Common uses include parsing required delimiters\n   * or terminators.\n   *\n   * @param parserB - The parser to run but whose result will be discarded\n   * @returns {Parser<T>} A parser that produces only the first result\n   * @template B The type of value produced by the second parser (discarded)\n   *\n   * @example\n   * ```ts\n   * // Parse a statement and discard the semicolon\n   * const statement = expression().thenDiscard(char(';'));\n   * statement.parse(\"x + 1;\") // succeeds with the expression, semicolon discarded\n   *\n   * // Parse a quoted string and discard the closing quote\n   * const quotedContent = char('\"').then(stringUntil('\"')).thenDiscard(char('\"'));\n   *\n   * // Parse array elements and discard separators\n   * const element = number().thenDiscard(optional(char(',')));\n   * ```\n   */\n  thenDiscard<B>(parserB: Parser<B>): Parser<T> {\n    return this.zip(parserB).map(([a, _]) => a);\n  }\n\n  /**\n   * Alias for `thenDiscard` - sequences parsers and keeps the left result.\n   *\n   * This alias follows the naming convention from applicative functors where\n   * \"zipLeft\" means to combine two values but keep only the left one.\n   *\n   * @see {@link thenDiscard} for details and examples\n   */\n  zipLeft = this.thenDiscard;\n\n  /**\n   * Makes this parser usable in generator syntax for cleaner sequential parsing.\n   *\n   * This iterator implementation allows parsers to be used with `yield*` in\n   * generator functions, enabling a more imperative style of parser composition\n   * that can be easier to read for complex sequential parsing.\n   *\n   * @returns {Generator<Parser<T>, T, any>} A generator that yields this parser and returns its result\n   * @internal\n   */\n  *[Symbol.iterator](): Generator<Parser<T>, T, any> {\n    return yield this;\n  }\n\n  /**\n   * Adds a tap point to observe the current state and result during parsing.\n   * Useful for debugging parser behavior.\n   *\n   * @example\n   * ```ts\n   * const parser = parser(function* () {\n   *   const name = yield* identifier();\n   *   yield* char(':');\n   *   const value = yield* number();\n   *   return { name, value };\n   * });\n   * parser.tap(({ state, result }) => {\n   *   console.log(`Parsed ${result} at position ${state.pos}`);\n   * });\n   * ```\n   *\n   * @param callback - Function called with current state and result\n   * @returns {Parser<T>} The same parser with the tap point added\n   */\n  tap(\n    callback: (args: { state: ParserState; result: ParserOutput<T> }) => void\n  ): Parser<T> {\n    return new Parser(state => {\n      const result = this.run(state);\n      callback({ state, result });\n      return result;\n    });\n  }\n\n  static gen = <T>(f: () => Generator<Parser<any>, T, any>): Parser<T> =>\n    new Parser<T>(state => {\n      const iterator = f();\n      let current = iterator.next();\n      let currentState: ParserState = state;\n      while (!current.done) {\n        const { result, state: updatedState } = current.value.run(currentState);\n        if (Either.isLeft(result)) {\n          // const hasFatalError = result.left.errors.some(e => e.tag === \"Fatal\");\n          // const isCommitted = updatedState?.committed || state?.committed;\n          // TODO: actually use hasFatalError and isCommitted to determine if we should continue or not\n          return {\n            result: result as unknown as Either<T, ParseErrorBundle>,\n            state: updatedState\n          };\n        }\n        currentState = updatedState;\n        current = iterator.next(result.right);\n      }\n      return Parser.succeed(current.value, currentState);\n    });\n\n  trim(parser: Parser<any>) {\n    return parser.then(this).thenDiscard(parser);\n  }\n\n  trimLeft(parser: Parser<any>): Parser<T> {\n    return parser.then(this);\n  }\n\n  trimRight(parser: Parser<any>): Parser<T> {\n    return this.thenDiscard(parser);\n  }\n\n  /**\n   * Adds a label to this parser for better error messages\n   * @param name - The label name to add to the context stack\n   * @returns {Parser<T>} A new parser with the label added\n   */\n  label(name: string): Parser<T> {\n    return new Parser(state => {\n      const newState = {\n        ...state,\n        context: {\n          ...state,\n          labelStack: [name, ...(state.labelStack || [])]\n        }\n      };\n\n      const result = this.run(newState);\n\n      if (Either.isLeft(result.result)) {\n        return ParserOutput(\n          state,\n          Either.left(\n            new ParseErrorBundle(\n              [\n                // Convert generic errors to labeled expectations\n                {\n                  tag: \"Expected\",\n                  span: Span(state),\n                  items: [name],\n                  context: newState.labelStack || []\n                }\n              ],\n              state.source\n            )\n          )\n        );\n      }\n\n      return result;\n    });\n  }\n\n  /**\n   * Helper for creating semantic expectations with both label and error message\n   * @param description - The description for both the label and error message\n   * @returns {Parser<T>} A new parser with both labeling and error message\n   */\n  expect(description: string): Parser<T> {\n    return new Parser<T>(state => {\n      const output = this.run(state);\n      if (Either.isLeft(output.result)) {\n        return Parser.fail(\n          {\n            message: `Expected ${description}`\n          },\n          output.state\n        );\n      }\n      return output;\n    });\n  }\n\n  /**\n   * Helper for creating semantic expectations with both label and error message\n   * @param errorBundle - The error bundle containing the errors to be displayed\n   * @param state - The current parser state\n   * @returns {ParserOutput<never>} A parser output with the error bundle and the current state\n   * @internal\n   */\n  static failRich(\n    errorBundle: { errors: ParseError[] },\n    state: ParserState\n  ): ParserOutput<never> {\n    const bundle = new ParseErrorBundle(\n      errorBundle.errors,\n      // state?.source ?? state.remaining\n      state.source\n    );\n\n    return ParserOutput(state, Either.left(bundle));\n  }\n\n  /**\n   * Commits to the current parsing path, preventing backtracking beyond this point.\n   *\n   * Once a parser is committed, if it fails later in the sequence, the error won't\n   * backtrack to try other alternatives in a `choice` or `or` combinator. This leads\n   * to more specific error messages instead of generic \"expected one of\" errors.\n   *\n   * @returns {Parser<T>} A new parser that sets the commit flag after successful parsing\n   *\n   * @example\n   * ```ts\n   * // Use commit after matching a keyword to ensure specific error messages\n   * const ifStatement = parser(function* () {\n   *   yield* keyword(\"if\")\n   *   yield* commit()  // After seeing \"if\", we know it's an if statement\n   *   yield* char('(').expect(\"opening parenthesis after 'if'\")\n   *   const condition = yield* expression\n   *   yield* char(')').expect(\"closing parenthesis\")\n   *   const body = yield* block\n   *   return { type: \"if\", condition, body }\n   * })\n   *\n   * // In a choice, commit prevents backtracking\n   * const statement = choice([\n   *   ifStatement,\n   *   whileStatement,\n   *   assignment\n   * ])\n   *\n   * // Input: \"if x > 5 {}\"  (missing parentheses)\n   * // Without commit: \"Expected if, while, or assignment\"\n   * // With commit: \"Expected opening parenthesis after 'if'\"\n   * ```\n   *\n   * @example\n   * ```ts\n   * // Commit can be chained with other methods\n   * const jsonObject = char('{')\n   *   .commit()  // Once we see '{', it must be an object\n   *   .then(whitespace)\n   *   .then(objectContent)\n   *   .expect(\"valid JSON object\")\n   * ```\n   *\n   * @see {@link commit} - Standalone function version\n   * @see {@link cut} - Alias with Prolog-style naming\n   */\n  commit = (): Parser<T> =>\n    new Parser(state => {\n      const result = this.run(state);\n      if (Either.isRight(result.result)) {\n        return ParserOutput(\n          { ...result.state, committed: true },\n          result.result\n        );\n      }\n      return result;\n    });\n\n  /**\n   * Creates an atomic parser that either fully succeeds or resets to the original state.\n   *\n   * This is useful for \"all-or-nothing\" parsing where you want to try a complex\n   * parser but not consume any input if it fails. The parser acts as a transaction -\n   * if any part fails, the entire parse is rolled back.\n   *\n   * @returns {Parser<T>} A new parser that resets state on failure\n   *\n   * @example\n   * ```ts\n   * // Without atomic - partial consumption on failure\n   * const badParser = parser(function* () {\n   *   yield* string(\"foo\")\n   *   yield* string(\"bar\")  // If this fails, \"foo\" is already consumed\n   * })\n   *\n   * // With atomic - no consumption on failure\n   * const goodParser = parser(function* () {\n   *   yield* string(\"foo\")\n   *   yield* string(\"bar\")  // If this fails, we reset to before \"foo\"\n   * }).atomic()\n   * ```\n   *\n   * @example\n   * ```ts\n   * // Useful for trying complex alternatives\n   * const value = or(\n   *   // Try to parse as a complex expression\n   *   expression.atomic(),\n   *   // If that fails completely, try as a simple literal\n   *   literal\n   * )\n   * ```\n   *\n   * @example\n   * ```ts\n   * // Lookahead parsing without consumption\n   * const startsWithKeyword = or(\n   *   string(\"function\").atomic(),\n   *   string(\"const\").atomic(),\n   *   string(\"let\").atomic()\n   * ).map(() => true).or(Parser.succeed(false))\n   * ```\n   *\n   * @see {@link atomic} - Standalone function version\n   */\n  atomic(): Parser<T> {\n    return new Parser(state => {\n      const result = this.run(state);\n      if (Either.isLeft(result.result)) {\n        // On failure, return the error but with the original state\n        return ParserOutput(state, result.result);\n      }\n      return result;\n    });\n  }\n\n  spanned(): Parser<Spanned<T>> {\n    return new Parser(state => {\n      const startState = state;\n      const result = this.run(state);\n\n      if (result.result._tag === \"Right\") {\n        const span = Span(\n          startState,\n          result.state.pos.offset - startState.pos.offset\n        );\n        return ParserOutput(\n          result.state,\n          Either.right([result.result.right, span])\n        );\n      }\n\n      return result as ParserOutput<Spanned<T>>;\n    });\n  }\n}\n\nexport const parser = Parser.gen;\n\n// /**\n//  * Creates a parser that fails with an Expected error.\n//  * Used when specific tokens or patterns were expected.\n//  *\n//  * @param items - Array of expected items (tokens, patterns, etc.)\n//  * @param found - What was actually found (optional)\n//  * @returns A parser that always fails with an Expected error\n//  *\n//  * @example\n//  * ```ts\n//  * Parser.expected([\")\", \"]\"], \"{\")  // Expected ) or ], found {\n//  * Parser.expected([\"identifier\"])   // Expected identifier\n//  * ```\n//  */\n// static expected(items: string[], found?: string): Parser<never> {\n//   return new Parser(state => {\n//     const error: ParseErr = {\n//       tag: \"Expected\",\n//       span: createSpan(state),\n//       items,\n//       found,\n//       context: state?.labelStack ?? []\n//     };\n//     return Parser.failRich({ errors: [error] }, state);\n//   });\n// }\n\n// /**\n//  * Creates a parser that fails with an Unexpected error.\n//  * Used when unexpected input was encountered.\n//  *\n//  * @param found - What was found that wasn't expected\n//  * @param hints - Optional hints for the user\n//  * @returns A parser that always fails with an Unexpected error\n//  *\n//  * @example\n//  * ```ts\n//  * Parser.unexpected(\"}\", [\"Expected closing paren\"])\n//  * Parser.unexpected(\"123\", [\"Identifiers cannot start with numbers\"])\n//  * ```\n//  */\n// static unexpected(found: string, hints?: string[]): Parser<never> {\n//   return new Parser(state => {\n//     const error: ParseErr = {\n//       tag: \"Unexpected\",\n//       span: createSpan(state),\n//       found,\n//       hints,\n//       context: state?.labelStack ?? []\n//     };\n//     return Parser.failRich({ errors: [error] }, state);\n//   });\n// }\n\n// static selectRight<A>(p: Parser<A>): Parser<Either<A, never>> {\n//   return p.flatMap(a => Parser.lift(Either.right(a)));\n// }\n\n// static selectLeft<A>(p: Parser<A>): Parser<Either<never, A>> {\n//   return p.flatMap(a => Parser.lift(Either.left(a)));\n// }\n\n// /**\n//  * Creates a parser that fails with a specific error type and options.\n//  * This is the most powerful error creation method for complex cases.\n//  *\n//  * @param options - Configuration object for the error\n//  * @returns A parser that always fails with the specified error\n//  *\n//  * @example\n//  * ```ts\n//  * Parser.failWith({\n//  *   type: \"expected\",\n//  *   items: [\"identifier\", \"number\"],\n//  *   found: \"string literal\",\n//  *   hints: [\"Variables must start with letters\"]\n//  * })\n//  *\n//  * Parser.failWith({\n//  *   type: \"fatal\",\n//  *   message: \"Cannot recover from this syntax error\"\n//  * })\n//  * ```\n//  */\n// static failWith(options: {\n//   type: \"expected\" | \"unexpected\" | \"custom\" | \"fatal\";\n//   message?: string;\n//   items?: string[];\n//   found?: string;\n//   hints?: string[];\n// }): Parser<never> {\n//   return new Parser(state => {\n//     const span = createSpan(state);\n//     const context = state?.labelStack ?? [];\n\n//     let error: ParseError;\n//     switch (options.type) {\n//       case \"expected\":\n//         error = {\n//           tag: \"Expected\",\n//           span,\n//           items: options.items ?? [],\n//           found: options.found,\n//           context\n//         };\n//         break;\n//       case \"unexpected\":\n//         error = {\n//           tag: \"Unexpected\",\n//           span,\n//           found: options.found ?? \"\",\n//           hints: options.hints,\n//           context\n//         };\n//         break;\n//       case \"custom\":\n//         error = {\n//           tag: \"Custom\",\n//           span,\n//           message: options.message ?? \"\",\n//           hints: options.hints,\n//           context\n//         };\n//         break;\n//       case \"fatal\":\n//         error = {\n//           tag: \"Fatal\",\n//           span,\n//           message: options.message ?? \"\",\n//           context\n//         };\n//         break;\n//     }\n\n//     return Parser.failRich({ errors: [error] }, state);\n//   });\n// }\n\n// static error(\n//   message: string,\n//   hints?: string[],\n//   stateCallback?: (state: ParserState) => ParserState\n// ): Parser<never> {\n//   return new Parser(state => {\n//     return Parser.failRich(\n//       {\n//         errors: [\n//           ParseError.custom({\n//             span: createSpan(state),\n//             message,\n//             hints,\n//             context: state?.labelStack ?? []\n//           })\n//         ]\n//       },\n//       stateCallback ? stateCallback(state) : state\n//     );\n//   });\n// }\n\n// withTrace(label: string): Parser<T> {\n//   return new Parser<T>(state => {\n//     if (!state?.debug) {\n//       return this.run(state);\n//     }\n//     return debug(this, label).run(state);\n//   });\n// }\n\n// /**\n//  * Adds an error message to the parser\n//  * @param makeMessage - A function that returns an error message\n//  * @returns A new parser with the error message added\n//  */\n// withError(\n//   makeMessage: (errorCtx: {\n//     error: ParseErrorBundle;\n//     state: ParserState;\n//   }) => string\n// ): Parser<T> {\n//   return new Parser<T>(state => {\n//     const output = this.run(state);\n//     if (Either.isLeft(output.result)) {\n//       return Parser.fail(\n//         {\n//           message: makeMessage({\n//             error: output.result.left,\n//             state: output.state\n//           })\n//         },\n//         output.state\n//       );\n//     }\n//     return output;\n//   });\n// }\n\n// type BindResult<T, K extends string, B> = Clean<T & { [k in K]: B }>;\n// bind<K extends string, B>(\n//   k: K,\n//   other: Parser<B> | ((a: T) => Parser<B>)\n// ): Parser<BindResult<T, K, B>> {\n//   return new Parser<BindResult<T, K, B>>(state => {\n//     const { result: resultA, state: stateA } = this.run(state);\n//     if (Either.isLeft(resultA)) {\n//       return {\n//         result: resultA as unknown as Either<\n//           BindResult<T, K, B>,\n//           ParseErrorBundle\n//         >,\n//         state: stateA\n//       };\n//     }\n//     const nextParser = other instanceof Parser ? other : other(resultA.right);\n//     const { result: resultB, state: stateB } = nextParser.run(stateA);\n//     if (Either.isLeft(resultB)) {\n//       return {\n//         result: resultB as unknown as Either<\n//           BindResult<T, K, B>,\n//           ParseErrorBundle\n//         >,\n//         state: stateB\n//       };\n//     }\n//     return Parser.succeed(\n//       { ...resultA.right, [k]: resultB.right } as BindResult<T, K, B>,\n//       stateB\n//     );\n//   });\n// }\n\n// static Do = Parser.pure({});\n","/**\n * @fileoverview\n */\n\nimport { Either } from \"./either\";\nimport { type ParseError, type ParseErrorBundle } from \"./errors\";\nimport { Parser, parser } from \"./parser\";\nimport {\n  ParserOutput,\n  State,\n  type ParserState,\n  type SourcePosition\n} from \"./state\";\n\n/**\n * Creates a parser that looks ahead in the input stream without consuming any input.\n * The parser will succeed with the result of the given parser but won't advance the input position.\n *\n * @param par - The parser to look ahead with\n * @returns {Parser<T | undefined>} A new parser that peeks at the input without consuming it\n * ```ts\n * const parser = lookahead(char('a'))\n * parser.run('abc') // Right(['a', {...}])\n * // Input position remains at 'abc', 'a' is not consumed\n * ```\n */\nexport const lookahead = <T>(par: Parser<T>): Parser<T | undefined> =>\n  new Parser(state => {\n    const { result } = par.run(state);\n    if (Either.isRight(result)) {\n      return Parser.succeed(result.right, state);\n    }\n    return Parser.succeed(undefined, state);\n  });\n\n/**\n * Creates a parser that succeeds only if the given parser fails to match.\n * If the parser succeeds, this parser fails with an error message.\n *\n * @param par - The parser that should not match\n * @returns {Parser<boolean>} A new parser that succeeds only if the input parser fails\n * ```ts\n * const notA = notFollowedBy(char('a'))\n * notA.run('bcd') // Right([true, {...}]) - Succeeds because 'a' is not found\n * notA.run('abc') // Left(error) - Fails because 'a' is found\n * ```\n */\nexport function notFollowedBy<T>(par: Parser<T>): Parser<boolean> {\n  return new Parser(state => {\n    const { result, state: newState } = par.run(state);\n    if (Either.isRight(result)) {\n      // if (parser.options?.name) {\n      //   const message = `Found ${parser.options.name} when it should not appear here`;\n      //   return Parser.fail({ message, expected: [] }, newState);\n      // }\n      return Parser.fail(\n        {\n          message: \"Expected not to follow\",\n          expected: [],\n          found: state.remaining.at(0)\n        },\n        newState\n      );\n    }\n    return Parser.succeed(true, state);\n  });\n}\n\n/**\n * Creates a parser that matches an exact string in the input.\n *\n * @param str - The string to match\n * @returns {Parser<string>} A parser that matches and consumes the exact string\n * ```ts\n * const parser = string(\"hello\")\n * parser.run(\"hello world\") // Right([\"hello\", {...}])\n * parser.run(\"goodbye\") // Left(error)\n * ```\n */\nexport const string = (str: string): Parser<string> =>\n  new Parser(state => {\n    if (state.remaining.startsWith(str)) {\n      return Parser.succeed(str, State.consume(state, str.length));\n    }\n\n    const message =\n      `Expected '${str}', ` +\n      `but found '${state.remaining.slice(0, str.length)}'`;\n\n    return Parser.fail(\n      {\n        message,\n        expected: [str],\n        found: state.remaining.slice(0, str.length)\n      },\n      state\n    );\n  });\n\n/**\n * Creates a parser that matches an exact string literal type.\n * Similar to string parser but preserves the literal type information.\n *\n * @param str - The string literal to match\n * @returns {Parser<T>} A parser that matches and consumes the exact string with preserved type\n * ```ts\n * const parser = narrowedString(\"hello\") // Parser<\"hello\">\n * parser.run(\"hello world\") // Right([\"hello\", {...}])\n * parser.run(\"goodbye\") // Left(error)\n * ```\n */\nexport const narrowedString = <const T extends string>(str: T): Parser<T> =>\n  string(str) as any;\n\n/**\n * Creates a parser that matches a single character.\n *\n * @param ch - The character to match\n * @returns {Parser<T>} A parser that matches and consumes a single character\n * ```ts\n * const parser = char(\"a\")\n * parser.run(\"abc\") // Right([\"a\", {...}])\n * parser.run(\"xyz\") // Left(error)\n * ```\n */\nexport const char = <T extends string>(ch: T): Parser<T> =>\n  new Parser(state => {\n    if (ch.length !== 1) {\n      return Parser.fail(\n        { message: \"Incorrect usage of char parser.\", expected: [ch] },\n        state\n      );\n    }\n    if (state.remaining[0] === ch) {\n      return Parser.succeed(ch, State.consume(state, 1));\n    }\n\n    return Parser.fail(\n      {\n        message: `Expected ${ch} but found ${state.remaining.at(0)}.`,\n        expected: [ch],\n        found: state.remaining.at(0)\n      },\n      state\n    );\n  });\n\n/**\n * A parser that matches any single alphabetic character (a-z, A-Z).\n *\n * ```ts\n * const parser = alphabet\n * parser.run(\"abc\") // Right([\"a\", {...}])\n * parser.run(\"123\") // Left(error)\n * ```\n */\nexport const alphabet = new Parser(state => {\n  if (State.isAtEnd(state)) {\n    return Parser.fail(\n      { message: \"Unexpected end of input\", expected: [] },\n      state\n    );\n  }\n  const first = state.remaining[0];\n  if (first && /^[a-zA-Z]$/.test(first)) {\n    return Parser.succeed(first, State.consume(state, 1));\n  }\n  const message = `Expected alphabetic character, but got '${first}'`;\n  return Parser.fail(\n    { message, expected: [], found: state.remaining[0] },\n    state\n  );\n});\n\n/**\n * A parser that matches any single digit character (0-9).\n *\n * ```ts\n * const parser = digit\n * parser.run(\"123\") // Right([\"1\", {...}])\n * parser.run(\"abc\") // Left(error)\n * ```\n */\nexport const digit = new Parser(state => {\n  if (State.isAtEnd(state)) {\n    return Parser.fail(\n      { message: \"Unexpected end of input\", expected: [] },\n      state\n    );\n  }\n  const first = state.remaining[0];\n  if (first && /^[0-9]$/.test(first)) {\n    return Parser.succeed(first, State.consume(state, 1));\n  }\n  const message = `Expected digit, but got '${first}'`;\n  return Parser.fail(\n    { message, expected: [], found: state.remaining[0] },\n    state\n  );\n});\n\n/**\n * Creates a parser that matches zero or more occurrences of elements separated by a separator.\n *\n * @param sepParser - Parser for the separator between elements\n * @param parser - Parser for the elements\n * @returns {Parser<T[]>} A parser that produces an array of matched elements\n *\n * ```ts\n * const parser = sepBy(char(','), digit)\n * parser.run(\"1,2,3\") // Right([[\"1\", \"2\", \"3\"], {...}])\n * parser.run(\"\") // Right([[], {...}])\n * ```\n */\n// TODO: fix this\nexport function sepBy<S, T>(\n  parser: Parser<T>,\n  sepParser: Parser<S>\n): Parser<T[]> {\n  return new Parser(state => {\n    const results: T[] = [];\n    let currentState = state;\n\n    const { result: firstResult, state: firstState } = parser.run(currentState);\n    if (Either.isLeft(firstResult)) {\n      return Parser.succeed([], state);\n    }\n\n    results.push(firstResult.right);\n    currentState = firstState;\n\n    while (true) {\n      const { result: sepResult, state: sepState } =\n        sepParser.run(currentState);\n      if (Either.isLeft(sepResult)) {\n        break;\n      }\n\n      const { result: itemResult, state: itemState } = parser.run(sepState);\n      if (Either.isLeft(itemResult)) {\n        break;\n      }\n\n      results.push(itemResult.right);\n      currentState = itemState;\n    }\n\n    return Parser.succeed(results, currentState);\n  });\n}\n\n/**\n * Parses one or more occurrences of a parser separated by another parser.\n * Requires at least one match of the main parser.\n *\n * @param par - The parser for the elements\n * @param sepParser - The parser for the separator\n * @returns {Parser<T[]>} A parser that produces a non-empty array of parsed elements\n *\n * @example\n * ```ts\n * const numbers = sepBy1(number, char(','))\n * numbers.parse(\"1,2,3\") // Success: [1, 2, 3]\n * numbers.parse(\"\") // Error: Expected at least one element\n * ```\n */\nexport function sepBy1<S, T>(\n  par: Parser<T>,\n  sepParser: Parser<S>\n): Parser<T[]> {\n  return parser(function* () {\n    const first = yield* par;\n    const rest = yield* many0(sepParser.then(par));\n    return [first, ...rest];\n  });\n}\n\n/**\n * Creates a parser that matches content between two string delimiters.\n *\n * @param start - The opening delimiter string\n * @param end - The closing delimiter string\n * @param par - The parser for the content between delimiters\n * @returns {Parser<T>} A parser that matches content between delimiters\n *\n * ```ts\n * const parser = between(char('('), char(')'), digit)\n * parser.run('(5)') // Right(['5', {...}])\n * parser.run('5') // Left(error)\n * parser.run('(5') // Left(error: Expected closing delimiter)\n * ```\n */\nexport function between<T>(\n  start: Parser<any>,\n  end: Parser<any>,\n  par: Parser<T>\n): Parser<T> {\n  return parser(function* () {\n    yield* start;\n    const content = yield* par;\n    yield* end.expect(`closing delimiter`);\n    return content;\n  });\n}\n\n/**\n * A parser that matches any single character.\n *\n * @returns {Parser<string>} A parser that matches any single character\n */\nexport function anyChar(): Parser<string> {\n  return new Parser<string>(state => {\n    if (State.isAtEnd(state)) {\n      return Parser.fail(\n        { message: \"Unexpected end of input\", expected: [] },\n        state\n      );\n    }\n    return Parser.succeed(state.remaining[0], State.consume(state, 1));\n  });\n}\n\n/**\n * Internal helper function for creating repetition parsers.\n *\n * @param count - Minimum number of repetitions required\n * @returns {(parser: Parser<T>, separator?: Parser<S>) => Parser<T[]>} A function that creates a parser matching multiple occurrences\n */\nfunction many_<S, T>(\n  count: number\n): (parser: Parser<T>, separator?: Parser<S>) => Parser<T[]> {\n  return (parser: Parser<T>, separator?: Parser<S>): Parser<T[]> => {\n    return new Parser(state => {\n      const results: T[] = [];\n      let currentState = state;\n\n      while (true) {\n        // Try to parse the next item\n        const itemResult = parser.run(currentState);\n        if (Either.isLeft(itemResult.result)) {\n          // Check if we're in a committed state\n          const isCommitted =\n            itemResult.state?.committed && !currentState?.committed;\n\n          // If committed, propagate the error regardless of count\n          if (isCommitted) {\n            return itemResult as unknown as typeof itemResult & {\n              result: Either<T[], ParseErrorBundle>;\n            };\n          }\n\n          // If we have enough items, return success\n          if (results.length >= count) {\n            return Parser.succeed(results, currentState);\n          }\n          const message = `Expected at least ${count} occurrences, but only found ${results.length}`;\n          return Parser.fail({ message, expected: [] }, itemResult.state);\n        }\n\n        // Add the item and update state\n        const { result: value, state: newState } = itemResult;\n        results.push(value.right);\n\n        // Check that parser advanced - prevent infinite loops\n        if (newState.pos.offset <= currentState.pos.offset) {\n          throw new Error(\"Parser did not advance - infinite loop prevented\");\n        }\n        currentState = newState as ParserState;\n\n        // If we have a separator, try to parse it\n        if (separator) {\n          const { result: sepResult, state } = separator.run(currentState);\n          if (Either.isLeft(sepResult)) {\n            break;\n          }\n          // Check that separator advanced too\n          if (state.pos.offset <= currentState.pos.offset) {\n            throw new Error(\n              \"Separator parser did not advance - infinite loop prevented\"\n            );\n          }\n          currentState = state as ParserState;\n        }\n      }\n\n      if (results.length >= count) {\n        return Parser.succeed(results, currentState);\n      }\n\n      const message = `Expected at least ${count} occurrences, but only found ${results.length}`;\n      return Parser.fail({ message, expected: [] }, currentState);\n    });\n  };\n}\n\n/**\n * Creates a parser that matches zero or more occurrences of the input parser.\n *\n * @param parser - The parser to repeat\n * @returns {Parser<T[]>} A parser that produces an array of all matches\n */\nexport const many0 = <S, T>(\n  parser: Parser<T>,\n  separator?: Parser<S>\n): Parser<T[]> => many_<S, T>(0)(parser, separator);\n\n/**\n * Parses zero or more occurrences of a parser (alias for many0).\n *\n * @param parser - The parser to repeat\n * @returns {Parser<T[]>} A parser that produces an array of parsed elements\n */\nexport const many = <T>(parser: Parser<T>): Parser<T[]> => many0(parser);\n\n/**\n * Creates a parser that matches one or more occurrences of the input parser.\n *\n * @param parser - The parser to repeat\n * @returns {Parser<T[]>} A parser that produces an array of all matches (at least one)\n */\nexport const many1 = <S, T>(\n  parser: Parser<T>,\n  separator?: Parser<S>\n): Parser<T[]> => many_<S, T>(1)(parser, separator);\n\n/**\n * Creates a parser that matches at least n occurrences of the input parser.\n *\n * @param parser - The parser to repeat\n * @param n - Number of required repetitions\n * @returns {Parser<T[]>} A parser that produces an array of at least n matches\n */\nexport const manyN = <S, T>(\n  parser: Parser<T>,\n  n: number,\n  separator?: Parser<S>\n): Parser<T[]> => many_<S, T>(n)(parser, separator);\n\n/**\n * Creates a parser that matches exactly n occurrences of the input parser.\n *\n * @param parser - The parser to repeat\n * @param n - Number of required repetitions\n * @param separator - Optional parser to match between occurrences\n * @returns {Parser<T[]>} A parser that produces an array of exactly n matches\n */\n\nexport const manyNExact = <S, T>(\n  par: Parser<T>,\n  n: number,\n  separator?: Parser<S>\n): Parser<T[]> =>\n  parser(function* () {\n    const results = yield* manyN(par, n, separator);\n    if (results.length !== n) {\n      const message = `Expected exactly ${n} occurrences, but found ${results.length}`;\n      return yield* Parser.fatal(message);\n    }\n    return results;\n  });\n\n/**\n * Internal helper function for creating skipping repetition parsers.\n *\n * @param count - Minimum number of repetitions required\n * @returns {(parser: Parser<T>) => Parser<undefined>} A function that creates a parser skipping multiple occurrences\n */\nconst skipMany_ =\n  <T>(count: number): ((parser: Parser<T>) => Parser<undefined>) =>\n  (parser: Parser<T>): Parser<undefined> =>\n    new Parser(state => {\n      let currentState = state;\n      let successes = 0;\n\n      while (true) {\n        const { result, state: newState } = parser.run(currentState);\n        if (Either.isLeft(result)) {\n          break;\n        }\n\n        // Check that parser advanced - prevent infinite loops\n        if (newState.pos.offset <= currentState.pos.offset) {\n          throw new Error(\"Parser did not advance - infinite loop prevented\");\n        }\n\n        successes++;\n        currentState = newState as ParserState;\n      }\n\n      if (successes >= count) {\n        return Parser.succeed(undefined, currentState);\n      }\n      const message = `Expected at least ${count} occurrences, but only found ${successes}`;\n      return Parser.fail({ message, expected: [] }, state);\n    });\n\n/**\n * Creates a parser that skips zero or more occurrences of the input parser.\n *\n * @param parser - The parser to skip\n * @returns {Parser<undefined>} A parser that skips all matches\n */\nexport const skipMany0 = <T>(parser: Parser<T>): Parser<undefined> =>\n  skipMany_<T>(0)(parser);\n\n/**\n * Creates a parser that skips one or more occurrences of the input parser.\n *\n * @param parser - The parser to skip\n * @returns {Parser<undefined>} A parser that skips all matches (requires at least one)\n */\nexport const skipMany1 = <T>(parser: Parser<T>): Parser<undefined> =>\n  skipMany_<T>(1)(parser);\n\n/**\n * Creates a parser that skips exactly n occurrences of the input parser.\n *\n * @param parser - The parser to skip\n * @param n - Number of required repetitions to skip\n * @returns A parser that skips exactly n matches\n */\nexport const skipManyN = <T>(parser: Parser<T>, n: number) =>\n  skipMany_<T>(n)(parser);\n\n/**\n * Creates a parser that skips input until the given parser succeeds.\n *\n * @param parser - The parser to look for\n * @returns A parser that skips input until a match is found\n */\nexport function skipUntil<T>(parser: Parser<T>): Parser<undefined> {\n  return new Parser(state => {\n    let currentState = state;\n\n    while (!State.isAtEnd(currentState)) {\n      const { result, state: newState } = parser.run(currentState);\n      if (Either.isRight(result)) {\n        return Parser.succeed(undefined, newState);\n      }\n      currentState = State.consume(currentState, 1);\n    }\n\n    return Parser.succeed(undefined, currentState);\n  });\n}\n\n/**\n * Creates a parser that takes input until the given parser succeeds.\n *\n * @param parser - The parser to look for\n * @returns A parser that takes input until a match is found\n */\nexport function takeUntil<T>(parser: Parser<T>): Parser<string> {\n  return new Parser(state => {\n    let currentState = state;\n    let collected = \"\";\n\n    while (!State.isAtEnd(currentState)) {\n      const { result, state: newState } = parser.run(currentState);\n      if (Either.isRight(result)) {\n        return Parser.succeed(collected, newState);\n      }\n      collected += currentState.remaining[0];\n      currentState = State.consume(currentState, 1);\n    }\n\n    return Parser.succeed(collected, currentState);\n  });\n}\n\n/**\n * Creates a parser that takes input until the given character is found.\n *\n * @param char - The character to look for\n * @returns A parser that takes input until the character is found\n */\nexport function parseUntilChar(char: string): Parser<string> {\n  return new Parser(state => {\n    if (char.length !== 1) {\n      return Parser.fail(\n        {\n          message: \"Incorrect usage of parseUntilChar parser.\",\n          expected: [char]\n        },\n        state\n      );\n    }\n    let currentState = state;\n    let collected = \"\";\n\n    while (!State.isAtEnd(currentState)) {\n      if (currentState.remaining[0] === char) {\n        return Parser.succeed(collected, currentState);\n      }\n      collected += currentState.remaining[0];\n      currentState = State.consume(currentState, 1);\n    }\n\n    const message = `Expected character ${char} but found ${collected}`;\n    return Parser.fail({ message, expected: [char] }, currentState);\n  });\n}\n\n/**\n * A parser that skips any number of space characters.\n */\nexport const skipSpaces = new Parser(state =>\n  Parser.succeed(\n    undefined,\n    State.consumeWhile(state, char => char === \" \")\n  )\n);\n\n/**\n * Creates a parser that tries multiple parsers in order until one succeeds.\n *\n * @param parsers - Array of parsers to try\n * @returns A parser that succeeds if any of the input parsers succeed\n */\n/**\n * Creates a parser that tries each of the given parsers in order until one succeeds.\n *\n * This combinator is commit-aware: if any parser sets the `committed` flag during\n * parsing, no further alternatives will be tried. This enables better error messages\n * by preventing backtracking once we've identified the intended parse path.\n *\n * @param parsers - Array of parsers to try in order\n * @returns {Parser<Parsers[number] extends Parser<infer T> ? T : never>} A parser that succeeds with the first successful parser's result\n *\n * @example\n * ```ts\n * // Basic usage - tries each alternative\n * const value = or(\n *   numberLiteral,\n *   stringLiteral,\n *   booleanLiteral\n * )\n * ```\n *\n * @example\n * ```ts\n * // With commit for better errors\n * const statement = or(\n *   parser(function* () {\n *     yield* keyword(\"if\")\n *     yield* commit()  // No backtracking after this\n *     yield* char('(').expect(\"opening parenthesis\")\n *     // ...\n *   }),\n *   whileStatement,\n *   assignment\n * )\n *\n * // Input: \"if x > 5\"  (missing parentheses)\n * // Without commit: \"Expected if, while, or assignment\"\n * // With commit: \"Expected opening parenthesis\"\n * ```\n *\n * @example\n * ```ts\n * // Error accumulation without commit\n * const config = or(\n *   jsonParser.label(\"JSON format\"),\n *   yamlParser.label(\"YAML format\"),\n *   tomlParser.label(\"TOML format\")\n * )\n * // Errors from all three parsers are accumulated\n * ```\n */\nexport function or<Parsers extends Parser<any>[]>(\n  ...parsers: Parsers\n): Parser<Parsers[number] extends Parser<infer T> ? T : never> {\n  return new Parser(state => {\n    const errors: ParseError[] = [];\n\n    for (const parser of parsers) {\n      const { result, state: newState } = parser.run(state);\n\n      if (Either.isRight(result)) {\n        return Parser.succeed(result.right, newState);\n      }\n\n      // Accumulate errors from this branch\n      errors.push(...result.left.errors);\n\n      // Check if we're committed - if so, don't try other alternatives\n      if (newState?.committed && !state?.committed) {\n        return Parser.failRich({ errors }, newState);\n      }\n    }\n\n    // All alternatives failed, return accumulated errors\n    return Parser.failRich({ errors }, state);\n  });\n}\n\n/**\n * Creates a parser that optionally matches the input parser.\n * If the parser fails, returns undefined without consuming input.\n *\n * @param parser - The parser to make optional\n * @returns {Parser<T | undefined>} A parser that either succeeds with a value or undefined\n */\nexport function optional<T>(parser: Parser<T>): Parser<T | undefined> {\n  return new Parser((state: ParserState) => {\n    const { result, state: newState } = parser.run(state);\n    if (Either.isLeft(result)) {\n      return Parser.succeed(undefined, state);\n    }\n    // return result\n    return Parser.succeed(result.right, newState);\n  });\n}\n\ntype SequenceOutput<T extends Parser<any>[], Acc extends any[] = []> =\n  T[\"length\"] extends 0 ? Acc\n  : T extends [Parser<infer Head extends any>, ...infer Tail extends any[]] ?\n    SequenceOutput<Tail, [...Acc, Head]>\n  : never;\n\n/**\n * Creates a parser that runs multiple parsers in sequence and returns all results.\n *\n * @param parsers - Array of parsers to run in sequence\n * @returns {Parser<SequenceOutput<T>>} A parser that succeeds if all parsers succeed in order, returning a tuple of all results\n *\n * @example\n * ```ts\n * const parser = sequence([digit, char('-'), digit])\n * parser.run('1-2') // Right([['1', '-', '2'], {...}])\n * ```\n */\nexport const sequence = <const T extends any[]>(\n  parsers: T\n): Parser<SequenceOutput<T>> =>\n  parser(function* () {\n    const results = [];\n    for (const parser of parsers) {\n      const result = yield* parser;\n      results.push(result);\n    }\n    return results as any;\n  });\n\n/**\n * Creates a parser that matches input against a regular expression.\n * The regex must match at the start of the input.\n *\n * @param re - The regular expression to match against\n * @returns {Parser<string>} A parser that matches the regex pattern\n */\nexport const regex = (re: RegExp): Parser<string> => {\n  // Create a new RegExp without global flag to ensure consistent behavior\n  const nonGlobalRe = new RegExp(re.source, re.flags.replace(\"g\", \"\"));\n\n  return new Parser(state => {\n    const match = nonGlobalRe.exec(state.remaining);\n    if (match && match.index === 0) {\n      const value = match[0];\n      return Parser.succeed(value, State.consume(state, value.length));\n    }\n    const message = `Expected ${re} but found ${state.remaining.slice(0, 10)}...`;\n    return Parser.fail({ message, expected: [re.toString()] }, state);\n  });\n};\n\nexport function zip<A, B>(\n  parserA: Parser<A>,\n  parserB: Parser<B>\n): Parser<[A, B]> {\n  return parserA.zip(parserB);\n}\n\nexport function then<A, B>(parserA: Parser<A>, parserB: Parser<B>): Parser<B> {\n  return parserA.then(parserB);\n}\n\nexport const zipRight = then;\n\nexport function thenDiscard<A, B>(\n  parserA: Parser<A>,\n  parserB: Parser<B>\n): Parser<A> {\n  return parserA.thenDiscard(parserB);\n}\nexport const zipLeft = thenDiscard;\n\n/**\n * Creates a parser that takes input until the given parser would succeed, without consuming the parser.\n *\n * @param parser - The parser to look for\n * @returns A parser that takes input until before a match would be found\n */\nexport function takeUpto<T>(parser: Parser<T>): Parser<string> {\n  return new Parser(state => {\n    let currentState = state;\n    let collected = \"\";\n\n    while (!State.isAtEnd(currentState)) {\n      const { result } = parser.run(currentState);\n      if (Either.isRight(result)) {\n        return Parser.succeed(collected, currentState);\n      }\n      collected += currentState.remaining[0];\n      currentState = State.consume(currentState, 1);\n    }\n\n    return Parser.succeed(collected, currentState);\n  });\n}\n\n/**\n * Creates a parser that commits to the current parsing path, preventing backtracking.\n *\n * After calling `commit()`, if parsing fails later in the sequence, the parser won't\n * backtrack to try alternatives in a `choice` or `or` combinator. This results in\n * more specific, helpful error messages instead of generic \"expected one of\" errors.\n *\n * @returns {Parser<void>} A parser that sets the commit flag in the parsing context\n *\n * @example\n * ```ts\n * // Use commit after identifying the type of construct\n * const ifStatement = parser(function* () {\n *   yield* keyword(\"if\")\n *   yield* commit()  // No backtracking after this point\n *   yield* char('(').expect(\"opening parenthesis after 'if'\")\n *   const condition = yield* expression\n *   yield* char(')').expect(\"closing parenthesis\")\n *   const body = yield* block\n *   return { type: \"if\", condition, body }\n * })\n * ```\n *\n * @example\n * ```ts\n * // Commit in different parsing contexts\n * const jsonParser = parser(function* () {\n *   const firstChar = yield* peekChar\n *\n *   if (firstChar === '{') {\n *     yield* char('{')\n *     yield* commit()  // Definitely parsing an object\n *     return yield* jsonObject\n *   } else if (firstChar === '[') {\n *     yield* char('[')\n *     yield* commit()  // Definitely parsing an array\n *     return yield* jsonArray\n *   }\n *   // ...\n * })\n * ```\n *\n * @example\n * ```ts\n * // Commit with error recovery\n * const statement = choice([\n *   ifStatement,    // Has commit() after \"if\"\n *   whileStatement, // Has commit() after \"while\"\n *   forStatement,   // Has commit() after \"for\"\n *   expression      // No commit, can always fall back to this\n * ])\n *\n * // Input: \"if (x > 5 { }\"  (missing closing paren)\n * // Result: \"Expected closing parenthesis\" (not \"Expected if, while, for, or expression\")\n * ```\n *\n * @see {@link cut} - Alias with Prolog-style naming\n */\nexport function commit(): Parser<void> {\n  return new Parser(state => {\n    return Parser.succeed(void 0, {\n      ...state,\n      committed: true\n    }) as any;\n  });\n}\n\n/**\n * Alias for {@link commit} using Prolog-style naming.\n *\n * The cut operator (!) in Prolog prevents backtracking, similar to how\n * this prevents the parser from trying other alternatives after this point.\n *\n * @example\n * ```ts\n * const prologStyleIf = parser(function* () {\n *   yield* keyword(\"if\")\n *   yield* cut()  // Using Prolog-style naming\n *   yield* char('(')\n *   // ...\n * })\n * ```\n */\nexport const cut = commit;\n\n/**\n * Creates an atomic parser that either fully succeeds or resets to the original state.\n *\n * This combinator wraps a parser in a transaction-like behavior. If the parser fails\n * at any point, the input position is reset to where it was before the atomic parser\n * started, as if no input was consumed.\n *\n * @param parser - The parser to make atomic\n * @returns {Parser<T>} A new parser with atomic (all-or-nothing) behavior\n *\n * @example\n * ```ts\n * // Try to parse a complex structure without consuming input on failure\n * const functionCall = atomic(\n *   parser(function* () {\n *     const name = yield* identifier\n *     yield* char('(')\n *     const args = yield* sepBy(expression, char(','))\n *     yield* char(')')\n *     return { name, args }\n *   })\n * )\n * ```\n *\n * @example\n * ```ts\n * // Use atomic for lookahead without consumption\n * const nextIsOperator = atomic(\n *   or(\n *     string(\"++\"),\n *     string(\"--\"),\n *     string(\"+=\"),\n *     string(\"-=\")\n *   )\n * ).map(() => true).or(Parser.succeed(false))\n * ```\n *\n * @example\n * ```ts\n * // Combine with 'or' for clean alternatives\n * const value = or(\n *   atomic(complexExpression),  // Try complex first\n *   atomic(simpleExpression),   // Then simpler\n *   literal                     // Finally, just a literal\n * )\n *\n * // If complexExpression fails after consuming \"foo + \",\n * // atomic ensures we backtrack completely\n * ```\n *\n * @see {@link Parser.atomic} - Instance method version\n */\nexport function atomic<T>(parser: Parser<T>): Parser<T> {\n  return parser.atomic();\n}\n\n/**\n * Parses any character except the specified one.\n *\n * @param ch - The character to exclude\n * @returns {Parser<string>} A parser that matches any character except the specified one\n *\n * @example\n * ```ts\n * const notQuote = notChar('\"')\n * notQuote.parse('a') // Success: 'a'\n * notQuote.parse('\"') // Error: Expected any character except '\"'\n * ```\n */\nexport function notChar(ch: string): Parser<string> {\n  return new Parser(state => {\n    if (ch.length !== 1) {\n      return Parser.fail(\n        {\n          message: \"notChar expects a single character\",\n          expected: []\n        },\n        state\n      );\n    }\n\n    if (state.remaining[0] && state.remaining[0] !== ch) {\n      return Parser.succeed(state.remaining[0], State.consume(state, 1));\n    }\n\n    return Parser.fail(\n      {\n        message: `Expected any character except '${ch}'`,\n        expected: [`not '${ch}'`],\n        found: state.remaining[0]\n      },\n      state\n    );\n  });\n}\n\n/**\n * Parser that succeeds only at the end of input.\n *\n * @example\n * ```ts\n * const parser = string(\"hello\").then(eof)\n * parser.parse(\"hello\") // Success\n * parser.parse(\"hello world\") // Error: Expected end of input\n * ```\n */\nexport const eof = new Parser<void>(state => {\n  if (state.remaining.length === 0) {\n    return Parser.succeed(undefined, state);\n  }\n  return Parser.fail(\n    {\n      message: \"Expected end of input\",\n      expected: [\"end of input\"],\n      found:\n        state.remaining.slice(0, 20) +\n        (state.remaining.length > 20 ? \"...\" : \"\")\n    },\n    state\n  );\n});\n\n/**\n * Parses exactly n occurrences of a parser.\n *\n * @param n - The exact number of occurrences\n * @param parser - The parser to repeat\n * @returns {Parser<T[]>} A parser that produces an array of exactly n elements\n *\n * @example\n * ```ts\n * const threeDigits = count(3, digit)\n * threeDigits.parse(\"123\") // Success: ['1', '2', '3']\n * threeDigits.parse(\"12\") // Error: not enough matches\n * ```\n */\nexport function count<T>(n: number, par: Parser<T>): Parser<T[]> {\n  return parser(function* () {\n    const results: T[] = [];\n    for (let i = 0; i < n; i++) {\n      const result = yield* par;\n      results.push(result);\n    }\n    return results;\n  });\n}\n\n/**\n * Parses a list with optional trailing separator.\n *\n * @param parser - The parser for list elements\n * @param sep - The parser for separators\n * @returns {Parser<T[]>} A parser that allows optional trailing separator\n *\n * @example\n * ```ts\n * const list = sepEndBy(number, char(','))\n * list.parse(\"1,2,3\") // Success: [1, 2, 3]\n * list.parse(\"1,2,3,\") // Success: [1, 2, 3] (trailing comma OK)\n * ```\n */\nexport const sepEndBy = <S, T>(par: Parser<T>, sep: Parser<S>): Parser<T[]> =>\n  or(\n    parser(function* () {\n      const elements = yield* sepBy(par, sep);\n      yield* optional(sep); // Allow trailing separator\n      return elements;\n    }),\n    Parser.pure([])\n  );\n\nexport const position: Parser<SourcePosition> = new Parser(state => {\n  return ParserOutput(state, Either.right(state.pos));\n});\n","import { Parser } from \"./parser\";\nimport { type ParseError, Span } from \"./errors\";\nimport { State } from \"./state\";\n\n/**\n * Calculate the Levenshtein distance between two strings.\n * This measures the minimum number of single-character edits (insertions, deletions, or substitutions)\n * required to change one string into another.\n *\n * @param a - The first string\n * @param b - The second string\n * @returns The edit distance between the strings\n */\nexport function levenshteinDistance(a: string, b: string): number {\n  const matrix = Array(b.length + 1)\n    .fill(null)\n    .map(() => Array(a.length + 1).fill(null));\n\n  // Initialize first row and column\n  for (let i = 0; i <= a.length; i++) matrix[0][i] = i;\n  for (let j = 0; j <= b.length; j++) matrix[j][0] = j;\n\n  // Fill the matrix\n  for (let j = 1; j <= b.length; j++) {\n    for (let i = 1; i <= a.length; i++) {\n      const indicator = a[i - 1] === b[j - 1] ? 0 : 1;\n      matrix[j][i] = Math.min(\n        matrix[j][i - 1] + 1, // deletion\n        matrix[j - 1][i] + 1, // insertion\n        matrix[j - 1][i - 1] + indicator // substitution\n      );\n    }\n  }\n\n  return matrix[b.length][a.length];\n}\n\n/**\n * Generate helpful hints for a user's input based on a list of expected values.\n * Uses edit distance to find the closest matches and suggests them as \"Did you mean...\" options.\n *\n * @param found - The string the user actually typed\n * @param expected - Array of valid/expected strings\n * @param maxDistance - Maximum edit distance to consider (default: 2)\n * @param maxHints - Maximum number of hints to return (default: 3)\n * @returns Array of suggested strings, sorted by edit distance\n */\nexport function generateHints(\n  found: string,\n  expected: string[],\n  maxDistance: number = 2,\n  maxHints: number = 3\n): string[] {\n  const hints: Array<{ word: string; distance: number }> = [];\n\n  for (const candidate of expected) {\n    const distance = levenshteinDistance(found, candidate);\n    if (distance <= maxDistance && distance > 0) {\n      hints.push({ word: candidate, distance });\n    }\n  }\n\n  return hints\n    .sort((a, b) => a.distance - b.distance)\n    .slice(0, maxHints)\n    .map(h => h.word);\n}\n\n/**\n * Enhanced keyword parser that provides intelligent hints when the user types something similar.\n *\n * @param keywords - Array of valid keywords to match against\n * @returns A function that creates a parser for a specific keyword with hint generation\n *\n * @example\n * ```ts\n * const schemeKeywords = [\"lambda\", \"let\", \"if\", \"cond\", \"define\", \"quote\"]\n * const lambdaParser = keywordWithHints(schemeKeywords)(\"lambda\")\n *\n * // Parsing \"lamdba\" will suggest \"lambda\" as a hint\n * const result = lambdaParser.parse(\"lamdba\")\n * ```\n */\nexport const keywordWithHints =\n  (keywords: string[]): ((keyword: string) => Parser<string>) =>\n  (keyword: string) =>\n    new Parser(state => {\n      if (state.remaining.startsWith(keyword)) {\n        return Parser.succeed(keyword, State.consume(state, keyword.length));\n      }\n\n      // Try to extract what the user actually typed\n      const match = state.remaining.match(/^[a-zA-Z_][a-zA-Z0-9_]*/);\n      const found = match ? match[0] : state.remaining[0] || \"end of input\";\n\n      const hints = generateHints(found, keywords);\n\n      const error: ParseError = {\n        tag: \"Unexpected\",\n        span: Span(state, found.length),\n        found,\n        context: state.labelStack || [],\n        ...(hints.length > 0 && { hints })\n      };\n\n      return Parser.failRich({ errors: [error] }, state);\n    });\n\n/**\n * Creates a parser that matches any of the provided keywords with hint generation.\n *\n * @param keywords - Array of valid keywords\n * @returns A parser that matches any keyword and provides hints for typos\n *\n * @example\n * ```ts\n * const jsKeywords = [\"function\", \"const\", \"let\", \"var\", \"class\", \"if\", \"else\"]\n * const keywordParser = anyKeywordWithHints(jsKeywords)\n *\n * // Parsing \"functoin\" will suggest \"function\"\n * const result = keywordParser.parse(\"functoin\")\n * ```\n */\nexport function anyKeywordWithHints(keywords: string[]): Parser<string> {\n  return new Parser(state => {\n    // Try each keyword\n    for (const keyword of keywords) {\n      if (state.remaining.startsWith(keyword)) {\n        return Parser.succeed(keyword, State.consume(state, keyword.length));\n      }\n    }\n\n    // No exact match found, try to extract what was typed and generate hints\n    const match = state.remaining.match(/^[a-zA-Z_][a-zA-Z0-9_]*/);\n    const found = match ? match[0] : state.remaining[0] || \"end of input\";\n\n    const hints = generateHints(found, keywords);\n\n    const error: ParseError = {\n      tag: \"Unexpected\",\n      span: Span(state, found.length),\n      found,\n      context: state.labelStack || [],\n      ...(hints.length > 0 && { hints })\n    };\n\n    return Parser.failRich({ errors: [error] }, state);\n  });\n}\n\n/**\n * Creates a parser for string literals with hint generation for common mistakes.\n *\n * @param validStrings - Array of valid string values\n * @returns A parser that matches quoted strings and provides hints for typos\n *\n * @example\n * ```ts\n * const colorParser = stringWithHints([\"red\", \"green\", \"blue\", \"yellow\"])\n *\n * // Parsing '\"gren\"' will suggest \"green\"\n * const result = colorParser.parse('\"gren\"')\n * ```\n */\nexport function stringWithHints(validStrings: string[]): Parser<string> {\n  return new Parser(state => {\n    // Must start with quote\n    if (!state.remaining.startsWith('\"')) {\n      const error: ParseError = {\n        tag: \"Expected\",\n        span: Span(state, 1),\n        items: [\"string literal\"],\n        context: state.labelStack || []\n      };\n      return Parser.failRich({ errors: [error] }, state);\n    }\n\n    // Find the closing quote\n    let i = 1;\n    let content = \"\";\n    while (i < state.remaining.length && state.remaining[i] !== '\"') {\n      content += state.remaining[i];\n      i++;\n    }\n\n    if (i >= state.remaining.length) {\n      const error: ParseError = {\n        tag: \"Expected\",\n        span: Span(state, i),\n        items: [\"closing quote\"],\n        context: state.labelStack || []\n      };\n      return Parser.failRich({ errors: [error] }, state);\n    }\n\n    // Check if content is valid\n    if (validStrings.includes(content)) {\n      return Parser.succeed(content, State.consume(state, i + 1));\n    }\n\n    // Generate hints for invalid content\n    const hints = generateHints(content, validStrings);\n\n    const error: ParseError = {\n      tag: \"Unexpected\",\n      span: Span(state, i + 1),\n      found: `\"${content}\"`,\n      context: state.labelStack || [],\n      ...(hints.length > 0 && { hints: hints.map(h => `\"${h}\"`) })\n    };\n\n    return Parser.failRich({ errors: [error] }, state);\n  });\n}\n","/**\n * @fileoverview Utility parsers for inspecting parser state without consuming input.\n * These utilities are useful for debugging and understanding parser behavior.\n */\n\nimport { Parser } from \"./parser\";\n\nexport const peekState = new Parser(s => {\n  return Parser.succeed(s, s);\n});\n\nexport const peekRemaining = new Parser(s => {\n  return Parser.succeed(s.remaining, s);\n});\n\nexport const peekAhead = (n: number) =>\n  new Parser(s => {\n    return Parser.succeed(s.remaining.slice(0, n), s);\n  });\n\nexport const peekLine = new Parser(s => {\n  const restOfLine = s.remaining.slice(0, s.remaining.indexOf(\"\\n\"));\n  console.log(restOfLine);\n  return Parser.succeed(restOfLine, s);\n});\n\nexport const peekUntil = (ch: string) =>\n  new Parser(s => {\n    const index = s.remaining.indexOf(ch);\n    return Parser.succeed(s.remaining.slice(0, index), s);\n  });\n\ntype Narrowed<T> =\n  T extends readonly any[] ? [...T]\n  : T extends Record<string, any> ? { -readonly [K in keyof T]: Narrowed<T[K]> }\n  : T;\n\nexport function narrow<const T>(value: T): Narrowed<T> {\n  return value as any;\n}\n"],"mappings":"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","names":["ErrorFormatter","char","parser","parser","count","message","state","char","error"]}