2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 %************************************************************************
6 \section[SrcLoc]{The @SrcLoc@ type}
8 %************************************************************************
14 mkSrcLoc, isGoodSrcLoc, isWiredInLoc,
15 noSrcLoc, -- "I'm sorry, I haven't a clue"
18 importedSrcLoc, -- Unknown place in an interface
19 wiredInSrcLoc, -- Something wired into the compiler
20 generatedSrcLoc, -- Code generated within the compiler
22 srcLocFile, -- return the file name part
23 srcLocLine, -- return the line part
24 srcLocCol, -- return the column part
27 #include "HsVersions.h"
29 import Util ( thenCmp )
31 import FastString ( unpackFS )
35 import GLAEXTS ( (+#), quotInt# )
38 %************************************************************************
40 \subsection[SrcLoc-SrcLocations]{Source-location information}
42 %************************************************************************
44 We keep information about the {\em definition} point for each entity;
45 this is the obvious stuff:
48 = WiredInLoc -- Used exclusively for Ids and TyCons
49 -- that are totally wired in to the
50 -- compiler. That supports the
51 -- occasionally-useful predicate
54 | SrcLoc FastString -- A precise location (file name)
58 | UnhelpfulSrcLoc FastString -- Just a general indication
64 -- A precise source file span
65 | SrcSpan FastString -- file name
66 FastInt -- beginning line
67 FastInt -- beginning column
71 | UnhelpfulSrcSpan FastString -- Just a general indication
75 Note that an entity might be imported via more than one route, and
76 there could be more than one ``definition point'' --- in two or more
77 \tr{.hi} files. We deemed it probably-unworthwhile to cater for this
80 %************************************************************************
82 \subsection[SrcLoc-access-fns]{Access functions for names}
84 %************************************************************************
88 mkSrcLoc x line col = SrcLoc x (iUnbox line) (iUnbox col)
89 wiredInSrcLoc = WiredInLoc
90 noSrcLoc = UnhelpfulSrcLoc FSLIT("<No locn>")
91 importedSrcLoc = UnhelpfulSrcLoc FSLIT("<imported>")
92 generatedSrcLoc = UnhelpfulSrcLoc FSLIT("<compiler-generated-code>")
94 isGoodSrcLoc (SrcLoc _ _ _) = True
95 isGoodSrcLoc other = False
97 isWiredInLoc WiredInLoc = True
98 isWiredInLoc other = False
100 srcLocFile :: SrcLoc -> FastString
101 srcLocFile (SrcLoc fname _ _) = fname
103 srcLocLine :: SrcLoc -> Int
104 srcLocLine (SrcLoc _ l c) = iBox l
106 srcLocCol :: SrcLoc -> Int
107 srcLocCol (SrcLoc _ l c) = iBox c
109 advanceSrcLoc :: SrcLoc -> Char -> SrcLoc
110 advanceSrcLoc (SrcLoc f l c) '\t' = SrcLoc f l (tab c)
111 advanceSrcLoc (SrcLoc f l c) '\n' = SrcLoc f (l +# 1#) 0#
112 advanceSrcLoc (SrcLoc f l c) _ = SrcLoc f l (c +# 1#)
114 -- Advance to the next tab stop. Tabs are at column positions 0, 8, 16, etc.
115 tab :: FastInt -> FastInt
116 tab c = (c `quotInt#` 8# +# 1#) *# 8#
119 %************************************************************************
121 \subsection[SrcLoc-instances]{Instance declarations for various names}
123 %************************************************************************
126 -- SrcLoc is an instance of Ord so that we can sort error messages easily
127 instance Eq SrcLoc where
128 loc1 == loc2 = case loc1 `cmpSrcLoc` loc2 of
132 instance Ord SrcLoc where
135 cmpSrcLoc WiredInLoc WiredInLoc = EQ
136 cmpSrcLoc WiredInLoc other = LT
138 cmpSrcLoc (UnhelpfulSrcLoc s1) (UnhelpfulSrcLoc s2) = s1 `compare` s2
139 cmpSrcLoc (UnhelpfulSrcLoc s1) other = GT
141 cmpSrcLoc (SrcLoc _ _ _) WiredInLoc = GT
142 cmpSrcLoc (SrcLoc _ _ _) (UnhelpfulSrcLoc _) = LT
143 cmpSrcLoc (SrcLoc s1 l1 c1) (SrcLoc s2 l2 c2)
144 = (s1 `compare` s2) `thenCmp` (l1 `cmpline` l2) `thenCmp` (c1 `cmpline` c2)
146 l1 `cmpline` l2 | l1 <# l2 = LT
150 instance Outputable SrcLoc where
151 ppr (SrcLoc src_path src_line src_col)
152 = getPprStyle $ \ sty ->
153 if userStyle sty || debugStyle sty then
154 hcat [ ftext src_path, char ':',
156 {- TODO: char ':', int (iBox src_col) -}
159 hcat [text "{-# LINE ", int (iBox src_line), space,
160 char '\"', ftext src_path, text " #-}"]
162 src_file = unpackFS src_path -- Leave the directory prefix intact,
163 -- so emacs can find the file
165 ppr (UnhelpfulSrcLoc s) = ftext s
166 ppr WiredInLoc = ptext SLIT("<Wired in>")