-- -*- Haskell -*-

-- The include file for alex-generated syntax highlighters.  Because alex
-- declares its own types, any wrapper must have the highlighter in scope...
-- so it must be included.  Doubleplusyuck.

#define IBOX(n) (I# (n))

#define GEQ_(x, y) (GHC.Exts.tagToEnum# (x >=# y))
#define EQ_(x, y) (GHC.Exts.tagToEnum# (x ==# y))

-- | Scan one token. Return (maybe) a token and a new state.
alexScanToken :: (AlexState HlState, AlexInput) -> Maybe (Tok Token, (AlexState HlState, AlexInput))
alexScanToken (AlexState state lookedOfs pos, inp@(_prevCh,_bs,str)) =
    let (scn,lookahead) = alexScanUser' state inp (stateToInit state)
        lookedOfs' = max lookedOfs (posnOfs pos +~ Size lookahead) in
    case scn of
      AlexEOF -> Nothing
      AlexError inp' -> Nothing
      AlexSkip  inp' len  ->
        let chunk = take (fromIntegral len) str
        in alexScanToken (AlexState state lookedOfs' (moveStr pos chunk), inp')
      AlexToken inp' len act ->
        let (state', tokValue) = act chunk state
            chunk = take (fromIntegral len) str
            newPos = moveStr pos chunk
        in Just (Tok tokValue (posnOfs newPos ~- posnOfs pos) pos, (AlexState state' lookedOfs' newPos, inp'))

alexScan' input (I# (sc))
  = alexScanUser' undefined input (I# (sc))

alexScanUser' user input (I# (sc))
  = case alex_scan_tkn' user input 0# input sc AlexNone of
      (AlexNone, input', lookahead) ->
        case alexGetByte input of
          Nothing -> (AlexEOF, lookahead)
          Just _  -> (AlexError input', lookahead)
      (AlexLastSkip input'' len, _, lookahead) -> (AlexSkip input'' len, lookahead)
#if MIN_TOOL_VERSION_alex(3,2,0)
      (AlexLastAcc k input'' len, _, lookahead) -> (AlexToken input'' len (alex_actions Data.Array.! k), lookahead)
#else
      (AlexLastAcc k input'' len, _, lookahead) -> (AlexToken input'' len k, lookahead)
#endif


-- Same as alex_scan_tkn, but also return the length of lookahead.
alex_scan_tkn' user orig_input len input s last_acc =
  input `seq` -- strict in the input
  let new_acc = check_accs (alex_accept `quickIndex` IBOX(s)) in
  new_acc `seq`
  case alexGetByte input of
     Nothing -> (new_acc, input, IBOX(len))
     Just (c, new_input) ->
      let base       = alexIndexInt32OffAddr alex_base s
          ord_c = case fromIntegral c of (I# x) -> x
          offset     = (base +# ord_c)
          check      = alexIndexInt16OffAddr alex_check offset

          new_s      = if GEQ_(offset, 0#) && EQ_(check, ord_c)
                       then alexIndexInt16OffAddr alex_table offset
                       else alexIndexInt16OffAddr alex_deflt s
          new_len    = if c < 0x80 || c >= 0xC0 then len +# 1# else len
      in case new_s of
          -1# -> (new_acc, input, IBOX(new_len))
          -- on an error, we want to keep the input *before* the
          -- character that failed, not after.
          -- (but still, we looked after)
          _ -> alex_scan_tkn' user orig_input new_len new_input new_s new_acc

  where
    check_accs (AlexAccNone) = last_acc
    check_accs (AlexAcc a  ) = AlexLastAcc a input IBOX(len)
    check_accs (AlexAccSkip) = AlexLastSkip  input IBOX(len)
#ifndef NO_ALEX_CONTEXTS
    check_accs (AlexAccPred a predx rest)
       | predx user orig_input IBOX(len) input
       = AlexLastAcc a input IBOX(len)
       | otherwise
       = check_accs rest
    check_accs (AlexAccSkipPred predx rest)
       | predx user orig_input IBOX(len) input
       = AlexLastSkip input IBOX(len)
       | otherwise
       = check_accs rest
#endif


c = actionConst
m = actionAndModify
ms = actionStringAndModify
cs = actionStringConst
