2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 \section[Lexical analysis]{Lexical analysis}
6 --------------------------------------------------------
8 There's a known bug in here:
10 If an interface file ends prematurely, Lex tries to
11 do headFS of an empty FastString.
13 An example that provokes the error is
15 f _:_ _forall_ [a] <<<END OF FILE>>>
16 --------------------------------------------------------
19 {-# OPTIONS -#include "ctypes.h" #-}
26 IfaceToken(..), lexIface, IfM, thenIf, returnIf, getSrcLocIf,
33 #include "HsVersions.h"
35 import Char ( ord, isSpace )
36 import List ( isSuffixOf )
38 import CostCentre -- Pretty much all of it
39 import IdInfo ( InlinePragInfo(..) )
40 import Name ( isLowerISO, isUpperISO, mkModule )
42 import PrelMods ( mkTupNameStr, mkUbxTupNameStr )
43 import CmdLineOpts ( opt_IgnoreIfacePragmas, opt_HiVersion, opt_NoHiCheck )
44 import Demand ( Demand(..) {- instance Read -} )
45 import UniqFM ( UniqFM, listToUFM, lookupUFM)
46 import BasicTypes ( NewOrData(..), IfaceFlavour(..) )
47 import SrcLoc ( SrcLoc, incSrcLine, srcLocFile )
49 import Maybes ( MaybeErr(..) )
50 import ErrUtils ( ErrMsg )
58 #if __GLASGOW_HASKELL__ >= 303
65 import PrelRead ( readRational__ ) -- Glasgow non-std
68 %************************************************************************
70 \subsection{Data types}
72 %************************************************************************
74 The token data type, fairly un-interesting except from one
75 constructor, @ITidinfo@, which is used to lazily lex id info (arity,
76 strictness, unfolding etc).
78 The Idea/Observation here is that the renamer needs to scan through
79 all of an interface file before it can continue. But only a fraction
80 of the information contained in the file turns out to be useful, so
81 delaying as much as possible of the scanning and parsing of an
82 interface file Makes Sense (Heap profiles of the compiler
83 show a reduction in heap usage by at least a factor of two,
86 Hence, the interface file lexer spots when value declarations are
87 being scanned and return the @ITidinfo@ and @ITtype@ constructors
88 for the type and any other id info for that binding (unfolding, strictness
89 etc). These constructors are applied to the result of lexing these sub-chunks.
91 The lexing of the type and id info is all done lazily, of course, so
92 the scanning (and subsequent parsing) will be done *only* on the ids the
93 renamer finds out that it is interested in. The rest will just be junked.
94 Laziness, you know it makes sense :-)
98 = ITcase -- Haskell keywords
123 | ITinterface -- GHC-extension keywords
130 | ITccall (Bool,Bool) -- (is_casm, may_gc)
143 | ITunfold InlinePragInfo
144 | ITstrict ([Demand], Bool)
147 | ITdotdot -- reserved symbols
160 | ITbiglam -- GHC-extension symbols
162 | ITocurly -- special symbols
173 | ITvarid FAST_STRING -- identifiers
174 | ITconid FAST_STRING
175 | ITvarsym FAST_STRING
176 | ITconsym FAST_STRING
177 | ITqvarid (FAST_STRING,FAST_STRING,IfaceFlavour)
178 | ITqconid (FAST_STRING,FAST_STRING,IfaceFlavour)
179 | ITqvarsym (FAST_STRING,FAST_STRING,IfaceFlavour)
180 | ITqconsym (FAST_STRING,FAST_STRING,IfaceFlavour)
182 | ITpragma StringBuffer
185 | ITstring FAST_STRING
187 | ITrational Rational
189 | ITunknown String -- Used when the lexer can't make sense of it
190 | ITeof -- end of file token
191 deriving Text -- debugging
193 instance Text CostCentre -- cheat!
197 %************************************************************************
199 \subsection{The lexical analyser}
201 %************************************************************************
204 lexIface :: (IfaceToken -> IfM a) -> IfM a
207 -- if bufferExhausted buf then
210 -- trace ("Lexer: '"++[C# (currentChar# buf)]++"'") $
211 case currentChar# buf of
212 -- whitespace and comments, ignore.
213 ' '# -> lexIface cont (stepOn buf)
214 '\t'# -> lexIface cont (stepOn buf)
215 '\n'# -> \ loc -> lexIface cont (stepOn buf) (incSrcLine loc)
217 -- Numbers and comments
219 case lookAhead# buf 1# of
220 -- '-'# -> lex_comment cont (stepOnBy# buf 2#)
223 then lex_num cont (negate) (ord# c -# ord# '0'#) (incLexeme (incLexeme buf))
224 else lex_sym cont buf
226 '{'# -> -- look for "{-##" special iface pragma
227 case lookAhead# buf 1# of
228 '-'# -> case lookAhead# buf 2# of
229 '#'# -> case lookAhead# buf 3# of
232 = doDiscard False (stepOnBy# buf 4#) in
233 cont (ITpragma lexeme) buf'
234 _ -> lex_nested_comment (lexIface cont) buf
235 _ -> cont ITocurly (stepOn buf)
236 -- lex_nested_comment (lexIface cont) buf
237 _ -> cont ITocurly (stepOn buf)
239 -- special symbols ----------------------------------------------------
241 case prefixMatch (stepOn buf) "..)" of
242 Just buf' -> cont ITdotdot (stepOverLexeme buf')
244 case lookAhead# buf 1# of
245 '#'# -> cont IToubxparen (stepOnBy# buf 2#)
246 _ -> cont IToparen (stepOn buf)
247 ')'# -> cont ITcparen (stepOn buf)
248 '}'# -> cont ITccurly (stepOn buf)
249 '#'# -> case lookAhead# buf 1# of
250 ')'# -> cont ITcubxparen (stepOnBy# buf 2#)
251 _ -> lex_sym cont (incLexeme buf)
252 '['# -> cont ITobrack (stepOn buf)
253 ']'# -> cont ITcbrack (stepOn buf)
254 ','# -> cont ITcomma (stepOn buf)
255 ';'# -> cont ITsemi (stepOn buf)
257 -- strings/characters -------------------------------------------------
258 '\"'#{-"-} -> case untilEndOfString# (stepOn buf) of
260 -- the string literal does *not* include the dquotes
261 case lexemeToFastString buf' of
262 v -> cont (ITstring v) (stepOn (stepOverLexeme buf'))
265 -- untilEndOfChar# extends the current lexeme until
266 -- it hits a non-escaped single quote. The lexeme of the
267 -- StringBuffer returned does *not* include the closing quote,
268 -- hence we augment the lexeme and make sure to add the
269 -- starting quote, before `read'ing the string.
271 case untilEndOfChar# (stepOn buf) of
272 buf' -> case reads ('\'':lexemeToString (incLexeme buf')) of
273 [ (ch, rest)] -> cont (ITchar ch) (stepOverLexeme (incLexeme buf'))
275 -- strictness pragma and __scc treated specially.
277 case lookAhead# buf 1# of
278 '_'# -> case lookAhead# buf 2# of
280 lex_demand cont (stepOnUntil (not . isSpace)
281 (stepOnBy# buf 3#)) -- past __S
283 case prefixMatch (stepOnBy# buf 3#) "cc" of
284 Just buf' -> lex_scc cont
285 (stepOnUntil (not . isSpace)
286 (stepOverLexeme buf'))
287 Nothing -> lex_id cont buf
291 -- ``thingy'' form for casm
293 case lookAhead# buf 1# of
294 '`'# -> lex_cstring cont (stepOnBy# buf 2#) -- remove the `s and go.
295 _ -> lex_sym cont (incLexeme buf) -- add ` to lexeme and assume
296 -- scanning an id of some sort.
299 if bufferExhausted (stepOn buf) then
302 trace "lexIface: misplaced NUL?" $
303 cont (ITunknown "\NUL") (stepOn buf)
305 c | is_digit c -> lex_num cont (id) (ord# c -# ord# '0'#) (incLexeme buf)
306 | is_symbol c -> lex_sym cont buf
307 | is_upper c -> lex_con cont buf
308 | is_ident c -> lex_id cont buf
311 lex_comment cont buf =
312 -- _trace ("comment: "++[C# (currentChar# buf)]) $
313 case untilChar# buf '\n'# of {buf' -> lexIface cont (stepOverLexeme buf')}
315 -------------------------------------------------------------------------------
317 lex_nested_comment cont buf =
318 case currentChar# buf of
319 '-'# -> case lookAhead# buf 1# of
320 '}'# -> cont (stepOnBy# buf 2#)
321 _ -> lex_nested_comment cont (stepOn buf)
323 '{'# -> case lookAhead# buf 1# of
324 '-'# -> lex_nested_comment
325 (lex_nested_comment cont)
327 _ -> lex_nested_comment cont (stepOn buf)
329 _ -> lex_nested_comment cont (stepOn buf)
331 -------------------------------------------------------------------------------
333 lex_demand cont buf =
334 case read_em [] buf of { (ls,buf') ->
335 case currentChar# buf' of
336 'B'# -> cont (ITstrict (ls, True )) (stepOverLexeme (stepOn buf'))
337 _ -> cont (ITstrict (ls, False)) (stepOverLexeme buf')
340 -- code snatched from Demand.lhs
342 case currentChar# buf of
343 'L'# -> read_em (WwLazy False : acc) (stepOn buf)
344 'A'# -> read_em (WwLazy True : acc) (stepOn buf)
345 'S'# -> read_em (WwStrict : acc) (stepOn buf)
346 'P'# -> read_em (WwPrim : acc) (stepOn buf)
347 'E'# -> read_em (WwEnum : acc) (stepOn buf)
348 ')'# -> (reverse acc, stepOn buf)
349 'U'# -> do_unpack DataType True acc (stepOnBy# buf 2#)
350 'u'# -> do_unpack DataType False acc (stepOnBy# buf 2#)
351 'N'# -> do_unpack NewType True acc (stepOnBy# buf 2#)
352 'n'# -> do_unpack NewType False acc (stepOnBy# buf 2#)
353 _ -> (reverse acc, buf)
355 do_unpack new_or_data wrapper_unpacks acc buf
356 = case read_em [] buf of
357 (stuff, rest) -> read_em (WwUnpack new_or_data wrapper_unpacks stuff : acc) rest
361 case currentChar# buf of
363 case prefixMatch (stepOn buf) "CAFs." of
365 case untilChar# (stepOverLexeme buf') '\"'# of
366 buf'' -> cont (ITscc (mkAllCafsCC (mkModule (lexemeToString buf'')) _NIL_))
367 (stepOn (stepOverLexeme buf''))
369 case prefixMatch (stepOn buf) "DICTs." of
371 case untilChar# (stepOverLexeme buf') '\"'# of
372 buf'' -> cont (ITscc (mkAllDictsCC (mkModule (lexemeToString buf'')) _NIL_ True))
373 (stepOn (stepOverLexeme buf''))
377 case untilChar# buf '/'# of
379 let mod_name = mkModule (lexemeToString buf') in
380 -- case untilChar# (stepOn (stepOverLexeme buf')) '/'# of
382 -- let grp_name = lexemeToFastString buf'' in
383 case untilChar# (stepOn (stepOverLexeme buf')) '\"'# of
385 -- The label may contain arbitrary characters, so it
386 -- may have been escaped etc., hence we `read' it in to get
387 -- rid of these meta-chars in the string and then pack it (again.)
388 -- ToDo: do the same for module name (single quotes allowed in m-names).
389 -- BTW, the code in this module is totally gruesome..
390 let upk_label = _UNPK_ (lexemeToFastString buf'') in
391 case reads ('"':upk_label++"\"") of
393 let cc_name = _PK_ cc_label in
394 (mkUserCC cc_name mod_name _NIL_{-grp_name-},
395 stepOn (stepOverLexeme buf''))
397 trace ("trouble lexing scc label: " ++ upk_label ++ " , ignoring")
398 (mkUserCC _NIL_ mod_name _NIL_{-grp_name-},
399 stepOn (stepOverLexeme buf''))
401 case prefixMatch (stepOn buf) "CAF:" of
403 case match_user_cc (stepOverLexeme buf') of
404 (cc, buf'') -> cont (ITscc (cafifyCC cc)) buf''
406 case match_user_cc (stepOn buf) of
407 (cc, buf'') -> cont (ITscc cc) buf''
408 c -> cont (ITunknown [C# c]) (stepOn buf)
412 lex_num :: (IfaceToken -> IfM a) -> (Int -> Int) -> Int# -> IfM a
413 lex_num cont minus acc# buf =
414 --trace ("lex_num: "++[C# (currentChar# buf)]) $
415 case scanNumLit (I# acc#) buf of
417 case currentChar# buf' of
419 -- this case is not optimised at all, as the
420 -- presence of floating point numbers in interface
421 -- files is not that common. (ToDo)
422 case expandWhile# is_digit (incLexeme buf') of
423 buf2 -> -- points to first non digit char
424 let l = case currentChar# buf2 of
425 'e'# -> let buf3 = incLexeme buf2 in
426 case currentChar# buf3 of
427 '-'# -> expandWhile# is_digit (incLexeme buf3)
428 _ -> expandWhile# is_digit buf3
430 in let v = readRational__ (lexemeToString l) in
431 cont (ITrational v) (stepOverLexeme l)
433 _ -> cont (ITinteger (fromInt (minus acc'))) (stepOverLexeme buf')
436 lex_cstring cont buf =
437 case expandUntilMatch buf "\'\'" of
438 buf' -> cont (ITstring (lexemeToFastString (setCurrentPos# buf' (negateInt# 2#))))
439 (stepOverLexeme buf')
441 ------------------------------------------------------------------------------
444 is_ident, is_symbol, is_any, is_upper, is_digit :: Char# -> Bool
446 {-# INLINE is_ctype #-}
447 #if __GLASGOW_HASKELL__ >= 303
448 is_ctype :: Word8 -> Char# -> Bool
449 is_ctype mask = \c ->
450 (indexWord8OffAddr (``char_types'' :: Addr) (ord (C# c)) .&. mask) /= 0
452 is_ctype :: Int -> Char# -> Bool
453 is_ctype (I# mask) = \c ->
454 let (A# ctype) = ``char_types'' :: Addr
455 flag_word = int2Word# (ord# (indexCharOffAddr# ctype (ord# c)))
457 (flag_word `and#` (int2Word# mask)) `neWord#` (int2Word# 0#)
460 is_ident = is_ctype 1
461 is_symbol = is_ctype 2
463 is_space = is_ctype 8
464 is_upper = is_ctype 16
465 is_digit = is_ctype 32
467 -----------------------------------------------------------------------------
468 -- identifiers, symbols etc.
471 case expandWhile# is_ident buf of { buf1 ->
472 case expandWhile# (eqChar# '#'#) buf1 of { buf' -> -- only if GHC extns on
473 let new_buf = stepOverLexeme buf'
474 lexeme = lexemeToFastString buf'
476 case _scc_ "Lex.haskellKeyword" lookupUFM haskellKeywordsFM lexeme of {
477 Just kwd_token -> --trace ("hkeywd: "++_UNPK_(lexeme)) $
478 cont kwd_token new_buf;
480 case lookupUFM ifaceKeywordsFM lexeme of {
481 Just kwd_token -> --trace ("ifacekeywd: "++_UNPK_(lexeme)) $
482 cont kwd_token new_buf;
483 Nothing -> --trace ("id: "++_UNPK_(lexeme)) $
484 cont (mk_var_token lexeme) new_buf
488 case expandWhile# is_symbol buf of
490 | is_comment lexeme -> lex_comment cont new_buf
492 case lookupUFM haskellKeySymsFM lexeme of {
493 Just kwd_token -> --trace ("keysym: "++unpackFS lexeme) $
494 cont kwd_token new_buf ;
495 Nothing -> --trace ("sym: "++unpackFS lexeme) $
496 cont (mk_var_token lexeme) new_buf
498 where lexeme = lexemeToFastString buf'
499 new_buf = stepOverLexeme buf'
503 | otherwise = trundle 0
507 trundle n | n == len = True
508 | otherwise = indexFS fs n == '-' && trundle (n+1)
511 case expandWhile# is_ident buf of { buf1 ->
512 case expandWhile# (eqChar# '#'#) buf1 of { buf' ->
513 case currentChar# buf' of
515 '!'# -> munch HiBootFile
519 just_a_conid = --trace ("con: "++unpackFS lexeme) $
520 cont (ITconid lexeme) new_buf
521 lexeme = lexemeToFastString buf'
522 new_buf = stepOverLexeme buf'
523 munch hif = lex_qid cont lexeme hif (stepOn new_buf) just_a_conid
526 lex_qid cont mod hif buf just_a_conid =
527 case currentChar# buf of
528 '['# -> -- Special case for []
529 case lookAhead# buf 1# of
530 ']'# -> cont (ITqconid (mod,SLIT("[]"),hif)) (stepOnBy# buf 2#)
533 '('# -> -- Special case for (,,,)
534 -- This *is* necessary to deal with e.g. "instance C PrelBase.(,,)"
535 case lookAhead# buf 1# of
536 '#'# -> case lookAhead# buf 2# of
537 ','# -> lex_ubx_tuple cont mod hif (stepOnBy# buf 3#)
540 ')'# -> cont (ITqconid (mod,SLIT("()"),hif)) (stepOnBy# buf 2#)
541 ','# -> lex_tuple cont mod hif (stepOnBy# buf 2#) just_a_conid
544 '-'# -> case lookAhead# buf 1# of
545 '>'# -> cont (ITqconid (mod,SLIT("->"),hif)) (stepOnBy# buf 2#)
546 _ -> lex_id3 cont mod hif buf just_a_conid
547 _ -> lex_id3 cont mod hif buf just_a_conid
549 lex_id3 cont mod hif buf just_a_conid
551 case expandWhile# is_symbol buf of { buf' ->
553 lexeme = lexemeToFastString buf'
554 new_buf = stepOverLexeme buf'
556 case lookupUFM haskellKeySymsFM lexeme of {
557 Just kwd_token -> just_a_conid; -- avoid M.:: etc.
558 Nothing -> cont (mk_qvar_token mod hif lexeme) new_buf
562 case expandWhile# is_ident buf of { buf1 ->
566 case expandWhile# (eqChar# '#'#) buf1 of { buf' -> -- only if GHC extns on
568 lexeme = lexemeToFastString buf'
569 new_buf = stepOverLexeme buf'
571 case _scc_ "Lex.haskellKeyword" lookupUFM haskellKeywordsFM lexeme of {
572 Just kwd_token -> just_a_conid; -- avoid M.where etc.
574 case lookupUFM ifaceKeywordsFM lexeme of { -- only for iface files
575 Just kwd_token -> just_a_conid;
576 Nothing -> cont (mk_qvar_token mod hif lexeme) new_buf
578 where c = currentChar# buf
581 | is_upper f = ITconid pk_str
582 -- _[A-Z] is treated as a constructor in interface files.
583 | f `eqChar#` '_'# && not (_NULL_ tl)
584 && (case _HEAD_ tl of { C# g -> is_upper g }) = ITconid pk_str
585 | is_ident f = ITvarid pk_str
586 | f `eqChar#` ':'# = ITconsym pk_str
587 | otherwise = ITvarsym pk_str
589 (C# f) = _HEAD_ pk_str
592 mk_qvar_token m hif token =
593 case mk_var_token token of
594 ITconid n -> ITqconid (m,n,hif)
595 ITvarid n -> ITqvarid (m,n,hif)
596 ITconsym n -> ITqconsym (m,n,hif)
597 ITvarsym n -> ITqvarsym (m,n,hif)
598 _ -> ITunknown (show token)
601 ----------------------------------------------------------------------------
602 Horrible stuff for dealing with M.(,,,)
605 lex_tuple cont mod hif buf back_off =
609 case currentChar# buf of
610 ','# -> go (n+1) (stepOn buf)
611 ')'# -> cont (ITqconid (mod, snd (mkTupNameStr n),hif)) (stepOn buf)
614 lex_ubx_tuple cont mod hif buf back_off =
618 case currentChar# buf of
619 ','# -> go (n+1) (stepOn buf)
620 '#'# -> case lookAhead# buf 1# of
621 ')'# -> cont (ITqconid (mod, snd (mkUbxTupNameStr n), hif))
627 -----------------------------------------------------------------------------
631 ifaceKeywordsFM :: UniqFM IfaceToken
632 ifaceKeywordsFM = listToUFM $
633 map (\ (x,y) -> (_PK_ x,y))
634 [ ("__interface", ITinterface),
635 ("__export", ITexport),
636 ("__instimport", ITinstimport),
637 ("__forall", ITforall),
638 ("__letrec", ITletrec),
639 ("__coerce", ITcoerce),
640 ("__inline", ITinline),
641 ("__DEFAULT", ITdefaultbranch),
643 ("__integer", ITinteger_lit),
644 ("__float", ITfloat_lit),
645 ("__rational", ITrational_lit),
646 ("__addr", ITaddr_lit),
647 ("__litlit", ITlit_lit),
648 ("__string", ITstring_lit),
651 ("__P", ITspecialise),
653 ("__u", ITunfold NoInlinePragInfo),
654 ("__U", ITunfold IWantToBeINLINEd),
655 ("__UU", ITunfold IMustBeINLINEd),
656 ("__Unot", ITunfold IMustNotBeINLINEd),
657 ("__Ux", ITunfold IAmALoopBreaker),
659 ("__ccall", ITccall (False, False)),
660 ("__ccall_GC", ITccall (False, True)),
661 ("__casm", ITccall (True, False)),
662 ("__casm_GC", ITccall (True, True)),
667 haskellKeywordsFM = listToUFM $
668 map (\ (x,y) -> (_PK_ x,y))
670 ( "class", ITclass ),
672 ( "default", ITdefault ),
673 ( "deriving", ITderiving ),
677 ( "import", ITimport ),
679 ( "infix", ITinfix ),
680 ( "infixl", ITinfixl ),
681 ( "infixr", ITinfixr ),
682 ( "instance", ITinstance ),
684 ( "module", ITmodule ),
685 ( "newtype", ITnewtype ),
691 -- These three aren't Haskell keywords at all
692 -- and 'as' is often used as a variable name
694 -- ( "qualified", ITqualified ),
695 -- ( "hiding", IThiding )
699 haskellKeySymsFM = listToUFM $
700 map (\ (x,y) -> (_PK_ x,y))
716 -----------------------------------------------------------------------------
717 doDiscard rips along really fast, looking for a '#-}',
718 indicating the end of the pragma we're skipping
721 doDiscard inStr buf =
722 case currentChar# buf of
724 case lookAhead# buf 1# of { '#'# ->
725 case lookAhead# buf 2# of { '-'# ->
726 case lookAhead# buf 3# of { '}'# ->
727 (lexemeToBuffer buf, stepOverLexeme (setCurrentPos# buf 4#));
728 _ -> doDiscard inStr (incLexeme buf) };
729 _ -> doDiscard inStr (incLexeme buf) };
730 _ -> doDiscard inStr (incLexeme buf) }
733 odd_slashes buf flg i# =
734 case lookAhead# buf i# of
735 '\\'# -> odd_slashes buf (not flg) (i# -# 1#)
738 case lookAhead# buf (negateInt# 1#) of --backwards, actually
739 '\\'# -> -- escaping something..
740 if odd_slashes buf True (negateInt# 2#) then
741 -- odd number of slashes, " is escaped.
742 doDiscard inStr (incLexeme buf)
744 -- even number of slashes, \ is escaped.
745 doDiscard (not inStr) (incLexeme buf)
746 _ -> case inStr of -- forced to avoid build-up
747 True -> doDiscard False (incLexeme buf)
748 False -> doDiscard True (incLexeme buf)
749 _ -> doDiscard inStr (incLexeme buf)
753 -----------------------------------------------------------------------------
756 type IfM a = StringBuffer -- Input string
760 returnIf :: a -> IfM a
761 returnIf a s l = Succeeded a
763 thenIf :: IfM a -> (a -> IfM b) -> IfM b
764 m `thenIf` k = \s l ->
766 Succeeded a -> k a s l
767 Failed err -> Failed err
769 getSrcLocIf :: IfM SrcLoc
770 getSrcLocIf s l = Succeeded l
773 happyError s l = Failed (ifaceParseErr s l)
777 Note that if the name of the file we're processing ends
778 with `hi-boot', we accept it on faith as having the right
779 version. This is done so that .hi-boot files that comes
780 with hsc don't have to be updated before every release,
781 *and* it allows us to share .hi-boot files with versions
782 of hsc that don't have .hi version checking (e.g., ghc-2.10's)
784 If the version number is 0, the checking is also turned off.
785 (needed to deal with GHC.hi only!)
787 Once we can assume we're compiling with a version of ghc that
788 supports interface file checking, we can drop the special
791 checkVersion :: Maybe Integer -> IfM ()
792 checkVersion mb@(Just v) s l
793 | (v==0) || (v == fromInt opt_HiVersion) || opt_NoHiCheck = Succeeded ()
794 | otherwise = Failed (ifaceVersionErr mb l ([]::[IfaceToken]){-Todo-})
795 checkVersion mb@Nothing s l
796 | "hi-boot" `isSuffixOf` (_UNPK_ (srcLocFile l)) = Succeeded ()
797 | otherwise = Failed (ifaceVersionErr mb l ([]::[IfaceToken]){-Todo-})
799 -----------------------------------------------------------------
801 ifaceParseErr :: StringBuffer -> SrcLoc -> ErrMsg
803 = hsep [ppr l, ptext SLIT("Interface-file parse error;"),
804 ptext SLIT("current input ="), text first_bit]
806 first_bit = lexemeToString (stepOnBy# s 100#)
808 ifaceVersionErr hi_vers l toks
809 = hsep [ppr l, ptext SLIT("Interface file version error;"),
810 ptext SLIT("Expected"), int opt_HiVersion,
811 ptext SLIT("found "), pp_version]
815 Nothing -> ptext SLIT("pre ghc-3.02 version")
816 Just v -> ptext SLIT("version") <+> integer v