// gerber and drill file lexer + tokenizer
import Moo from 'moo'
import {Token} from './tokens'
import {rules} from './rules'

export type LexerState = Moo.LexerState

export * from './tokens'

/**
 * {@linkcode Lexer} factory
 *
 * @example
 * ```ts
 * import {createLexer} from '@tracespace/parser'
 *
 * const lexer = createLexer()
 *
 * lexer.reset('G04 gerber string*\nM02*\n')
 *
 * Array.from(lexer).forEach(token => {
 *   console.log(`${token.type}: ${token.value}`)
 * })
 * ```
 *
 * @category Lexer
 */
export function createLexer(): Lexer {
  return Moo.compile(rules) as Lexer
}

/**
 * The lexing module of the parser. The Lexer is generated by
 * {@link https://github.com/no-context/moo | Moo}, which determines its API.
 *
 * @category Lexer
 */
export interface Lexer extends Moo.Lexer {
  /** Cursor position in the current chunk */
  index?: number
  /** Retrieve the next token from the chunk if available */
  next(): Token | undefined
  /** The Lexer may be treated as an iterator to get tokens */
  [Symbol.iterator](): Iterator<Token>
}
