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 ( mkTupNameStr, mkUbxTupNameStr,
41 isLowerISO, isUpperISO )
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
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') -> cont (ITstrict ls) (stepOverLexeme buf')}
336 -- code snatched from Demand.lhs
338 case currentChar# buf of
339 'L'# -> read_em (WwLazy False : acc) (stepOn buf)
340 'A'# -> read_em (WwLazy True : acc) (stepOn buf)
341 'S'# -> read_em (WwStrict : acc) (stepOn buf)
342 'P'# -> read_em (WwPrim : acc) (stepOn buf)
343 'E'# -> read_em (WwEnum : acc) (stepOn buf)
344 ')'# -> (reverse acc, stepOn buf)
345 'U'# -> do_unpack DataType True acc (stepOnBy# buf 2#)
346 'u'# -> do_unpack DataType False acc (stepOnBy# buf 2#)
347 'N'# -> do_unpack NewType True acc (stepOnBy# buf 2#)
348 'n'# -> do_unpack NewType False acc (stepOnBy# buf 2#)
349 _ -> (reverse acc, buf)
351 do_unpack new_or_data wrapper_unpacks acc buf
352 = case read_em [] buf of
353 (stuff, rest) -> read_em (WwUnpack new_or_data wrapper_unpacks stuff : acc) rest
357 case currentChar# buf of
359 case prefixMatch (stepOn buf) "CAFs." of
361 case untilChar# (stepOverLexeme buf') '\"'# of
362 buf'' -> cont (ITscc (mkAllCafsCC ({-module-}lexemeToFastString buf'') _NIL_)) (stepOn (stepOverLexeme buf''))
364 case prefixMatch (stepOn buf) "DICTs." of
366 case untilChar# (stepOverLexeme buf') '\"'# of
367 buf'' -> cont (ITscc (mkAllDictsCC (lexemeToFastString buf'') _NIL_ True))
368 (stepOn (stepOverLexeme buf''))
372 case untilChar# buf '/'# of
374 let mod_name = lexemeToFastString buf' in
375 -- case untilChar# (stepOn (stepOverLexeme buf')) '/'# of
377 -- let grp_name = lexemeToFastString buf'' in
378 case untilChar# (stepOn (stepOverLexeme buf')) '\"'# of
380 -- The label may contain arbitrary characters, so it
381 -- may have been escaped etc., hence we `read' it in to get
382 -- rid of these meta-chars in the string and then pack it (again.)
383 -- ToDo: do the same for module name (single quotes allowed in m-names).
384 -- BTW, the code in this module is totally gruesome..
385 let upk_label = _UNPK_ (lexemeToFastString buf'') in
386 case reads ('"':upk_label++"\"") of
388 let cc_name = _PK_ cc_label in
389 (mkUserCC cc_name mod_name _NIL_{-grp_name-},
390 stepOn (stepOverLexeme buf''))
392 trace ("trouble lexing scc label: " ++ upk_label ++ " , ignoring")
393 (mkUserCC _NIL_ mod_name _NIL_{-grp_name-},
394 stepOn (stepOverLexeme buf''))
396 case prefixMatch (stepOn buf) "CAF:" of
398 case match_user_cc (stepOverLexeme buf') of
399 (cc, buf'') -> cont (ITscc (cafifyCC cc)) buf''
401 case match_user_cc (stepOn buf) of
402 (cc, buf'') -> cont (ITscc cc) buf''
403 c -> cont (ITunknown [C# c]) (stepOn buf)
407 lex_num :: (IfaceToken -> IfM a) -> (Int -> Int) -> Int# -> IfM a
408 lex_num cont minus acc# buf =
409 --trace ("lex_num: "++[C# (currentChar# buf)]) $
410 case scanNumLit (I# acc#) buf of
412 case currentChar# buf' of
414 -- this case is not optimised at all, as the
415 -- presence of floating point numbers in interface
416 -- files is not that common. (ToDo)
417 case expandWhile# is_digit (incLexeme buf') of
418 buf2 -> -- points to first non digit char
419 let l = case currentChar# buf2 of
420 'e'# -> let buf3 = incLexeme buf2 in
421 case currentChar# buf3 of
422 '-'# -> expandWhile# is_digit (incLexeme buf3)
423 _ -> expandWhile# is_digit buf3
425 in let v = readRational__ (lexemeToString l) in
426 cont (ITrational v) (stepOverLexeme l)
428 _ -> cont (ITinteger (fromInt (minus acc'))) (stepOverLexeme buf')
431 lex_cstring cont buf =
432 case expandUntilMatch buf "\'\'" of
433 buf' -> cont (ITstring (lexemeToFastString (setCurrentPos# buf' (negateInt# 2#))))
434 (stepOverLexeme buf')
436 ------------------------------------------------------------------------------
439 is_ident, is_symbol, is_any, is_upper, is_digit :: Char# -> Bool
441 {-# INLINE is_ctype #-}
442 #if __GLASGOW_HASKELL__ >= 303
443 is_ctype :: Word8 -> Char# -> Bool
444 is_ctype mask = \c ->
445 (indexWord8OffAddr (``char_types'' :: Addr) (ord (C# c)) .&. mask) /= 0
447 is_ctype :: Int -> Char# -> Bool
448 is_ctype (I# mask) = \c ->
449 let (A# ctype) = ``char_types'' :: Addr
450 flag_word = int2Word# (ord# (indexCharOffAddr# ctype (ord# c)))
452 (flag_word `and#` (int2Word# mask)) `neWord#` (int2Word# 0#)
455 is_ident = is_ctype 1
456 is_symbol = is_ctype 2
458 is_space = is_ctype 8
459 is_upper = is_ctype 16
460 is_digit = is_ctype 32
462 -----------------------------------------------------------------------------
463 -- identifiers, symbols etc.
466 case expandWhile# is_ident buf of { buf1 ->
467 case expandWhile# (eqChar# '#'#) buf1 of { buf' -> -- only if GHC extns on
468 let new_buf = stepOverLexeme buf'
469 lexeme = lexemeToFastString buf'
471 case _scc_ "Lex.haskellKeyword" lookupUFM haskellKeywordsFM lexeme of {
472 Just kwd_token -> --trace ("hkeywd: "++_UNPK_(lexeme)) $
473 cont kwd_token new_buf;
475 case lookupUFM ifaceKeywordsFM lexeme of {
476 Just kwd_token -> --trace ("ifacekeywd: "++_UNPK_(lexeme)) $
477 cont kwd_token new_buf;
478 Nothing -> --trace ("id: "++_UNPK_(lexeme)) $
479 cont (mk_var_token lexeme) new_buf
483 case expandWhile# is_symbol buf of
484 buf' -> case lookupUFM haskellKeySymsFM lexeme of {
485 Just kwd_token -> --trace ("keysym: "++unpackFS lexeme) $
486 cont kwd_token new_buf ;
487 Nothing -> --trace ("sym: "++unpackFS lexeme) $
488 cont (mk_var_token lexeme) new_buf
490 where lexeme = lexemeToFastString buf'
491 new_buf = stepOverLexeme buf'
494 case expandWhile# is_ident buf of { buf1 ->
495 case expandWhile# (eqChar# '#'#) buf1 of { buf' ->
496 case currentChar# buf' of
498 '!'# -> munch HiBootFile
502 just_a_conid = --trace ("con: "++unpackFS lexeme) $
503 cont (ITconid lexeme) new_buf
504 lexeme = lexemeToFastString buf'
505 new_buf = stepOverLexeme buf'
506 munch hif = lex_qid cont lexeme hif (stepOn new_buf) just_a_conid
509 lex_qid cont mod hif buf just_a_conid =
510 case currentChar# buf of
511 '['# -> -- Special case for []
512 case lookAhead# buf 1# of
513 ']'# -> cont (ITqconid (mod,SLIT("[]"),hif)) (stepOnBy# buf 2#)
516 '('# -> -- Special case for (,,,)
517 -- This *is* necessary to deal with e.g. "instance C PrelBase.(,,)"
518 case lookAhead# buf 1# of
519 '#'# -> case lookAhead# buf 2# of
520 ','# -> lex_ubx_tuple cont mod hif (stepOnBy# buf 3#)
523 ')'# -> cont (ITqconid (mod,SLIT("()"),hif)) (stepOnBy# buf 2#)
524 ','# -> lex_tuple cont mod hif (stepOnBy# buf 2#) just_a_conid
527 '-'# -> case lookAhead# buf 1# of
528 '>'# -> cont (ITqconid (mod,SLIT("->"),hif)) (stepOnBy# buf 2#)
529 _ -> lex_id3 cont mod hif buf just_a_conid
530 _ -> lex_id3 cont mod hif buf just_a_conid
532 lex_id3 cont mod hif buf just_a_conid
534 case expandWhile# is_symbol buf of { buf' ->
536 lexeme = lexemeToFastString buf'
537 new_buf = stepOverLexeme buf'
539 case lookupUFM haskellKeySymsFM lexeme of {
540 Just kwd_token -> just_a_conid; -- avoid M.:: etc.
541 Nothing -> cont (mk_qvar_token mod hif lexeme) new_buf
545 case expandWhile# is_ident buf of { buf1 ->
549 case expandWhile# (eqChar# '#'#) buf1 of { buf' -> -- only if GHC extns on
551 lexeme = lexemeToFastString buf'
552 new_buf = stepOverLexeme buf'
554 case _scc_ "Lex.haskellKeyword" lookupUFM haskellKeywordsFM lexeme of {
555 Just kwd_token -> just_a_conid; -- avoid M.where etc.
557 case lookupUFM ifaceKeywordsFM lexeme of { -- only for iface files
558 Just kwd_token -> just_a_conid;
559 Nothing -> cont (mk_qvar_token mod hif lexeme) new_buf
561 where c = currentChar# buf
564 | is_upper f = ITconid pk_str
565 -- _[A-Z] is treated as a constructor in interface files.
566 | f `eqChar#` '_'# && not (_NULL_ tl)
567 && (case _HEAD_ tl of { C# g -> is_upper g }) = ITconid pk_str
568 | is_ident f = ITvarid pk_str
569 | f `eqChar#` ':'# = ITconsym pk_str
570 | otherwise = ITvarsym pk_str
572 (C# f) = _HEAD_ pk_str
575 mk_qvar_token m hif token =
576 case mk_var_token token of
577 ITconid n -> ITqconid (m,n,hif)
578 ITvarid n -> ITqvarid (m,n,hif)
579 ITconsym n -> ITqconsym (m,n,hif)
580 ITvarsym n -> ITqvarsym (m,n,hif)
581 _ -> ITunknown (show token)
584 ----------------------------------------------------------------------------
585 Horrible stuff for dealing with M.(,,,)
588 lex_tuple cont mod hif buf back_off =
592 case currentChar# buf of
593 ','# -> go (n+1) (stepOn buf)
594 ')'# -> cont (ITqconid (mod, snd (mkTupNameStr n),hif)) (stepOn buf)
597 lex_ubx_tuple cont mod hif buf back_off =
601 case currentChar# buf of
602 ','# -> go (n+1) (stepOn buf)
603 '#'# -> case lookAhead# buf 1# of
604 ')'# -> cont (ITqconid (mod, snd (mkUbxTupNameStr n), hif))
610 -----------------------------------------------------------------------------
614 ifaceKeywordsFM :: UniqFM IfaceToken
615 ifaceKeywordsFM = listToUFM $
616 map (\ (x,y) -> (_PK_ x,y))
617 [ ("__interface", ITinterface),
618 ("__export", ITexport),
619 ("__instimport", ITinstimport),
620 ("__forall", ITforall),
621 ("__letrec", ITletrec),
622 ("__coerce", ITcoerce),
623 ("__inline", ITinline),
624 ("__DEFAULT", ITdefaultbranch),
626 ("__integer", ITinteger_lit),
627 ("__float", ITfloat_lit),
628 ("__rational", ITrational_lit),
629 ("__addr", ITaddr_lit),
630 ("__litlit", ITlit_lit),
631 ("__string", ITstring_lit),
634 ("__P", ITspecialise),
636 ("__u", ITunfold NoInlinePragInfo),
637 ("__U", ITunfold IWantToBeINLINEd),
638 ("__UU", ITunfold IMustBeINLINEd),
639 ("__Unot", ITunfold IMustNotBeINLINEd),
640 ("__Ux", ITunfold IAmALoopBreaker),
642 ("__ccall", ITccall (False, False)),
643 ("__ccall_GC", ITccall (False, True)),
644 ("__casm", ITccall (True, False)),
645 ("__casm_GC", ITccall (True, True)),
650 haskellKeywordsFM = listToUFM $
651 map (\ (x,y) -> (_PK_ x,y))
653 ( "class", ITclass ),
655 ( "default", ITdefault ),
656 ( "deriving", ITderiving ),
660 ( "import", ITimport ),
662 ( "infix", ITinfix ),
663 ( "infixl", ITinfixl ),
664 ( "infixr", ITinfixr ),
665 ( "instance", ITinstance ),
667 ( "module", ITmodule ),
668 ( "newtype", ITnewtype ),
672 ( "where", ITwhere ),
674 ( "qualified", ITqualified ),
675 ( "hiding", IThiding )
678 haskellKeySymsFM = listToUFM $
679 map (\ (x,y) -> (_PK_ x,y))
695 -----------------------------------------------------------------------------
696 doDiscard rips along really fast, looking for a '#-}',
697 indicating the end of the pragma we're skipping
700 doDiscard inStr buf =
701 case currentChar# buf of
703 case lookAhead# buf 1# of { '#'# ->
704 case lookAhead# buf 2# of { '-'# ->
705 case lookAhead# buf 3# of { '}'# ->
706 (lexemeToBuffer buf, stepOverLexeme (setCurrentPos# buf 4#));
707 _ -> doDiscard inStr (incLexeme buf) };
708 _ -> doDiscard inStr (incLexeme buf) };
709 _ -> doDiscard inStr (incLexeme buf) }
712 odd_slashes buf flg i# =
713 case lookAhead# buf i# of
714 '\\'# -> odd_slashes buf (not flg) (i# -# 1#)
717 case lookAhead# buf (negateInt# 1#) of --backwards, actually
718 '\\'# -> -- escaping something..
719 if odd_slashes buf True (negateInt# 2#) then
720 -- odd number of slashes, " is escaped.
721 doDiscard inStr (incLexeme buf)
723 -- even number of slashes, \ is escaped.
724 doDiscard (not inStr) (incLexeme buf)
725 _ -> case inStr of -- forced to avoid build-up
726 True -> doDiscard False (incLexeme buf)
727 False -> doDiscard True (incLexeme buf)
728 _ -> doDiscard inStr (incLexeme buf)
732 -----------------------------------------------------------------------------
735 type IfM a = StringBuffer -- Input string
739 returnIf :: a -> IfM a
740 returnIf a s l = Succeeded a
742 thenIf :: IfM a -> (a -> IfM b) -> IfM b
743 m `thenIf` k = \s l ->
745 Succeeded a -> k a s l
746 Failed err -> Failed err
748 getSrcLocIf :: IfM SrcLoc
749 getSrcLocIf s l = Succeeded l
752 happyError s l = Failed (ifaceParseErr l ([]::[IfaceToken]){-Todo-})
756 Note that if the name of the file we're processing ends
757 with `hi-boot', we accept it on faith as having the right
758 version. This is done so that .hi-boot files that comes
759 with hsc don't have to be updated before every release,
760 *and* it allows us to share .hi-boot files with versions
761 of hsc that don't have .hi version checking (e.g., ghc-2.10's)
763 If the version number is 0, the checking is also turned off.
764 (needed to deal with GHC.hi only!)
766 Once we can assume we're compiling with a version of ghc that
767 supports interface file checking, we can drop the special
770 checkVersion :: Maybe Integer -> IfM ()
771 checkVersion mb@(Just v) s l
772 | (v==0) || (v == fromInt opt_HiVersion) || opt_NoHiCheck = Succeeded ()
773 | otherwise = Failed (ifaceVersionErr mb l ([]::[IfaceToken]){-Todo-})
774 checkVersion mb@Nothing s l
775 | "hi-boot" `isSuffixOf` (_UNPK_ (srcLocFile l)) = Succeeded ()
776 | otherwise = Failed (ifaceVersionErr mb l ([]::[IfaceToken]){-Todo-})
778 -----------------------------------------------------------------
781 = hsep [ppr l, ptext SLIT("Interface-file parse error;"),
782 ptext SLIT("toks="), text (show (take 10 toks))]
784 ifaceVersionErr hi_vers l toks
785 = hsep [ppr l, ptext SLIT("Interface file version error;"),
786 ptext SLIT("Expected"), int opt_HiVersion,
787 ptext SLIT("found "), pp_version]
791 Nothing -> ptext SLIT("pre ghc-3.02 version")
792 Just v -> ptext SLIT("version") <+> integer v