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