[project @ 2001-09-20 13:32:15 by simonmar]
[ghc-hetmet.git] / ghc / compiler / parser / Lex.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
3 %
4 \section[Lexical analysis]{Lexical analysis}
5
6 --------------------------------------------------------
7 [Jan 98]
8 There's a known bug in here:
9
10         If an interface file ends prematurely, Lex tries to
11         do headFS of an empty FastString.
12
13 An example that provokes the error is
14
15         f _:_ _forall_ [a] <<<END OF FILE>>>
16 --------------------------------------------------------
17
18 \begin{code}
19
20 module Lex (
21
22         ifaceParseErr, srcParseErr,
23
24         -- Monad for parser
25         Token(..), lexer, ParseResult(..), PState(..),
26         checkVersion, 
27         StringBuffer,
28
29         P, thenP, thenP_, returnP, mapP, failP, failMsgP,
30         getSrcLocP, setSrcLocP, getSrcFile,
31         layoutOn, layoutOff, pushContext, popContext
32     ) where
33
34 #include "HsVersions.h"
35
36 import Char             ( isSpace, toUpper )
37 import List             ( isSuffixOf )
38
39 import IdInfo           ( InlinePragInfo(..) )
40 import PrelNames        ( mkTupNameStr )
41 import CmdLineOpts      ( opt_HiVersion, opt_NoHiCheck )
42 import ForeignCall      ( Safety(..) )
43 import NewDemand        ( StrictSig(..), Demand(..), Keepity(..), 
44                           DmdResult(..), mkTopDmdType )
45 import UniqFM           ( listToUFM, lookupUFM )
46 import BasicTypes       ( Boxity(..) )
47 import SrcLoc           ( SrcLoc, incSrcLine, srcLocFile, srcLocLine,
48                           replaceSrcLine, mkSrcLoc )
49
50 import ErrUtils         ( Message )
51 import Outputable
52
53 import FastString
54 import StringBuffer
55 import GlaExts
56 import Ctype
57 import Char             ( chr, ord )
58 import PrelRead         ( readRational__ ) -- Glasgow non-std
59 \end{code}
60
61 %************************************************************************
62 %*                                                                      *
63 \subsection{Data types}
64 %*                                                                      *
65 %************************************************************************
66
67 The token data type, fairly un-interesting except from one
68 constructor, @ITidinfo@, which is used to lazily lex id info (arity,
69 strictness, unfolding etc).
70
71 The Idea/Observation here is that the renamer needs to scan through
72 all of an interface file before it can continue. But only a fraction
73 of the information contained in the file turns out to be useful, so
74 delaying as much as possible of the scanning and parsing of an
75 interface file Makes Sense (Heap profiles of the compiler 
76 show a reduction in heap usage by at least a factor of two,
77 post-renamer). 
78
79 Hence, the interface file lexer spots when value declarations are
80 being scanned and return the @ITidinfo@ and @ITtype@ constructors
81 for the type and any other id info for that binding (unfolding, strictness
82 etc). These constructors are applied to the result of lexing these sub-chunks.
83
84 The lexing of the type and id info is all done lazily, of course, so
85 the scanning (and subsequent parsing) will be done *only* on the ids the
86 renamer finds out that it is interested in. The rest will just be junked.
87 Laziness, you know it makes sense :-)
88
89 \begin{code}
90 data Token
91   = ITas                        -- Haskell keywords
92   | ITcase
93   | ITclass
94   | ITdata
95   | ITdefault
96   | ITderiving
97   | ITdo
98   | ITelse
99   | IThiding
100   | ITif
101   | ITimport
102   | ITin
103   | ITinfix
104   | ITinfixl
105   | ITinfixr
106   | ITinstance
107   | ITlet
108   | ITmodule
109   | ITnewtype
110   | ITof
111   | ITqualified
112   | ITthen
113   | ITtype
114   | ITwhere
115   | ITscc                       -- ToDo: remove (we use {-# SCC "..." #-} now)
116
117   | ITforall                    -- GHC extension keywords
118   | ITforeign
119   | ITexport
120   | ITlabel
121   | ITdynamic
122   | ITunsafe
123   | ITwith
124   | ITstdcallconv
125   | ITccallconv
126   | ITdotnet
127
128   | ITinterface                 -- interface keywords
129   | IT__export
130   | ITdepends
131   | IT__forall
132   | ITletrec 
133   | ITcoerce
134   | ITinlineMe
135   | ITinlineCall
136   | ITccall (Bool,Bool,Safety)  -- (is_dyn, is_casm, may_gc)
137   | ITdefaultbranch
138   | ITbottom
139   | ITinteger_lit 
140   | ITfloat_lit
141   | ITword_lit
142   | ITword64_lit
143   | ITint64_lit
144   | ITrational_lit
145   | ITaddr_lit
146   | ITlabel_lit
147   | ITlit_lit
148   | ITstring_lit
149   | ITtypeapp
150   | ITusage
151   | ITfuall
152   | ITarity 
153   | ITspecialise
154   | ITnocaf
155   | ITunfold InlinePragInfo
156   | ITstrict StrictSig
157   | ITrules
158   | ITcprinfo
159   | ITdeprecated
160   | IT__scc
161   | ITsccAllCafs
162
163   | ITspecialise_prag           -- Pragmas
164   | ITsource_prag
165   | ITinline_prag
166   | ITnoinline_prag
167   | ITrules_prag
168   | ITdeprecated_prag
169   | ITline_prag
170   | ITscc_prag
171   | ITclose_prag
172
173   | ITdotdot                    -- reserved symbols
174   | ITdcolon
175   | ITequal
176   | ITlam
177   | ITvbar
178   | ITlarrow
179   | ITrarrow
180   | ITat
181   | ITtilde
182   | ITdarrow
183   | ITminus
184   | ITbang
185   | ITdot
186
187   | ITbiglam                    -- GHC-extension symbols
188
189   | ITocurly                    -- special symbols
190   | ITccurly
191   | ITocurlybar                 -- {|, for type applications
192   | ITccurlybar                 -- |}, for type applications
193   | ITvccurly
194   | ITobrack
195   | ITcbrack
196   | IToparen
197   | ITcparen
198   | IToubxparen
199   | ITcubxparen
200   | ITsemi
201   | ITcomma
202   | ITunderscore
203   | ITbackquote
204
205   | ITvarid   FAST_STRING       -- identifiers
206   | ITconid   FAST_STRING
207   | ITvarsym  FAST_STRING
208   | ITconsym  FAST_STRING
209   | ITqvarid  (FAST_STRING,FAST_STRING)
210   | ITqconid  (FAST_STRING,FAST_STRING)
211   | ITqvarsym (FAST_STRING,FAST_STRING)
212   | ITqconsym (FAST_STRING,FAST_STRING)
213
214   | ITipvarid FAST_STRING       -- GHC extension: implicit param: ?x
215
216   | ITpragma StringBuffer
217
218   | ITchar       Int
219   | ITstring     FAST_STRING
220   | ITinteger    Integer
221   | ITrational   Rational
222
223   | ITprimchar   Int
224   | ITprimstring FAST_STRING
225   | ITprimint    Integer
226   | ITprimfloat  Rational
227   | ITprimdouble Rational
228   | ITlitlit     FAST_STRING
229
230   | ITunknown String            -- Used when the lexer can't make sense of it
231   | ITeof                       -- end of file token
232   deriving Show -- debugging
233 \end{code}
234
235 -----------------------------------------------------------------------------
236 Keyword Lists
237
238 \begin{code}
239 pragmaKeywordsFM = listToUFM $
240       map (\ (x,y) -> (_PK_ x,y))
241        [( "SPECIALISE", ITspecialise_prag ),
242         ( "SPECIALIZE", ITspecialise_prag ),
243         ( "SOURCE",     ITsource_prag ),
244         ( "INLINE",     ITinline_prag ),
245         ( "NOINLINE",   ITnoinline_prag ),
246         ( "NOTINLINE",  ITnoinline_prag ),
247         ( "LINE",       ITline_prag ),
248         ( "RULES",      ITrules_prag ),
249         ( "RULEZ",      ITrules_prag ), -- american spelling :-)
250         ( "SCC",        ITscc_prag ),
251         ( "DEPRECATED", ITdeprecated_prag )
252         ]
253
254 haskellKeywordsFM = listToUFM $
255       map (\ (x,y) -> (_PK_ x,y))
256        [( "_",          ITunderscore ),
257         ( "as",         ITas ),
258         ( "case",       ITcase ),     
259         ( "class",      ITclass ),    
260         ( "data",       ITdata ),     
261         ( "default",    ITdefault ),  
262         ( "deriving",   ITderiving ), 
263         ( "do",         ITdo ),       
264         ( "else",       ITelse ),     
265         ( "hiding",     IThiding ),
266         ( "if",         ITif ),       
267         ( "import",     ITimport ),   
268         ( "in",         ITin ),       
269         ( "infix",      ITinfix ),    
270         ( "infixl",     ITinfixl ),   
271         ( "infixr",     ITinfixr ),   
272         ( "instance",   ITinstance ), 
273         ( "let",        ITlet ),      
274         ( "module",     ITmodule ),   
275         ( "newtype",    ITnewtype ),  
276         ( "of",         ITof ),       
277         ( "qualified",  ITqualified ),
278         ( "then",       ITthen ),     
279         ( "type",       ITtype ),     
280         ( "where",      ITwhere ),
281         ( "_scc_",      ITscc )         -- ToDo: remove
282      ]
283
284 isSpecial :: Token -> Bool
285 -- If we see M.x, where x is a keyword, but
286 -- is special, we treat is as just plain M.x, 
287 -- not as a keyword.
288 isSpecial ITas          = True
289 isSpecial IThiding      = True
290 isSpecial ITqualified   = True
291 isSpecial ITforall      = True
292 isSpecial ITexport      = True
293 isSpecial ITlabel       = True
294 isSpecial ITdynamic     = True
295 isSpecial ITunsafe      = True
296 isSpecial ITwith        = True
297 isSpecial ITccallconv   = True
298 isSpecial ITstdcallconv = True
299 isSpecial _             = False
300
301 -- IMPORTANT: Keep this in synch with ParseIface.y's var_fs production! (SUP)
302 ghcExtensionKeywordsFM = listToUFM $
303         map (\ (x,y) -> (_PK_ x,y))
304      [  ( "forall",     ITforall ),
305         ( "foreign",    ITforeign ),
306         ( "export",     ITexport ),
307         ( "label",      ITlabel ),
308         ( "dynamic",    ITdynamic ),
309         ( "unsafe",     ITunsafe ),
310         ( "with",       ITwith ),
311         ( "stdcall",    ITstdcallconv),
312         ( "ccall",      ITccallconv),
313         ( "dotnet",     ITdotnet),
314         ("_ccall_",     ITccall (False, False, PlayRisky)),
315         ("_ccall_GC_",  ITccall (False, False, PlaySafe)),
316         ("_casm_",      ITccall (False, True,  PlayRisky)),
317         ("_casm_GC_",   ITccall (False, True,  PlaySafe)),
318
319         -- interface keywords
320         ("__interface",         ITinterface),
321         ("__export",            IT__export),
322         ("__depends",           ITdepends),
323         ("__forall",            IT__forall),
324         ("__letrec",            ITletrec),
325         ("__coerce",            ITcoerce),
326         ("__inline_me",         ITinlineMe),
327         ("__inline_call",       ITinlineCall),
328         ("__depends",           ITdepends),
329         ("__DEFAULT",           ITdefaultbranch),
330         ("__bot",               ITbottom),
331         ("__integer",           ITinteger_lit),
332         ("__float",             ITfloat_lit),
333         ("__int64",             ITint64_lit),
334         ("__word",              ITword_lit),
335         ("__word64",            ITword64_lit),
336         ("__rational",          ITrational_lit),
337         ("__addr",              ITaddr_lit),
338         ("__label",             ITlabel_lit),
339         ("__litlit",            ITlit_lit),
340         ("__string",            ITstring_lit),
341         ("__a",                 ITtypeapp),
342         ("__u",                 ITusage),
343         ("__fuall",             ITfuall),
344         ("__A",                 ITarity),
345         ("__P",                 ITspecialise),
346         ("__C",                 ITnocaf),
347         ("__R",                 ITrules),
348         ("__D",                 ITdeprecated),
349         ("__U",                 ITunfold NoInlinePragInfo),
350         
351         ("__ccall",             ITccall (False, False, PlayRisky)),
352         ("__ccall_GC",          ITccall (False, False, PlaySafe)),
353         ("__dyn_ccall",         ITccall (True,  False, PlayRisky)),
354         ("__dyn_ccall_GC",      ITccall (True,  False, PlaySafe)),
355         ("__casm",              ITccall (False, True,  PlayRisky)),
356         ("__dyn_casm",          ITccall (True,  True,  PlayRisky)),
357         ("__casm_GC",           ITccall (False, True,  PlaySafe)),
358         ("__dyn_casm_GC",       ITccall (True,  True,  PlaySafe)),
359
360         ("/\\",                 ITbiglam)
361      ]
362
363
364 haskellKeySymsFM = listToUFM $
365         map (\ (x,y) -> (_PK_ x,y))
366       [ ("..",          ITdotdot)
367        ,("::",          ITdcolon)
368        ,("=",           ITequal)
369        ,("\\",          ITlam)
370        ,("|",           ITvbar)
371        ,("<-",          ITlarrow)
372        ,("->",          ITrarrow)
373        ,("@",           ITat)
374        ,("~",           ITtilde)
375        ,("=>",          ITdarrow)
376        ,("-",           ITminus)
377        ,("!",           ITbang)
378        ,(".",           ITdot)          -- sadly, for 'forall a . t'
379        ]
380 \end{code}
381
382 -----------------------------------------------------------------------------
383 The lexical analyser
384
385 Lexer state:
386
387         - (glaexts) lexing an interface file or -fglasgow-exts
388         - (bol)   pointer to beginning of line (for column calculations)
389         - (buf)   pointer to beginning of token
390         - (buf)   pointer to current char
391         - (atbol) flag indicating whether we're at the beginning of a line
392
393 \begin{code}
394 lexer :: (Token -> P a) -> P a
395 lexer cont buf s@(PState{
396                     loc = loc,
397                     glasgow_exts = glaexts,
398                     bol = bol,
399                     atbol = atbol,
400                     context = ctx
401                 })
402
403         -- first, start a new lexeme and lose all the whitespace
404   =  _scc_ "Lexer" 
405   tab line bol atbol (stepOverLexeme buf)
406   where
407         line = srcLocLine loc
408
409         tab y bol atbol buf = -- trace ("tab: " ++ show (I# y) ++ " : " ++ show (currentChar buf)) $
410           case currentChar# buf of
411
412             '\NUL'# ->
413                    if bufferExhausted (stepOn buf)
414                         then cont ITeof buf s'
415                         else trace "lexer: misplaced NUL?" $ 
416                              tab y bol atbol (stepOn buf)
417
418             '\n'# -> let buf' = stepOn buf
419                      in tab (y +# 1#) (currentIndex# buf') 1# buf'
420
421                 -- find comments.  This got harder in Haskell 98.
422             '-'# ->  let trundle n = 
423                           let next = lookAhead# buf n in
424                           if next `eqChar#` '-'# then trundle (n +# 1#)
425                           else if is_symbol next || n <# 2#
426                                 then is_a_token
427                                 else tab y bol atbol 
428                                          (stepOnUntilChar# (stepOnBy# buf n) '\n'#)
429                     in trundle 1#
430
431                 -- comments and pragmas.  We deal with LINE pragmas here,
432                 -- and throw out any unrecognised pragmas as comments.  Any
433                 -- pragmas we know about are dealt with later (after any layout
434                 -- processing if necessary).
435             '{'# | lookAhead# buf 1# `eqChar#` '-'# ->
436                 if lookAhead# buf 2# `eqChar#` '#'# then
437                   if lookAhead# buf 3# `eqChar#` '#'# then is_a_token else
438                   case expandWhile# is_space (setCurrentPos# buf 3#) of { buf1->
439                   case expandWhile# is_ident (stepOverLexeme buf1)   of { buf2->
440                   let lexeme = mkFastString -- ToDo: too slow
441                                   (map toUpper (lexemeToString buf2)) in
442                   case lookupUFM pragmaKeywordsFM lexeme of
443                         -- ignore RULES pragmas when -fglasgow-exts is off
444                         Just ITrules_prag | not (flag glaexts) ->
445                            skip_to_end (stepOnBy# buf 2#) s'
446                         Just ITline_prag -> 
447                            line_prag skip_to_end buf2 s'
448                         Just other -> is_a_token
449                         Nothing -> skip_to_end (stepOnBy# buf 2#) s'
450                   }}
451
452                 else skip_to_end (stepOnBy# buf 2#) s'
453                 where
454                     skip_to_end = nested_comment (lexer cont)
455
456                 -- special GHC extension: we grok cpp-style #line pragmas
457             '#'# | lexemeIndex buf ==# bol ->   -- the '#' must be in column 0
458                 case expandWhile# is_space (stepOn buf) of { buf1 ->
459                 if is_digit (currentChar# buf1) 
460                         then line_prag next_line buf1 s'
461                         else is_a_token
462                 }
463                 where
464                 next_line buf = lexer cont (stepOnUntilChar# buf '\n'#)
465
466                 -- tabs have been expanded beforehand
467             c | is_space c -> tab y bol atbol (stepOn buf)
468               | otherwise  -> is_a_token
469
470            where s' = s{loc = replaceSrcLine loc y, 
471                         bol = bol,
472                        atbol = atbol}
473
474                  is_a_token | atbol /=# 0# = lexBOL cont buf s'
475                             | otherwise    = lexToken cont glaexts buf s'
476
477 -- {-# LINE .. #-} pragmas.  yeuch.
478 line_prag cont buf s@PState{loc=loc} =
479   case expandWhile# is_space buf                of { buf1 ->
480   case scanNumLit 0 (stepOverLexeme buf1)       of { (line,buf2) ->
481   -- subtract one: the line number refers to the *following* line.
482   let real_line = line - 1 in
483   case fromInteger real_line                    of { i@(I# l) -> 
484         -- ToDo, if no filename then we skip the newline.... d'oh
485   case expandWhile# is_space buf2               of { buf3 ->
486   case currentChar# buf3                        of
487      '\"'#{-"-} -> 
488         case untilEndOfString# (stepOn (stepOverLexeme buf3)) of { buf4 ->
489         let 
490             file = lexemeToFastString buf4 
491             new_buf = stepOn (stepOverLexeme buf4)
492         in
493         if nullFastString file
494                 then cont new_buf s{loc = replaceSrcLine loc l}
495                 else cont new_buf s{loc = mkSrcLoc file i}
496         }
497      _other -> cont (stepOverLexeme buf3) s{loc = replaceSrcLine loc l}
498   }}}}
499
500 nested_comment :: P a -> P a
501 nested_comment cont buf = loop buf
502  where
503    loop buf = 
504      case currentChar# buf of
505         '\NUL'# | bufferExhausted (stepOn buf) -> 
506                 lexError "unterminated `{-'" buf -- -}
507         '-'# | lookAhead# buf 1# `eqChar#` '}'# ->
508                 cont (stepOnBy# buf 2#)
509
510         '{'# | lookAhead# buf 1# `eqChar#` '-'# ->
511               nested_comment (nested_comment cont) (stepOnBy# buf 2#)
512
513         '\n'# -> \ s@PState{loc=loc} ->
514                  let buf' = stepOn buf in
515                  nested_comment cont buf'
516                         s{loc = incSrcLine loc, bol = currentIndex# buf',
517                           atbol = 1#}
518
519         _   -> nested_comment cont (stepOn buf)
520
521 -- When we are lexing the first token of a line, check whether we need to
522 -- insert virtual semicolons or close braces due to layout.
523
524 lexBOL :: (Token -> P a) -> P a
525 lexBOL cont buf s@(PState{
526                     loc = loc,
527                     glasgow_exts = glaexts,
528                     bol = bol,
529                     atbol = atbol,
530                     context = ctx
531                   }) =
532         if need_close_curly then 
533                 --trace ("col = " ++ show (I# col) ++ ", layout: inserting '}'") $
534                 cont ITvccurly buf s{atbol = 1#, context = tail ctx}
535         else if need_semi_colon then
536                 --trace ("col = " ++ show (I# col) ++ ", layout: inserting ';'") $
537                 cont ITsemi buf s{atbol = 0#}
538         else
539                 lexToken cont glaexts buf s{atbol = 0#}
540   where
541         col = currentIndex# buf -# bol
542
543         need_close_curly =
544                 case ctx of
545                         [] -> False
546                         (i:_) -> case i of
547                                     NoLayout -> False
548                                     Layout n -> col <# n
549         need_semi_colon =
550                 case ctx of
551                         [] -> False
552                         (i:_) -> case i of
553                                     NoLayout -> False
554                                     Layout n -> col ==# n
555
556
557 lexToken :: (Token -> P a) -> Int# -> P a
558 lexToken cont glaexts buf =
559  -- trace "lexToken" $
560   case currentChar# buf of
561
562     -- special symbols ----------------------------------------------------
563     '('# | flag glaexts && lookAhead# buf 1# `eqChar#` '#'# 
564                 -> cont IToubxparen (setCurrentPos# buf 2#)
565          | otherwise
566                 -> cont IToparen (incLexeme buf)
567
568     ')'# -> cont ITcparen    (incLexeme buf)
569     '['# -> cont ITobrack    (incLexeme buf)
570     ']'# -> cont ITcbrack    (incLexeme buf)
571     ','# -> cont ITcomma     (incLexeme buf)
572     ';'# -> cont ITsemi      (incLexeme buf)
573     '}'# -> \ s@PState{context = ctx} ->
574             case ctx of 
575                 (_:ctx') -> cont ITccurly (incLexeme buf) s{context=ctx'}
576                 _        -> lexError "too many '}'s" buf s
577     '|'# -> case lookAhead# buf 1# of
578                  '}'#  | flag glaexts -> cont ITccurlybar 
579                                               (setCurrentPos# buf 2#)
580                  _                    -> lex_sym cont (incLexeme buf)
581
582                 
583     '#'# -> case lookAhead# buf 1# of
584                 ')'#  | flag glaexts -> cont ITcubxparen (setCurrentPos# buf 2#)
585                 '-'# -> case lookAhead# buf 2# of
586                            '}'# -> cont ITclose_prag (setCurrentPos# buf 3#)
587                            _    -> lex_sym cont (incLexeme buf)
588                 _    -> lex_sym cont (incLexeme buf)
589
590     '`'# | flag glaexts && lookAhead# buf 1# `eqChar#` '`'#
591                 -> lex_cstring cont (setCurrentPos# buf 2#)
592          | otherwise
593                 -> cont ITbackquote (incLexeme buf)
594
595     '{'# ->     -- look for "{-##" special iface pragma
596             case lookAhead# buf 1# of
597            '|'# | flag glaexts 
598                 -> cont ITocurlybar (setCurrentPos# buf 2#)
599            '-'# -> case lookAhead# buf 2# of
600                     '#'# -> case lookAhead# buf 3# of
601                                 '#'# -> 
602                                    let (lexeme, buf') 
603                                           = doDiscard 0# (stepOnBy# (stepOverLexeme buf) 4#) in
604                                             cont (ITpragma lexeme) buf'
605                                 _ -> lex_prag cont (setCurrentPos# buf 3#)
606                     _    -> cont ITocurly (incLexeme buf) 
607            _ -> (layoutOff `thenP_` cont ITocurly)  (incLexeme buf) 
608
609     -- strings/characters -------------------------------------------------
610     '\"'#{-"-} -> lex_string cont glaexts [] (incLexeme buf)
611     '\''#      -> lex_char (char_end cont) glaexts (incLexeme buf)
612
613     -- strictness and cpr pragmas and __scc treated specially.
614     '_'# | flag glaexts ->
615          case lookAhead# buf 1# of
616            '_'# -> case lookAhead# buf 2# of
617                     'S'# -> 
618                         lex_demand cont (stepOnUntil (not . isSpace) 
619                                         (stepOnBy# buf 3#)) -- past __S
620                     'M'# -> 
621                         cont ITcprinfo (stepOnBy# buf 3#)       -- past __M
622
623                     's'# -> 
624                         case prefixMatch (stepOnBy# buf 3#) "cc" of
625                                Just buf' -> lex_scc cont (stepOverLexeme buf')
626                                Nothing   -> lex_id cont glaexts buf
627                     _ -> lex_id cont glaexts buf
628            _    -> lex_id cont glaexts buf
629
630         -- Hexadecimal and octal constants
631     '0'# | (ch `eqChar#` 'x'# || ch `eqChar#` 'X'#) && is_hexdigit ch2
632                 -> readNum (after_lexnum cont glaexts) buf' is_hexdigit 16 hex
633          | (ch `eqChar#` 'o'# || ch `eqChar#` 'O'#) && is_octdigit ch2
634                 -> readNum (after_lexnum cont glaexts) buf' is_octdigit  8 oct_or_dec
635         where ch   = lookAhead# buf 1#
636               ch2  = lookAhead# buf 2#
637               buf' = setCurrentPos# buf 2#
638
639     '\NUL'# ->
640             if bufferExhausted (stepOn buf) then
641                cont ITeof buf
642             else
643                trace "lexIface: misplaced NUL?" $ 
644                cont (ITunknown "\NUL") (stepOn buf)
645
646     '?'# | flag glaexts && is_lower (lookAhead# buf 1#) ->
647             lex_ip cont (incLexeme buf)
648     c | is_digit  c -> lex_num cont glaexts 0 buf
649       | is_symbol c -> lex_sym cont buf
650       | is_upper  c -> lex_con cont glaexts buf
651       | is_ident  c -> lex_id  cont glaexts buf
652       | otherwise   -> lexError "illegal character" buf
653
654 -- Int# is unlifted, and therefore faster than Bool for flags.
655 {-# INLINE flag #-}
656 flag :: Int# -> Bool
657 flag 0# = False
658 flag _  = True
659
660 -------------------------------------------------------------------------------
661 -- Pragmas
662
663 lex_prag cont buf
664   = case expandWhile# is_space buf of { buf1 ->
665     case expandWhile# is_ident (stepOverLexeme buf1) of { buf2 -> 
666     let lexeme = mkFastString (map toUpper (lexemeToString buf2)) in
667     case lookupUFM pragmaKeywordsFM lexeme of
668         Just kw -> cont kw (mergeLexemes buf buf2)
669         Nothing -> panic "lex_prag"
670   }}
671
672 -------------------------------------------------------------------------------
673 -- Strings & Chars
674
675 lex_string cont glaexts s buf
676   = case currentChar# buf of
677         '"'#{-"-} -> 
678            let buf' = incLexeme buf
679                s' = mkFastStringNarrow (map chr (reverse s)) 
680            in case currentChar# buf' of
681                 '#'# | flag glaexts -> if all (<= 0xFF) s
682                     then cont (ITprimstring s') (incLexeme buf')
683                     else lexError "primitive string literal must contain only characters <= \'\\xFF\'" buf'
684                 _                   -> cont (ITstring s') buf'
685
686         -- ignore \& in a string, deal with string gaps
687         '\\'# | next_ch `eqChar#` '&'# 
688                 -> lex_string cont glaexts s buf'
689               | is_space next_ch
690                 -> lex_stringgap cont glaexts s (incLexeme buf)
691
692             where next_ch = lookAhead# buf 1#
693                   buf' = setCurrentPos# buf 2#
694
695         _ -> lex_char (lex_next_string cont s) glaexts buf
696
697 lex_stringgap cont glaexts s buf
698   = let buf' = incLexeme buf in
699     case currentChar# buf of
700         '\n'# -> \st@PState{loc = loc} -> lex_stringgap cont glaexts s buf' 
701                   st{loc = incSrcLine loc}
702         '\\'# -> lex_string cont glaexts s buf'
703         c | is_space c -> lex_stringgap cont glaexts s buf'
704         other -> charError buf'
705
706 lex_next_string cont s glaexts c buf = lex_string cont glaexts (c:s) buf
707
708 lex_char :: (Int# -> Int -> P a) -> Int# -> P a
709 lex_char cont glaexts buf
710   = case currentChar# buf of
711         '\\'# -> lex_escape (cont glaexts) (incLexeme buf)
712         c | is_any c -> cont glaexts (I# (ord# c)) (incLexeme buf)
713         other -> charError buf
714
715 char_end cont glaexts c buf
716   = case currentChar# buf of
717         '\''# -> let buf' = incLexeme buf in
718                  case currentChar# buf' of
719                         '#'# | flag glaexts 
720                                 -> cont (ITprimchar c) (incLexeme buf')
721                         _       -> cont (ITchar c) buf'
722         _     -> charError buf
723
724 lex_escape cont buf
725   = let buf' = incLexeme buf in
726     case currentChar# buf of
727         'a'#       -> cont (ord '\a') buf'
728         'b'#       -> cont (ord '\b') buf'
729         'f'#       -> cont (ord '\f') buf'
730         'n'#       -> cont (ord '\n') buf'
731         'r'#       -> cont (ord '\r') buf'
732         't'#       -> cont (ord '\t') buf'
733         'v'#       -> cont (ord '\v') buf'
734         '\\'#      -> cont (ord '\\') buf'
735         '"'#       -> cont (ord '\"') buf'
736         '\''#      -> cont (ord '\'') buf'
737         '^'#       -> let c = currentChar# buf' in
738                       if c `geChar#` '@'# && c `leChar#` '_'#
739                         then cont (I# (ord# c -# ord# '@'#)) (incLexeme buf')
740                         else charError buf'
741
742         'x'#      -> readNum (after_charnum cont) buf' is_hexdigit 16 hex
743         'o'#      -> readNum (after_charnum cont) buf' is_octdigit  8 oct_or_dec
744         x | is_digit x 
745                   -> readNum (after_charnum cont) buf is_digit    10 oct_or_dec
746
747         _          -> case [ (c,buf2) | (p,c) <- silly_escape_chars,
748                                        Just buf2 <- [prefixMatch buf p] ] of
749                             (c,buf2):_ -> cont (ord c) buf2
750                             [] -> charError buf'
751
752 after_charnum cont i buf
753   = if i >= 0 && i <= 0x10FFFF
754         then cont (fromInteger i) buf
755         else charError buf
756
757 readNum cont buf is_digit base conv = read buf 0
758   where read buf i 
759           = case currentChar# buf of { c ->
760             if is_digit c
761                 then read (incLexeme buf) (i*base + (toInteger (I# (conv c))))
762                 else cont i buf
763             }
764
765 is_hexdigit c 
766         =  is_digit c 
767         || (c `geChar#` 'a'# && c `leChar#` 'f'#)
768         || (c `geChar#` 'A'# && c `leChar#` 'F'#)
769
770 hex c | is_digit c = ord# c -# ord# '0'#
771       | otherwise  = ord# (to_lower c) -# ord# 'a'# +# 10#
772 oct_or_dec c = ord# c -# ord# '0'#
773
774 is_octdigit c = c `geChar#` '0'# && c `leChar#` '7'#
775
776 to_lower c 
777   | c `geChar#` 'A'# && c `leChar#` 'Z'#  
778         = chr# (ord# c -# (ord# 'A'# -# ord# 'a'#))
779   | otherwise = c
780
781 charError buf = lexError "error in character literal" buf
782
783 silly_escape_chars = [
784         ("NUL", '\NUL'),
785         ("SOH", '\SOH'),
786         ("STX", '\STX'),
787         ("ETX", '\ETX'),
788         ("EOT", '\EOT'),
789         ("ENQ", '\ENQ'),
790         ("ACK", '\ACK'),
791         ("BEL", '\BEL'),
792         ("BS", '\BS'),
793         ("HT", '\HT'),
794         ("LF", '\LF'),
795         ("VT", '\VT'),
796         ("FF", '\FF'),
797         ("CR", '\CR'),
798         ("SO", '\SO'),
799         ("SI", '\SI'),
800         ("DLE", '\DLE'),
801         ("DC1", '\DC1'),
802         ("DC2", '\DC2'),
803         ("DC3", '\DC3'),
804         ("DC4", '\DC4'),
805         ("NAK", '\NAK'),
806         ("SYN", '\SYN'),
807         ("ETB", '\ETB'),
808         ("CAN", '\CAN'),
809         ("EM", '\EM'),
810         ("SUB", '\SUB'),
811         ("ESC", '\ESC'),
812         ("FS", '\FS'),
813         ("GS", '\GS'),
814         ("RS", '\RS'),
815         ("US", '\US'),
816         ("SP", '\SP'),
817         ("DEL", '\DEL')
818         ]
819
820 -------------------------------------------------------------------------------
821
822 lex_demand cont buf = 
823  case read_em [] buf of { (ls,buf') -> 
824  case currentChar# buf' of
825    'b'# -> cont (ITstrict (StrictSig (mkTopDmdType ls BotRes))) (incLexeme buf')
826    'm'# -> cont (ITstrict (StrictSig (mkTopDmdType ls RetCPR))) (incLexeme buf')
827    _    -> cont (ITstrict (StrictSig (mkTopDmdType ls TopRes))) buf'
828  }
829  where
830   read_em acc buf = 
831    case currentChar# buf of
832     'L'# -> read_em (Lazy : acc) (stepOn buf)
833     'A'# -> read_em (Abs : acc) (stepOn buf)
834     'V'# -> read_em (Eval : acc) (stepOn buf)
835     'X'# -> read_em (Err : acc) (stepOn buf)
836     'B'# -> read_em (Bot : acc) (stepOn buf)
837     ')'# -> (reverse acc, stepOn buf)
838     'C'# -> do_call acc (stepOnBy# buf 2#)
839     'D'# -> do_unpack1 Defer acc (stepOnBy# buf 1#)
840     'U'# -> do_unpack1 Drop acc (stepOnBy# buf 1#)
841     'S'# -> do_unpack1 Keep acc (stepOnBy# buf 1#)
842     _    -> (reverse acc, buf)
843
844   do_unpack1 keepity acc buf
845     = case currentChar# buf of
846         '('# -> do_unpack2 keepity acc (stepOnBy# buf 1#)
847         _    -> read_em (Seq keepity [] : acc) buf
848
849   do_unpack2 keepity acc buf
850     = case read_em [] buf of
851         (stuff, rest) -> read_em (Seq keepity stuff : acc) rest
852
853   do_call acc buf
854     = case read_em [] buf of
855         ([dmd], rest) -> read_em (Call dmd : acc) rest
856
857 ------------------
858 lex_scc cont buf =
859  case currentChar# buf of
860   'C'# -> cont ITsccAllCafs (incLexeme buf)
861   other -> cont ITscc buf
862
863 -----------------------------------------------------------------------------
864 -- Numbers
865
866 lex_num :: (Token -> P a) -> Int# -> Integer -> P a
867 lex_num cont glaexts acc buf =
868  case scanNumLit acc buf of
869      (acc',buf') ->
870        case currentChar# buf' of
871          '.'# | is_digit (lookAhead# buf' 1#) ->
872              -- this case is not optimised at all, as the
873              -- presence of floating point numbers in interface
874              -- files is not that common. (ToDo)
875             case expandWhile# is_digit (incLexeme buf') of
876               buf2 -> -- points to first non digit char
877
878                 let l = case currentChar# buf2 of
879                           'E'# -> do_exponent
880                           'e'# -> do_exponent
881                           _ -> buf2
882
883                     do_exponent 
884                         = let buf3 = incLexeme buf2 in
885                           case currentChar# buf3 of
886                                 '-'# -> expandWhile# is_digit (incLexeme buf3)
887                                 '+'# -> expandWhile# is_digit (incLexeme buf3)
888                                 x | is_digit x -> expandWhile# is_digit buf3
889                                 _ -> buf2
890
891                     v = readRational__ (lexemeToString l)
892
893                 in case currentChar# l of -- glasgow exts only
894                       '#'# | flag glaexts -> let l' = incLexeme l in
895                               case currentChar# l' of
896                                 '#'# -> cont (ITprimdouble v) (incLexeme l')
897                                 _    -> cont (ITprimfloat  v) l'
898                       _ -> cont (ITrational v) l
899
900          _ -> after_lexnum cont glaexts acc' buf'
901                 
902 after_lexnum cont glaexts i buf
903   = case currentChar# buf of
904         '#'# | flag glaexts -> cont (ITprimint i) (incLexeme buf)
905         _    -> cont (ITinteger i) buf
906
907 -----------------------------------------------------------------------------
908 -- C "literal literal"s  (i.e. things like ``NULL'', ``stdout'' etc.)
909
910 -- we lexemeToFastString on the bit between the ``''s, but include the
911 -- quotes in the full lexeme.
912
913 lex_cstring cont buf =
914  case expandUntilMatch (stepOverLexeme buf) "\'\'" of
915    Just buf' -> cont (ITlitlit (lexemeToFastString 
916                                 (setCurrentPos# buf' (negateInt# 2#))))
917                    (mergeLexemes buf buf')
918    Nothing   -> lexError "unterminated ``" buf
919
920 -----------------------------------------------------------------------------
921 -- identifiers, symbols etc.
922
923 lex_ip cont buf =
924  case expandWhile# is_ident buf of
925    buf' -> cont (ITipvarid lexeme) buf'
926            where lexeme = lexemeToFastString buf'
927
928 lex_id cont glaexts buf =
929  let buf1 = expandWhile# is_ident buf in
930  seq buf1 $
931
932  case (if flag glaexts 
933         then expandWhile# (eqChar# '#'#) buf1 -- slurp trailing hashes
934         else buf1)                              of { buf' ->
935
936  let lexeme  = lexemeToFastString buf' in
937
938  case _scc_ "Lex.haskellKeyword" lookupUFM haskellKeywordsFM lexeme of {
939         Just kwd_token -> --trace ("hkeywd: "++_UNPK_(lexeme)) $
940                           cont kwd_token buf';
941         Nothing        -> 
942
943  let var_token = cont (ITvarid lexeme) buf' in
944
945  if not (flag glaexts)
946    then var_token
947    else
948
949  case lookupUFM ghcExtensionKeywordsFM lexeme of {
950         Just kwd_token -> cont kwd_token buf';
951         Nothing        -> var_token
952
953  }}}
954
955 lex_sym cont buf =
956  -- trace "lex_sym" $
957  case expandWhile# is_symbol buf of
958    buf' -> case lookupUFM haskellKeySymsFM lexeme of {
959                 Just kwd_token -> --trace ("keysym: "++unpackFS lexeme) $
960                                   cont kwd_token buf' ;
961                 Nothing        -> --trace ("sym: "++unpackFS lexeme) $
962                                   cont (mk_var_token lexeme) buf'
963            }
964         where lexeme = lexemeToFastString buf'
965
966
967 -- lex_con recursively collects components of a qualified identifer.
968 -- The argument buf is the StringBuffer representing the lexeme
969 -- identified so far, where the next character is upper-case.
970
971 lex_con cont glaexts buf =
972  -- trace ("con: "{-++unpackFS lexeme-}) $
973  let empty_buf = stepOverLexeme buf in
974  case expandWhile# is_ident empty_buf    of { buf1 ->
975  case slurp_trailing_hashes buf1 glaexts of { con_buf ->
976
977  let all_buf = mergeLexemes buf con_buf
978      
979      con_lexeme = lexemeToFastString con_buf
980      mod_lexeme = lexemeToFastString (decLexeme buf)
981      all_lexeme = lexemeToFastString all_buf
982
983      just_a_conid
984         | emptyLexeme buf = cont (ITconid con_lexeme)               all_buf
985         | otherwise       = cont (ITqconid (mod_lexeme,con_lexeme)) all_buf
986  in
987
988  case currentChar# all_buf of
989      '.'# -> maybe_qualified cont glaexts all_lexeme 
990                 (incLexeme all_buf) just_a_conid
991      _    -> just_a_conid
992   }}
993
994
995 maybe_qualified cont glaexts mod buf just_a_conid =
996  -- trace ("qid: "{-++unpackFS lexeme-}) $
997  case currentChar# buf of
998   '['# ->       -- Special case for []
999     case lookAhead# buf 1# of
1000      ']'# -> cont (ITqconid  (mod,SLIT("[]"))) (setCurrentPos# buf 2#)
1001      _    -> just_a_conid
1002
1003   '('# ->  -- Special case for (,,,)
1004            -- This *is* necessary to deal with e.g. "instance C PrelBase.(,,)"
1005     case lookAhead# buf 1# of
1006      '#'# | flag glaexts -> case lookAhead# buf 2# of
1007                 ','# -> lex_ubx_tuple cont mod (setCurrentPos# buf 3#) 
1008                                 just_a_conid
1009                 _    -> just_a_conid
1010      ')'# -> cont (ITqconid (mod,SLIT("()"))) (setCurrentPos# buf 2#)
1011      ','# -> lex_tuple cont mod (setCurrentPos# buf 2#) just_a_conid
1012      _    -> just_a_conid
1013
1014   '-'# -> case lookAhead# buf 1# of
1015             '>'# -> cont (ITqconid (mod,SLIT("(->)"))) (setCurrentPos# buf 2#)
1016             _    -> lex_id3 cont glaexts mod buf just_a_conid
1017
1018   _    -> lex_id3 cont glaexts mod buf just_a_conid
1019
1020
1021 lex_id3 cont glaexts mod buf just_a_conid
1022   | is_upper (currentChar# buf) =
1023      lex_con cont glaexts buf
1024
1025   | is_symbol (currentChar# buf) =
1026      let 
1027         start_new_lexeme = stepOverLexeme buf
1028      in
1029      -- trace ("lex_id31 "{-++unpackFS lexeme-}) $
1030      case expandWhile# is_symbol start_new_lexeme of { buf' ->
1031      let
1032        lexeme  = lexemeToFastString buf'
1033         -- real lexeme is M.<sym>
1034        new_buf = mergeLexemes buf buf'
1035      in
1036      cont (mk_qvar_token mod lexeme) new_buf
1037         -- wrong, but arguably morally right: M... is now a qvarsym
1038      }
1039
1040   | otherwise   =
1041      let 
1042         start_new_lexeme = stepOverLexeme buf
1043      in
1044      -- trace ("lex_id32 "{-++unpackFS lexeme-}) $
1045      case expandWhile# is_ident start_new_lexeme of { buf1 ->
1046      if emptyLexeme buf1 
1047             then just_a_conid
1048             else
1049
1050      case slurp_trailing_hashes buf1 glaexts of { buf' ->
1051
1052      let
1053       lexeme      = lexemeToFastString buf'
1054       new_buf     = mergeLexemes buf buf'
1055       is_a_qvarid = cont (mk_qvar_token mod lexeme) new_buf
1056      in
1057      case _scc_ "Lex.haskellKeyword" lookupUFM haskellKeywordsFM lexeme of {
1058             Nothing          -> is_a_qvarid ;
1059
1060             Just kwd_token | isSpecial kwd_token   -- special ids (as, qualified, hiding) shouldn't be
1061                            -> is_a_qvarid          --  recognised as keywords here.
1062                            | otherwise
1063                            -> just_a_conid         -- avoid M.where etc.
1064      }}}
1065
1066 slurp_trailing_hashes buf glaexts
1067   | flag glaexts = expandWhile# (`eqChar#` '#'#) buf
1068   | otherwise    = buf
1069
1070
1071 mk_var_token pk_str
1072   | is_upper f          = ITconid pk_str
1073   | is_ident f          = ITvarid pk_str
1074   | f `eqChar#` ':'#    = ITconsym pk_str
1075   | otherwise           = ITvarsym pk_str
1076   where
1077       (C# f) = _HEAD_ pk_str
1078       -- tl     = _TAIL_ pk_str
1079
1080 mk_qvar_token m token =
1081 -- trace ("mk_qvar ") $ 
1082  case mk_var_token token of
1083    ITconid n  -> ITqconid  (m,n)
1084    ITvarid n  -> ITqvarid  (m,n)
1085    ITconsym n -> ITqconsym (m,n)
1086    ITvarsym n -> ITqvarsym (m,n)
1087    _          -> ITunknown (show token)
1088 \end{code}
1089
1090 ----------------------------------------------------------------------------
1091 Horrible stuff for dealing with M.(,,,)
1092
1093 \begin{code}
1094 lex_tuple cont mod buf back_off =
1095   go 2 buf
1096   where
1097    go n buf =
1098     case currentChar# buf of
1099       ','# -> go (n+1) (stepOn buf)
1100       ')'# -> cont (ITqconid (mod, snd (mkTupNameStr Boxed n))) (stepOn buf)
1101       _    -> back_off
1102
1103 lex_ubx_tuple cont mod buf back_off =
1104   go 2 buf
1105   where
1106    go n buf =
1107     case currentChar# buf of
1108       ','# -> go (n+1) (stepOn buf)
1109       '#'# -> case lookAhead# buf 1# of
1110                 ')'# -> cont (ITqconid (mod, snd (mkTupNameStr Unboxed n)))
1111                                  (stepOnBy# buf 2#)
1112                 _    -> back_off
1113       _    -> back_off
1114 \end{code}
1115
1116 -----------------------------------------------------------------------------
1117 doDiscard rips along really fast, looking for a '##-}', 
1118 indicating the end of the pragma we're skipping
1119
1120 \begin{code}
1121 doDiscard inStr buf =
1122  case currentChar# buf of
1123    '#'# | inStr ==# 0# ->
1124        case lookAhead# buf 1# of { '#'# -> 
1125        case lookAhead# buf 2# of { '-'# ->
1126        case lookAhead# buf 3# of { '}'# -> 
1127            (lexemeToBuffer buf, stepOverLexeme (setCurrentPos# buf 4#));
1128         _    -> doDiscard inStr (incLexeme buf) };
1129         _    -> doDiscard inStr (incLexeme buf) };
1130         _    -> doDiscard inStr (incLexeme buf) }
1131
1132    '"'# ->
1133        let
1134         odd_slashes buf flg i# =
1135           case lookAhead# buf i# of
1136            '\\'# -> odd_slashes buf (not flg) (i# -# 1#)
1137            _     -> flg
1138
1139         not_inStr = if inStr ==# 0# then 1# else 0#
1140        in
1141        case lookAhead# buf (negateInt# 1#) of --backwards, actually
1142          '\\'# -> -- escaping something..
1143            if odd_slashes buf True (negateInt# 2#) 
1144                 then  -- odd number of slashes, " is escaped.
1145                       doDiscard inStr (incLexeme buf)
1146                 else  -- even number of slashes, \ is escaped.
1147                       doDiscard not_inStr (incLexeme buf)
1148          _ -> doDiscard not_inStr (incLexeme buf)
1149
1150    '\''# | inStr ==# 0# ->
1151         case lookAhead# buf 1# of { '"'# ->
1152         case lookAhead# buf 2# of { '\''# ->
1153            doDiscard inStr (setCurrentPos# buf 3#);
1154         _ -> doDiscard inStr (incLexeme buf) };
1155         _ -> doDiscard inStr (incLexeme buf) }
1156
1157    _ -> doDiscard inStr (incLexeme buf)
1158
1159 \end{code}
1160
1161 -----------------------------------------------------------------------------
1162
1163 \begin{code}
1164 data LayoutContext
1165   = NoLayout
1166   | Layout Int#
1167
1168 data ParseResult a
1169   = POk PState a
1170   | PFailed Message
1171
1172 data PState = PState { 
1173         loc           :: SrcLoc,
1174         glasgow_exts  :: Int#,
1175         bol           :: Int#,
1176         atbol         :: Int#,
1177         context       :: [LayoutContext]
1178      }
1179
1180 type P a = StringBuffer         -- Input string
1181         -> PState
1182         -> ParseResult a
1183
1184 returnP   :: a -> P a
1185 returnP a buf s = POk s a
1186
1187 thenP      :: P a -> (a -> P b) -> P b
1188 m `thenP` k = \ buf s ->
1189         case m buf s of
1190                 POk s1 a -> k a buf s1
1191                 PFailed err  -> PFailed err
1192
1193 thenP_     :: P a -> P b -> P b
1194 m `thenP_` k = m `thenP` \_ -> k
1195
1196 mapP :: (a -> P b) -> [a] -> P [b]
1197 mapP f [] = returnP []
1198 mapP f (a:as) = 
1199      f a `thenP` \b ->
1200      mapP f as `thenP` \bs ->
1201      returnP (b:bs)
1202
1203 failP :: String -> P a
1204 failP msg buf s = PFailed (text msg)
1205
1206 failMsgP :: Message -> P a
1207 failMsgP msg buf s = PFailed msg
1208
1209 lexError :: String -> P a
1210 lexError str buf s@PState{ loc = loc } 
1211   = failMsgP (hcat [ppr loc, text ": ", text str]) buf s
1212
1213 getSrcLocP :: P SrcLoc
1214 getSrcLocP buf s@(PState{ loc = loc }) = POk s loc
1215
1216 -- use a temporary SrcLoc for the duration of the argument
1217 setSrcLocP :: SrcLoc -> P a -> P a
1218 setSrcLocP new_loc p buf s = 
1219   case p buf s{ loc=new_loc } of
1220       POk _ a   -> POk s a
1221       PFailed e -> PFailed e
1222   
1223 getSrcFile :: P FAST_STRING
1224 getSrcFile buf s@(PState{ loc = loc }) = POk s (srcLocFile loc)
1225
1226 pushContext :: LayoutContext -> P ()
1227 pushContext ctxt buf s@(PState{ context = ctx }) = POk s{context = ctxt:ctx} ()
1228
1229 {-
1230
1231 This special case in layoutOn is to handle layout contexts with are
1232 indented the same or less than the current context.  This is illegal
1233 according to the Haskell spec, so we have to arrange to close the
1234 current context.  eg.
1235
1236 class Foo a where
1237 class Bar a
1238
1239 after the first 'where', the sequence of events is:
1240
1241         - layout system inserts a ';' (column 0)
1242         - parser begins a new context at column 0
1243         - parser shifts ';' (legal empty declaration)
1244         - parser sees 'class': parse error (we're still in the inner context)
1245
1246 trouble is, by the time we know we need a new context, the lexer has
1247 already generated the ';'.  Hacky solution is as follows: since we
1248 know the column of the next token (it's the column number of the new
1249 context), we set the ACTUAL column number of the new context to this
1250 numer plus one.  Hence the next time the lexer is called, a '}' will
1251 be generated to close the new context straight away.  Furthermore, we
1252 have to set the atbol flag so that the ';' that the parser shifted as
1253 part of the new context is re-generated.
1254
1255 when the new context is *less* indented than the current one:
1256
1257 f = f where g = g where
1258 h = h
1259
1260         - current context: column 12.
1261         - on seeing 'h' (column 0), the layout system inserts '}'
1262         - parser starts a new context, column 0
1263         - parser sees '}', uses it to close new context
1264         - we still need to insert another '}' followed by a ';',
1265           hence the atbol trick.
1266
1267 There's also a special hack in here to deal with
1268
1269         do
1270            ....
1271            e $ do
1272            blah
1273
1274 i.e. the inner context is at the same indentation level as the outer
1275 context.  This is strictly illegal according to Haskell 98, but
1276 there's a lot of existing code using this style and it doesn't make
1277 any sense to disallow it, since empty 'do' lists don't make sense.
1278 -}
1279
1280 layoutOn :: Bool -> P ()
1281 layoutOn strict buf s@(PState{ bol = bol, context = ctx }) =
1282     let offset = lexemeIndex buf -# bol in
1283     case ctx of
1284         Layout prev_off : _ 
1285            | if strict then prev_off >=# offset else prev_off ># offset ->
1286                 --trace ("layout on, column: " ++  show (I# offset)) $
1287                 POk s{ context = Layout (offset +# 1#) : ctx, atbol = 1# } ()
1288         other -> 
1289                 --trace ("layout on, column: " ++  show (I# offset)) $
1290                 POk s{ context = Layout offset : ctx } ()
1291
1292 layoutOff :: P ()
1293 layoutOff buf s@(PState{ context = ctx }) =
1294     POk s{ context = NoLayout:ctx } ()
1295
1296 popContext :: P ()
1297 popContext = \ buf s@(PState{ context = ctx, loc = loc }) ->
1298   case ctx of
1299         (_:tl) -> POk s{ context = tl } ()
1300         []     -> PFailed (srcParseErr buf loc)
1301
1302 {- 
1303  Note that if the name of the file we're processing ends
1304  with `hi-boot', we accept it on faith as having the right
1305  version. This is done so that .hi-boot files that comes
1306  with hsc don't have to be updated before every release,
1307  *and* it allows us to share .hi-boot files with versions
1308  of hsc that don't have .hi version checking (e.g., ghc-2.10's)
1309
1310  If the version number is 0, the checking is also turned off.
1311  (needed to deal with GHC.hi only!)
1312
1313  Once we can assume we're compiling with a version of ghc that
1314  supports interface file checking, we can drop the special
1315  pleading
1316 -}
1317 checkVersion :: Maybe Integer -> P ()
1318 checkVersion mb@(Just v) buf s@(PState{loc = loc})
1319  | (v==0) || (v == fromInt opt_HiVersion) || opt_NoHiCheck = POk s ()
1320  | otherwise = PFailed (ifaceVersionErr mb loc ([]::[Token]){-Todo-})
1321 checkVersion mb@Nothing  buf s@(PState{loc = loc})
1322  | "hi-boot" `isSuffixOf` (_UNPK_ (srcLocFile loc)) = POk s ()
1323  | otherwise = PFailed (ifaceVersionErr mb loc ([]::[Token]){-Todo-})
1324
1325 -----------------------------------------------------------------
1326
1327 ifaceParseErr :: StringBuffer -> SrcLoc -> Message
1328 ifaceParseErr s l
1329   = hsep [ppr l, ptext SLIT("Interface file parse error; on input `"),
1330           text (lexemeToString s), char '\'']
1331
1332 ifaceVersionErr hi_vers l toks
1333   = hsep [ppr l, ptext SLIT("Interface file version error;"),
1334           ptext SLIT("Expected"), int opt_HiVersion, 
1335           ptext SLIT("found "), pp_version]
1336     where
1337      pp_version =
1338       case hi_vers of
1339         Nothing -> ptext SLIT("pre ghc-3.02 version")
1340         Just v  -> ptext SLIT("version") <+> integer v
1341
1342 -----------------------------------------------------------------------------
1343
1344 srcParseErr :: StringBuffer -> SrcLoc -> Message
1345 srcParseErr s l
1346   = hcat [ppr l, 
1347           if null token 
1348              then ptext SLIT(": parse error (possibly incorrect indentation)")
1349              else hcat [ptext SLIT(": parse error on input "),
1350                         char '`', text token, char '\'']
1351     ]
1352   where 
1353         token = lexemeToString s
1354
1355 \end{code}