class Rouge::RegexLexer

def self.[](name)

def self.[](name)
  get_state(name)
end

def self.get_state(name)

def self.get_state(name)
  return name if name.is_a? State
  state = states[name.to_s]
  raise "unknown state: #{name}" unless state
  state.load!
end

def self.start(&b)

def self.start(&b)
  start_procs << b
end

def self.start_procs

def self.start_procs
  @start_procs ||= []
end

def self.state(name, &b)

def self.state(name, &b)
  name = name.to_s
  states[name] = State.new(self, name, &b)
end

def self.states

def self.states
  @states ||= {}
end

def get_state(name)

def get_state(name)
  self.class.get_state(name)
end

def reset!

def reset!
  @scan_state = nil
  self.class.start_procs.each do |pr|
    scan_state.instance_eval(&pr)
  end
end

def run_rule(rule, scan_state, &b)

def run_rule(rule, scan_state, &b)
  case rule
  when String
    debug { "  entering mixin #{rule}" }
    res = step(get_state(rule), scan_state, &b)
    debug { "  exiting  mixin #{rule}" }
    res
  when Rule
    debug { "  trying #{rule.inspect}" }
    scan_state.scan(rule.re) do |match|
      debug { "    got #{match[0].inspect}" }
      scan_state.run_callback(&rule.callback).each do |tok, res|
        debug { "    yielding #{tok.to_s.inspect}, #{res.inspect}" }
        b.call(Token[tok], res)
      end
    end
  end
end

def scan_state

def scan_state
  @scan_state ||= ScanState.new(self)
end

def step(state, scan_state, &b)

def step(state, scan_state, &b)
  state.rules.each do |rule|
    return true if run_rule(rule, scan_state, &b)
  end
  false
end

def stream_tokens(stream, &b)

def stream_tokens(stream, &b)
  scan_state.scanner = stream
  until scan_state.eos?
    debug { "lexer: #{self.class.tag}" }
    debug { "stack: #{scan_state.stack.map(&:name).inspect}" }
    debug { "stream: #{scan_state.scanner.peek(20).inspect}" }
    success = step(get_state(scan_state.state), scan_state, &b)
    if !success
      debug { "    no match, yielding Error" }
      b.call(Token['Error'], scan_state.scanner.getch)
    end
  end
end