Blame templates/GenericTemplate.hs

Packit 2cbdf3
-- -----------------------------------------------------------------------------
Packit 2cbdf3
-- ALEX TEMPLATE
Packit 2cbdf3
--
Packit 2cbdf3
-- This code is in the PUBLIC DOMAIN; you may copy it freely and use
Packit 2cbdf3
-- it for any purpose whatsoever.
Packit 2cbdf3
Packit 2cbdf3
-- -----------------------------------------------------------------------------
Packit 2cbdf3
-- INTERNALS and main scanner engine
Packit 2cbdf3
Packit 2cbdf3
#ifdef ALEX_GHC
Packit 2cbdf3
#undef __GLASGOW_HASKELL__
Packit 2cbdf3
#define ALEX_IF_GHC_GT_500 #if __GLASGOW_HASKELL__ > 500
Packit 2cbdf3
#define ALEX_IF_GHC_LT_503 #if __GLASGOW_HASKELL__ < 503
Packit 2cbdf3
#define ALEX_IF_GHC_GT_706 #if __GLASGOW_HASKELL__ > 706
Packit 2cbdf3
#define ALEX_ELIF_GHC_500 #elif __GLASGOW_HASKELL__ == 500
Packit 2cbdf3
#define ALEX_IF_BIGENDIAN #ifdef WORDS_BIGENDIAN
Packit 2cbdf3
#define ALEX_ELSE #else
Packit 2cbdf3
#define ALEX_ENDIF #endif
Packit 2cbdf3
#define ALEX_DEFINE #define
Packit 2cbdf3
#endif
Packit 2cbdf3
Packit 2cbdf3
#ifdef ALEX_GHC
Packit 2cbdf3
#define ILIT(n) n#
Packit 2cbdf3
#define IBOX(n) (I# (n))
Packit 2cbdf3
#define FAST_INT Int#
Packit 2cbdf3
-- Do not remove this comment. Required to fix CPP parsing when using GCC and a clang-compiled alex.
Packit 2cbdf3
ALEX_IF_GHC_GT_706
Packit 2cbdf3
ALEX_DEFINE GTE(n,m) (tagToEnum# (n >=# m))
Packit 2cbdf3
ALEX_DEFINE EQ(n,m) (tagToEnum# (n ==# m))
Packit 2cbdf3
ALEX_ELSE
Packit 2cbdf3
ALEX_DEFINE GTE(n,m) (n >=# m)
Packit 2cbdf3
ALEX_DEFINE EQ(n,m) (n ==# m)
Packit 2cbdf3
ALEX_ENDIF
Packit 2cbdf3
#define PLUS(n,m) (n +# m)
Packit 2cbdf3
#define MINUS(n,m) (n -# m)
Packit 2cbdf3
#define TIMES(n,m) (n *# m)
Packit 2cbdf3
#define NEGATE(n) (negateInt# (n))
Packit 2cbdf3
#define IF_GHC(x) (x)
Packit 2cbdf3
#else
Packit 2cbdf3
#define ILIT(n) (n)
Packit 2cbdf3
#define IBOX(n) (n)
Packit 2cbdf3
#define FAST_INT Int
Packit 2cbdf3
#define GTE(n,m) (n >= m)
Packit 2cbdf3
#define EQ(n,m) (n == m)
Packit 2cbdf3
#define PLUS(n,m) (n + m)
Packit 2cbdf3
#define MINUS(n,m) (n - m)
Packit 2cbdf3
#define TIMES(n,m) (n * m)
Packit 2cbdf3
#define NEGATE(n) (negate (n))
Packit 2cbdf3
#define IF_GHC(x)
Packit 2cbdf3
#endif
Packit 2cbdf3
Packit 2cbdf3
#ifdef ALEX_GHC
Packit 2cbdf3
data AlexAddr = AlexA# Addr#
Packit 2cbdf3
-- Do not remove this comment. Required to fix CPP parsing when using GCC and a clang-compiled alex.
Packit 2cbdf3
ALEX_IF_GHC_LT_503
Packit 2cbdf3
uncheckedShiftL# = shiftL#
Packit 2cbdf3
ALEX_ENDIF
Packit 2cbdf3
Packit 2cbdf3
{-# INLINE alexIndexInt16OffAddr #-}
Packit 2cbdf3
alexIndexInt16OffAddr (AlexA# arr) off =
Packit 2cbdf3
ALEX_IF_BIGENDIAN
Packit 2cbdf3
  narrow16Int# i
Packit 2cbdf3
  where
Packit 2cbdf3
        i    = word2Int# ((high `uncheckedShiftL#` 8#) `or#` low)
Packit 2cbdf3
        high = int2Word# (ord# (indexCharOffAddr# arr (off' +# 1#)))
Packit 2cbdf3
        low  = int2Word# (ord# (indexCharOffAddr# arr off'))
Packit 2cbdf3
        off' = off *# 2#
Packit 2cbdf3
ALEX_ELSE
Packit 2cbdf3
  indexInt16OffAddr# arr off
Packit 2cbdf3
ALEX_ENDIF
Packit 2cbdf3
#else
Packit 2cbdf3
alexIndexInt16OffAddr arr off = arr ! off
Packit 2cbdf3
#endif
Packit 2cbdf3
Packit 2cbdf3
#ifdef ALEX_GHC
Packit 2cbdf3
{-# INLINE alexIndexInt32OffAddr #-}
Packit 2cbdf3
alexIndexInt32OffAddr (AlexA# arr) off =
Packit 2cbdf3
ALEX_IF_BIGENDIAN
Packit 2cbdf3
  narrow32Int# i
Packit 2cbdf3
  where
Packit 2cbdf3
   i    = word2Int# ((b3 `uncheckedShiftL#` 24#) `or#`
Packit 2cbdf3
                     (b2 `uncheckedShiftL#` 16#) `or#`
Packit 2cbdf3
                     (b1 `uncheckedShiftL#` 8#) `or#` b0)
Packit 2cbdf3
   b3   = int2Word# (ord# (indexCharOffAddr# arr (off' +# 3#)))
Packit 2cbdf3
   b2   = int2Word# (ord# (indexCharOffAddr# arr (off' +# 2#)))
Packit 2cbdf3
   b1   = int2Word# (ord# (indexCharOffAddr# arr (off' +# 1#)))
Packit 2cbdf3
   b0   = int2Word# (ord# (indexCharOffAddr# arr off'))
Packit 2cbdf3
   off' = off *# 4#
Packit 2cbdf3
ALEX_ELSE
Packit 2cbdf3
  indexInt32OffAddr# arr off
Packit 2cbdf3
ALEX_ENDIF
Packit 2cbdf3
#else
Packit 2cbdf3
alexIndexInt32OffAddr arr off = arr ! off
Packit 2cbdf3
#endif
Packit 2cbdf3
Packit 2cbdf3
#ifdef ALEX_GHC
Packit 2cbdf3
Packit 2cbdf3
ALEX_IF_GHC_LT_503
Packit 2cbdf3
quickIndex arr i = arr ! i
Packit 2cbdf3
ALEX_ELSE
Packit 2cbdf3
-- GHC >= 503, unsafeAt is available from Data.Array.Base.
Packit 2cbdf3
quickIndex = unsafeAt
Packit 2cbdf3
ALEX_ENDIF
Packit 2cbdf3
#else
Packit 2cbdf3
quickIndex arr i = arr ! i
Packit 2cbdf3
#endif
Packit 2cbdf3
Packit 2cbdf3
-- -----------------------------------------------------------------------------
Packit 2cbdf3
-- Main lexing routines
Packit 2cbdf3
Packit 2cbdf3
data AlexReturn a
Packit 2cbdf3
  = AlexEOF
Packit 2cbdf3
  | AlexError  !AlexInput
Packit 2cbdf3
  | AlexSkip   !AlexInput !Int
Packit 2cbdf3
  | AlexToken  !AlexInput !Int a
Packit 2cbdf3
Packit 2cbdf3
-- alexScan :: AlexInput -> StartCode -> AlexReturn a
Packit 2cbdf3
alexScan input__ IBOX(sc)
Packit 2cbdf3
  = alexScanUser undefined input__ IBOX(sc)
Packit 2cbdf3
Packit 2cbdf3
alexScanUser user__ input__ IBOX(sc)
Packit 2cbdf3
  = case alex_scan_tkn user__ input__ ILIT(0) input__ sc AlexNone of
Packit 2cbdf3
  (AlexNone, input__') ->
Packit 2cbdf3
    case alexGetByte input__ of
Packit 2cbdf3
      Nothing ->
Packit 2cbdf3
#ifdef ALEX_DEBUG
Packit 2cbdf3
                                   trace ("End of input.") $
Packit 2cbdf3
#endif
Packit 2cbdf3
                                   AlexEOF
Packit 2cbdf3
      Just _ ->
Packit 2cbdf3
#ifdef ALEX_DEBUG
Packit 2cbdf3
                                   trace ("Error.") $
Packit 2cbdf3
#endif
Packit 2cbdf3
                                   AlexError input__'
Packit 2cbdf3
Packit 2cbdf3
  (AlexLastSkip input__'' len, _) ->
Packit 2cbdf3
#ifdef ALEX_DEBUG
Packit 2cbdf3
    trace ("Skipping.") $
Packit 2cbdf3
#endif
Packit 2cbdf3
    AlexSkip input__'' len
Packit 2cbdf3
Packit 2cbdf3
  (AlexLastAcc k input__''' len, _) ->
Packit 2cbdf3
#ifdef ALEX_DEBUG
Packit 2cbdf3
    trace ("Accept.") $
Packit 2cbdf3
#endif
Packit 2cbdf3
    AlexToken input__''' len (alex_actions ! k)
Packit 2cbdf3
Packit 2cbdf3
Packit 2cbdf3
-- Push the input through the DFA, remembering the most recent accepting
Packit 2cbdf3
-- state it encountered.
Packit 2cbdf3
Packit 2cbdf3
alex_scan_tkn user__ orig_input len input__ s last_acc =
Packit 2cbdf3
  input__ `seq` -- strict in the input
Packit 2cbdf3
  let
Packit 2cbdf3
  new_acc = (check_accs (alex_accept `quickIndex` IBOX(s)))
Packit 2cbdf3
  in
Packit 2cbdf3
  new_acc `seq`
Packit 2cbdf3
  case alexGetByte input__ of
Packit 2cbdf3
     Nothing -> (new_acc, input__)
Packit 2cbdf3
     Just (c, new_input) ->
Packit 2cbdf3
#ifdef ALEX_DEBUG
Packit 2cbdf3
      trace ("State: " ++ show IBOX(s) ++ ", char: " ++ show c) $
Packit 2cbdf3
#endif
Packit 2cbdf3
      case fromIntegral c of { IBOX(ord_c) ->
Packit 2cbdf3
        let
Packit 2cbdf3
                base   = alexIndexInt32OffAddr alex_base s
Packit 2cbdf3
                offset = PLUS(base,ord_c)
Packit 2cbdf3
                check  = alexIndexInt16OffAddr alex_check offset
Packit 2cbdf3
Packit 2cbdf3
                new_s = if GTE(offset,ILIT(0)) && EQ(check,ord_c)
Packit 2cbdf3
                          then alexIndexInt16OffAddr alex_table offset
Packit 2cbdf3
                          else alexIndexInt16OffAddr alex_deflt s
Packit 2cbdf3
        in
Packit 2cbdf3
        case new_s of
Packit 2cbdf3
            ILIT(-1) -> (new_acc, input__)
Packit 2cbdf3
                -- on an error, we want to keep the input *before* the
Packit 2cbdf3
                -- character that failed, not after.
Packit 2cbdf3
            _ -> alex_scan_tkn user__ orig_input (if c < 0x80 || c >= 0xC0 then PLUS(len,ILIT(1)) else len)
Packit 2cbdf3
                                                -- note that the length is increased ONLY if this is the 1st byte in a char encoding)
Packit 2cbdf3
                        new_input new_s new_acc
Packit 2cbdf3
      }
Packit 2cbdf3
  where
Packit 2cbdf3
        check_accs (AlexAccNone) = last_acc
Packit 2cbdf3
        check_accs (AlexAcc a  ) = AlexLastAcc a input__ IBOX(len)
Packit 2cbdf3
        check_accs (AlexAccSkip) = AlexLastSkip  input__ IBOX(len)
Packit 2cbdf3
#ifndef ALEX_NOPRED
Packit 2cbdf3
        check_accs (AlexAccPred a predx rest)
Packit 2cbdf3
           | predx user__ orig_input IBOX(len) input__
Packit 2cbdf3
           = AlexLastAcc a input__ IBOX(len)
Packit 2cbdf3
           | otherwise
Packit 2cbdf3
           = check_accs rest
Packit 2cbdf3
        check_accs (AlexAccSkipPred predx rest)
Packit 2cbdf3
           | predx user__ orig_input IBOX(len) input__
Packit 2cbdf3
           = AlexLastSkip input__ IBOX(len)
Packit 2cbdf3
           | otherwise
Packit 2cbdf3
           = check_accs rest
Packit 2cbdf3
#endif
Packit 2cbdf3
Packit 2cbdf3
data AlexLastAcc
Packit 2cbdf3
  = AlexNone
Packit 2cbdf3
  | AlexLastAcc !Int !AlexInput !Int
Packit 2cbdf3
  | AlexLastSkip     !AlexInput !Int
Packit 2cbdf3
Packit 2cbdf3
data AlexAcc user
Packit 2cbdf3
  = AlexAccNone
Packit 2cbdf3
  | AlexAcc Int
Packit 2cbdf3
  | AlexAccSkip
Packit 2cbdf3
#ifndef ALEX_NOPRED
Packit 2cbdf3
  | AlexAccPred Int (AlexAccPred user) (AlexAcc user)
Packit 2cbdf3
  | AlexAccSkipPred (AlexAccPred user) (AlexAcc user)
Packit 2cbdf3
Packit 2cbdf3
type AlexAccPred user = user -> AlexInput -> Int -> AlexInput -> Bool
Packit 2cbdf3
Packit 2cbdf3
-- -----------------------------------------------------------------------------
Packit 2cbdf3
-- Predicates on a rule
Packit 2cbdf3
Packit 2cbdf3
alexAndPred p1 p2 user__ in1 len in2
Packit 2cbdf3
  = p1 user__ in1 len in2 && p2 user__ in1 len in2
Packit 2cbdf3
Packit 2cbdf3
--alexPrevCharIsPred :: Char -> AlexAccPred _
Packit 2cbdf3
alexPrevCharIs c _ input__ _ _ = c == alexInputPrevChar input__
Packit 2cbdf3
Packit 2cbdf3
alexPrevCharMatches f _ input__ _ _ = f (alexInputPrevChar input__)
Packit 2cbdf3
Packit 2cbdf3
--alexPrevCharIsOneOfPred :: Array Char Bool -> AlexAccPred _
Packit 2cbdf3
alexPrevCharIsOneOf arr _ input__ _ _ = arr ! alexInputPrevChar input__
Packit 2cbdf3
Packit 2cbdf3
--alexRightContext :: Int -> AlexAccPred _
Packit 2cbdf3
alexRightContext IBOX(sc) user__ _ _ input__ =
Packit 2cbdf3
     case alex_scan_tkn user__ input__ ILIT(0) input__ sc AlexNone of
Packit 2cbdf3
          (AlexNone, _) -> False
Packit 2cbdf3
          _ -> True
Packit 2cbdf3
        -- TODO: there's no need to find the longest
Packit 2cbdf3
        -- match when checking the right context, just
Packit 2cbdf3
        -- the first match will do.
Packit 2cbdf3
#endif