[project @ 2000-08-04 09:02:56 by simonmar]
[ghc-hetmet.git] / ghc / driver / GetImports.hs
1 -----------------------------------------------------------------------------
2 -- $Id: GetImports.hs,v 1.1 2000/08/02 15:27:25 simonmar Exp $
3 --
4 -- Collect up the imports from a Haskell module.  This is approximate: we don't
5 -- parse the module, but we do eliminate comments and strings.
6 --
7 -- (c) The GHC Team 2000
8 --
9
10 module GetImports (Import(..), getImports) where
11
12 import List ( nub )
13 import Char ( isAlphaNum )
14
15 data Import 
16    = Normal String | Source String
17      deriving (Eq, Show)
18
19 getImports :: String -> [Import]
20 getImports = nub . gmiBase . clean
21
22 -- really get the imports from a de-litted, cpp'd, de-literal'd string
23 gmiBase :: String -> [Import]
24 gmiBase s
25    = f (words s)
26      where
27         f ("foreign" : "import" : ws) = f ws
28         f ("import" : "{-#" : "SOURCE" : "#-}" : "qualified" : m : ws) 
29            = Source (takeWhile isModId m) : f ws
30         f ("import" : "{-#" : "SOURCE" : "#-}" : m : ws) 
31            = Source (takeWhile isModId m) : f ws
32         f ("import" : "qualified" : m : ws) 
33            = Normal (takeWhile isModId m) : f ws
34         f ("import" : m : ws) 
35            = Normal (takeWhile isModId m) : f ws
36         f (w:ws) = f ws
37         f [] = []
38
39 isModId c = isAlphaNum c || c `elem` "'_"
40
41 -- remove literals and comments from a string
42 clean :: String -> String
43 clean s
44    = keep s
45      where
46         -- running through text we want to keep
47         keep []                   = []
48         keep ('"':cs)             = dquote cs
49                 -- try to eliminate single quotes when they're part of
50                 -- an identifier...
51         keep (c:'\'':cs) | isAlphaNum c || c == '_' = keep (dropWhile (=='\'') cs)
52         keep ('\'':cs)            = squote cs
53         keep ('-':'-':cs)         = linecomment cs
54         keep ('{':'-':'#':' ':cs) = "{-# " ++ keep cs
55         keep ('{':'-':cs)         = runcomment cs
56         keep (c:cs)               = c : keep cs
57
58         -- in a double-quoted string
59         dquote []             = []
60         dquote ('\\':'\"':cs) = dquote cs
61         dquote ('\\':'\\':cs) = dquote cs
62         dquote ('\"':cs)      = keep cs
63         dquote (c:cs)         = dquote cs
64
65         -- in a single-quoted string
66         squote []             = []
67         squote ('\\':'\'':cs) = squote cs
68         squote ('\\':'\\':cs) = squote cs
69         squote ('\'':cs)      = keep cs
70         squote (c:cs)         = squote cs
71
72         -- in a line comment
73         linecomment []        = []
74         linecomment ('\n':cs) = '\n':keep cs
75         linecomment (c:cs)    = linecomment cs
76
77         -- in a running comment
78         runcomment []           = []
79         runcomment ('-':'}':cs) = keep cs
80         runcomment (c:cs)       = runcomment cs