[project @ 2000-07-06 14:08:31 by simonmar]
[ghc-hetmet.git] / ghc / compiler / parser / Lex.lhs
index 6d56a6d..9a2ab9c 100644 (file)
@@ -16,7 +16,6 @@ An example that provokes the error is
 --------------------------------------------------------
 
 \begin{code}
-{-# OPTIONS -#include "ctypes.h" #-}
 
 module Lex (
 
@@ -34,35 +33,26 @@ module Lex (
 
 #include "HsVersions.h"
 
-import Char            ( ord, isSpace, toUpper )
+import Char            ( isSpace, toUpper )
 import List             ( isSuffixOf )
 
-import IdInfo          ( InlinePragInfo(..), CprInfo(..) )
-import Name            ( isLowerISO, isUpperISO )
-import PrelMods                ( mkTupNameStr, mkUbxTupNameStr )
-import CmdLineOpts     ( opt_IgnoreIfacePragmas, opt_HiVersion, opt_NoHiCheck )
+import IdInfo          ( InlinePragInfo(..) )
+import PrelNames       ( mkTupNameStr )
+import CmdLineOpts     ( opt_HiVersion, opt_NoHiCheck )
 import Demand          ( Demand(..) {- instance Read -} )
-import UniqFM           ( UniqFM, listToUFM, lookupUFM)
-import BasicTypes      ( NewOrData(..) )
+import UniqFM           ( listToUFM, lookupUFM )
+import BasicTypes      ( NewOrData(..), Boxity(..) )
 import SrcLoc          ( SrcLoc, incSrcLine, srcLocFile, srcLocLine,
                          replaceSrcLine, mkSrcLoc )
 
-import Maybes          ( MaybeErr(..) )
 import ErrUtils                ( Message )
 import Outputable
 
 import FastString
 import StringBuffer
 import GlaExts
-import ST              ( runST )
-
-#if __GLASGOW_HASKELL__ >= 303
-import Bits
-import Word
-#endif
-
+import Ctype
 import Char            ( chr )
-import Addr
 import PrelRead        ( readRational__ ) -- Glasgow non-std
 \end{code}
 
@@ -145,8 +135,12 @@ data Token
   | ITbottom
   | ITinteger_lit 
   | ITfloat_lit
+  | ITword_lit
+  | ITword64_lit
+  | ITint64_lit
   | ITrational_lit
   | ITaddr_lit
+  | ITlabel_lit
   | ITlit_lit
   | ITstring_lit
   | ITtypeapp
@@ -158,8 +152,8 @@ data Token
   | ITunfold InlinePragInfo
   | ITstrict ([Demand], Bool)
   | ITrules
+  | ITcprinfo
   | ITdeprecated
-  | ITcprinfo (CprInfo)
   | IT__scc
   | ITsccAllCafs
 
@@ -229,7 +223,7 @@ data Token
 
   | ITunknown String           -- Used when the lexer can't make sense of it
   | ITeof                      -- end of file token
-  deriving Text -- debugging
+  deriving Show -- debugging
 \end{code}
 
 -----------------------------------------------------------------------------
@@ -311,8 +305,12 @@ ghcExtensionKeywordsFM = listToUFM $
        ("__bot",               ITbottom),
        ("__integer",           ITinteger_lit),
        ("__float",             ITfloat_lit),
+       ("__int64",             ITint64_lit),
+       ("__word",              ITword_lit),
+       ("__word64",            ITword64_lit),
        ("__rational",          ITrational_lit),
        ("__addr",              ITaddr_lit),
+       ("__label",             ITlabel_lit),
        ("__litlit",            ITlit_lit),
        ("__string",            ITstring_lit),
        ("__a",                 ITtypeapp),
@@ -401,9 +399,8 @@ lexer cont buf s@(PState{
                          if next `eqChar#` '-'# then trundle (n +# 1#)
                          else if is_symbol next || n <# 2#
                                then is_a_token
-                               else case untilChar# (stepOnBy# buf n) '\n'# of 
-                                   { buf' -> tab y bol atbol (stepOverLexeme buf')
-                                   }
+                               else tab y bol atbol 
+                                        (stepOnUntilChar# (stepOnBy# buf n) '\n'#)
                    in trundle 1#
 
                -- comments and pragmas.  We deal with LINE pragmas here,
@@ -419,14 +416,21 @@ lexer cont buf s@(PState{
                  let lexeme = mkFastString -- ToDo: too slow
                                  (map toUpper (lexemeToString buf2)) in
                  case lookupUFM pragmaKeywordsFM lexeme of
-                       Just ITline_prag -> line_prag (lexer cont) buf2 s'
+                       Just ITline_prag -> 
+                          line_prag skip_to_end buf2 s'
                        Just other -> is_a_token
-                       Nothing -> skip_to_end (stepOnBy# buf 2#)
+                       Nothing -> skip_to_end (stepOnBy# buf 2#) s'
                  }}
-               
-               else skip_to_end (stepOnBy# buf 2#)
+
+               else skip_to_end (stepOnBy# buf 2#) s'
                where
-                   skip_to_end buf = nested_comment (lexer cont) buf s'
+                   skip_to_end = nested_comment (lexer cont)
+
+               -- special GHC extension: we grok cpp-style #line pragmas
+           '#'# | lexemeIndex buf ==# bol ->   -- the '#' must be in column 0
+               line_prag next_line (stepOn buf) s'
+               where
+               next_line buf = lexer cont (stepOnUntilChar# buf '\n'#)
 
                -- tabs have been expanded beforehand
            c | is_space c -> tab y bol atbol (stepOn buf)
@@ -440,23 +444,27 @@ lexer cont buf s@(PState{
                            | otherwise    = lexToken cont glaexts buf s'
 
 -- {-# LINE .. #-} pragmas.  yeuch.
-line_prag cont buf =
+line_prag cont buf s@PState{loc=loc} =
   case expandWhile# is_space buf               of { buf1 ->
   case scanNumLit 0 (stepOverLexeme buf1)      of { (line,buf2) ->
   -- subtract one: the line number refers to the *following* line.
   let real_line = line - 1 in
   case fromInteger real_line                   of { i@(I# l) -> 
+       -- ToDo, if no filename then we skip the newline.... d'oh
   case expandWhile# is_space buf2              of { buf3 ->
   case currentChar# buf3                       of
      '\"'#{-"-} -> 
        case untilEndOfString# (stepOn (stepOverLexeme buf3)) of { buf4 ->
-       let file = lexemeToFastString buf4 in
-       \s@PState{loc=loc} -> skipToEnd buf4 s{loc = mkSrcLoc file i}
+       let 
+           file = lexemeToFastString buf4 
+           new_buf = stepOn (stepOverLexeme buf4)
+       in
+       if nullFastString file
+               then cont new_buf s{loc = replaceSrcLine loc l}
+               else cont new_buf s{loc = mkSrcLoc file i}
        }
-     other -> \s@PState{loc=loc} -> skipToEnd buf3 s{loc = replaceSrcLine loc l}
+     _other -> cont (stepOverLexeme buf3) s{loc = replaceSrcLine loc l}
   }}}}
-  where
-       skipToEnd buf = nested_comment cont buf
 
 nested_comment :: P a -> P a
 nested_comment cont buf = loop buf
@@ -574,8 +582,8 @@ lexToken cont glaexts buf =
                        lex_demand cont (stepOnUntil (not . isSpace) 
                                        (stepOnBy# buf 3#)) -- past __S
                    'M'# -> 
-                       lex_cpr cont (stepOnUntil (not . isSpace) 
-                                    (stepOnBy# buf 3#)) -- past __M
+                       cont ITcprinfo (stepOnBy# buf 3#)       -- past __M
+
                    's'# -> 
                        case prefixMatch (stepOnBy# buf 3#) "cc" of
                               Just buf' -> lex_scc cont (stepOverLexeme buf')
@@ -799,23 +807,6 @@ lex_demand cont buf =
    = case read_em [] buf of
       (stuff, rest) -> read_em (WwUnpack new_or_data wrapper_unpacks stuff : acc) rest
 
-lex_cpr cont buf = 
- case read_em [] buf of { (cpr_inf,buf') -> 
-   ASSERT ( null (tail cpr_inf) )
-   cont (ITcprinfo $ head cpr_inf) buf'
- }
- where
-   -- code snatched from lex_demand above
-  read_em acc buf = 
-   case currentChar# buf of
-    '-'# -> read_em (NoCPRInfo : acc) (stepOn buf)
-    '('# -> do_unpack acc (stepOn buf)
-    ')'# -> (reverse acc, stepOn buf)
-    _    -> (reverse acc, buf)
-
-  do_unpack acc buf
-   = case read_em [] buf of
-      (stuff, rest) -> read_em ((CPRInfo stuff)  : acc) rest
 
 ------------------
 lex_scc cont buf =
@@ -880,33 +871,6 @@ lex_cstring cont buf =
                   (mergeLexemes buf buf')
    Nothing   -> lexError "unterminated ``" buf
 
-------------------------------------------------------------------------------
--- Character Classes
-
-is_ident, is_symbol, is_any, is_upper, is_digit :: Char# -> Bool
-
-{-# INLINE is_ctype #-}
-#if __GLASGOW_HASKELL__ >= 303
-is_ctype :: Word8 -> Char# -> Bool
-is_ctype mask = \c ->
-   (indexWord8OffAddr (``char_types'' :: Addr) (ord (C# c)) .&. mask) /= 0
-#else
-is_ctype :: Int -> Char# -> Bool
-is_ctype (I# mask) = \c ->
-    let (A# ctype) = ``char_types'' :: Addr
-       flag_word  = int2Word# (ord# (indexCharOffAddr# ctype (ord# c)))
-    in
-       (flag_word `and#` (int2Word# mask)) `neWord#` (int2Word# 0#)
-#endif
-
-is_ident  = is_ctype 1
-is_symbol = is_ctype 2
-is_any    = is_ctype 4
-is_space  = is_ctype 8
-is_lower  = is_ctype 16
-is_upper  = is_ctype 32
-is_digit  = is_ctype 64
-
 -----------------------------------------------------------------------------
 -- identifiers, symbols etc.
 
@@ -916,7 +880,8 @@ lex_ip cont buf =
           where lexeme = lexemeToFastString buf'
 
 lex_id cont glaexts buf =
- case expandWhile# is_ident buf of { buf1 -> 
+ let buf1 = expandWhile# is_ident buf in
+ seq buf1 $
 
  case (if flag glaexts 
        then expandWhile# (eqChar# '#'#) buf1 -- slurp trailing hashes
@@ -929,7 +894,7 @@ lex_id cont glaexts buf =
                          cont kwd_token buf';
        Nothing        -> 
 
- let var_token = cont (mk_var_token lexeme) buf' in
+ let var_token = cont (ITvarid lexeme) buf' in
 
  if not (flag glaexts)
    then var_token
@@ -939,7 +904,7 @@ lex_id cont glaexts buf =
        Just kwd_token -> cont kwd_token buf';
        Nothing        -> var_token
 
- }}}}
+ }}}
 
 lex_sym cont buf =
  case expandWhile# is_symbol buf of
@@ -1036,9 +1001,6 @@ slurp_trailing_hashes buf glaexts
 
 mk_var_token pk_str
   | is_upper f         = ITconid pk_str
-       -- _[A-Z] is treated as a constructor in interface files.
-  | f `eqChar#` '_'# && not (_NULL_ tl) 
-       && (case _HEAD_ tl of { C# g -> is_upper g }) = ITconid pk_str
   | is_ident f         = ITvarid pk_str
   | f `eqChar#` ':'#   = ITconsym pk_str
   | otherwise          = ITvarsym pk_str
@@ -1065,7 +1027,7 @@ lex_tuple cont mod buf back_off =
    go n buf =
     case currentChar# buf of
       ','# -> go (n+1) (stepOn buf)
-      ')'# -> cont (ITqconid (mod, snd (mkTupNameStr n))) (stepOn buf)
+      ')'# -> cont (ITqconid (mod, snd (mkTupNameStr Boxed n))) (stepOn buf)
       _    -> back_off
 
 lex_ubx_tuple cont mod buf back_off =
@@ -1075,7 +1037,7 @@ lex_ubx_tuple cont mod buf back_off =
     case currentChar# buf of
       ','# -> go (n+1) (stepOn buf)
       '#'# -> case lookAhead# buf 1# of
-               ')'# -> cont (ITqconid (mod, snd (mkUbxTupNameStr n)))
+               ')'# -> cont (ITqconid (mod, snd (mkTupNameStr Unboxed n)))
                                 (stepOnBy# buf 2#)
                _    -> back_off
       _    -> back_off