never executed always true always false
    1 -- Copyright (C) 2018-2024 Jun Zhang <zhangjunphy[at]gmail[dot]com>
    2 --
    3 -- This file is a part of decafc.
    4 --
    5 -- decafc is free software: you can redistribute it and/or modify it under the
    6 -- terms of the MIT (X11) License as described in the LICENSE file.
    7 --
    8 -- decafc is distributed in the hope that it will be useful, but WITHOUT ANY
    9 -- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   10 -- FOR A PARTICULAR PURPOSE.  See the X11 license for more details.
   11 
   12 -- Lexer entry point
   13 module Lexer
   14   ( Token (..),
   15     Alex (..),
   16     AlexState (..),
   17     AlexUserState(..),
   18     scan,
   19     alexMonadScan,
   20     runAlex,
   21     addError,
   22     alexError,
   23     getAlexState
   24   )
   25 where
   26 
   27 import Data.ByteString.Lazy (ByteString)
   28 import Lexer.Lex
   29 import Lexer.Token
   30 import Util.SourceLoc qualified as SL
   31 import Types (CompileError(..))
   32 import Data.Text qualified as Text
   33 
   34 -- Produce error tokens for later use
   35 catchErrors :: SL.Located Token -> Alex ()
   36 catchErrors tok = do
   37   s <- getAlexState
   38   case tok of 
   39     t@(SL.LocatedAt _ EOF) -> eofCheck s t
   40     t -> return ()
   41   where
   42     eofCheck s@AlexState {alex_ust = ust} tok@(SL.LocatedAt loc _) =
   43       case ust of
   44         val
   45           | lexerStringState ust -> addError $ CompileError (Just loc) "String not closed at EOF"
   46           | lexerCharState ust -> addError $ CompileError (Just loc) "Char not closed at EOF"
   47           | lexerCommentDepth ust > 0 -> addError $ CompileError (Just loc) "Comment not closed at EOF"
   48           | otherwise -> return ()
   49 
   50 scan :: ByteString -> Either [CompileError] [SL.Located Token]
   51 scan str =
   52   let loop = do
   53         tok'@(SL.LocatedAt _ tok) <- alexMonadScan
   54         catchErrors tok'
   55         if tok == EOF
   56           then return []
   57           else do
   58             toks <- loop
   59             return (tok' : toks)
   60       tokenAndErrors = loop >>= \tokens -> do
   61         state <- getAlexState
   62         let errs = errors $ alex_ust state
   63         return (errs, tokens)
   64    in case runAlex str tokenAndErrors of
   65         Left m -> Left [CompileError Nothing $ Text.pack m]
   66         Right (errs, _) | not $ null errs -> Left errs
   67         Right (_, toks) -> Right toks