root/compiler/parser/LexCore.hs

Revision e0383e29bee3903ebbe8a123a34ce0b174fdb02b, 4.5 KB (checked in by Ian Lynagh <igloo@…>, 4 months ago)

Remove trailing whitespace in compiler/parser/LexCore.hs

  • Property mode set to 100644
Line 
1module LexCore where
2
3import ParserCoreUtils
4import Panic
5import Data.Char
6import Numeric
7
8isNameChar :: Char -> Bool
9isNameChar c = isAlpha c || isDigit c || (c == '_') || (c == '\'')
10               || (c == '$') || (c == '-') || (c == '.')
11
12isKeywordChar :: Char -> Bool
13isKeywordChar c = isAlpha c || (c == '_')
14
15lexer :: (Token -> P a) -> P a
16lexer cont []           = cont TKEOF []
17lexer cont ('\n':cs)    = \line -> lexer cont cs (line+1)
18lexer cont ('-':'>':cs) = cont TKrarrow cs
19
20lexer cont (c:cs)
21      | isSpace c               = lexer cont cs
22      | isLower c || (c == '_') = lexName cont TKname (c:cs)
23      | isUpper c               = lexName cont TKcname (c:cs)
24      | isDigit c || (c == '-') = lexNum cont (c:cs)
25
26lexer cont ('%':cs)     = lexKeyword cont cs
27lexer cont ('\'':cs)    = lexChar cont cs
28lexer cont ('\"':cs)    = lexString [] cont cs
29lexer cont ('#':cs)     = cont TKhash cs
30lexer cont ('(':cs)     = cont TKoparen cs
31lexer cont (')':cs)     = cont TKcparen cs
32lexer cont ('{':cs)     = cont TKobrace cs
33lexer cont ('}':cs)     = cont TKcbrace cs
34lexer cont ('=':cs)     = cont TKeq cs
35lexer cont (':':'=':':':cs) = cont TKcoloneqcolon cs
36lexer cont (':':':':cs) = cont TKcoloncolon cs
37lexer cont ('*':cs)     = cont TKstar cs
38lexer cont ('.':cs)     = cont TKdot cs
39lexer cont ('\\':cs)    = cont TKlambda cs
40lexer cont ('@':cs)     = cont TKat cs
41lexer cont ('?':cs)     = cont TKquestion cs
42lexer cont (';':cs)     = cont TKsemicolon cs
43-- 20060420 GHC spits out constructors with colon in them nowadays. jds
44-- 20061103 but it's easier to parse if we split on the colon, and treat them
45-- as several tokens
46lexer cont (':':cs)     = cont TKcolon cs
47-- 20060420 Likewise does it create identifiers starting with dollar. jds
48lexer cont ('$':cs)     = lexName cont TKname ('$':cs)
49lexer _    (c:_)        = failP "invalid character" [c]
50
51lexChar :: (Token -> String -> Int -> ParseResult a) -> String -> Int
52        -> ParseResult a
53lexChar cont ('\\':'x':h1:h0:'\'':cs)
54    | isHexEscape [h1,h0] = cont (TKchar (hexToChar h1 h0)) cs
55lexChar _    ('\\':cs)    = failP "invalid char character" ('\\':(take 10 cs))
56lexChar _    ('\'':_)     = failP "invalid char character" ['\'']
57lexChar _    ('\"':_)     = failP "invalid char character" ['\"']
58lexChar cont (c:'\'':cs)  = cont (TKchar c) cs
59lexChar _    cs           = panic ("lexChar: " ++ show cs)
60
61lexString :: String -> (Token -> [Char] -> Int -> ParseResult a)
62          -> String -> Int -> ParseResult a
63lexString s cont ('\\':'x':h1:h0:cs)
64    | isHexEscape [h1,h0]  = lexString (s++[hexToChar h1 h0]) cont cs
65lexString _ _    ('\\':_)  = failP "invalid string character" ['\\']
66lexString _ _    ('\'':_)  = failP "invalid string character" ['\'']
67lexString s cont ('\"':cs) = cont (TKstring s) cs
68lexString s cont (c:cs)    = lexString (s++[c]) cont cs
69lexString _ _    []        = panic "lexString []"
70
71isHexEscape :: String -> Bool
72isHexEscape = all (\c -> isHexDigit c && (isDigit c || isLower c))
73
74hexToChar :: Char -> Char -> Char
75hexToChar h1 h0 = chr (digitToInt h1 * 16 + digitToInt h0)
76
77lexNum :: (Token -> String -> a) -> String -> a
78lexNum cont cs =
79  case cs of
80     ('-':cs) -> f (-1) cs
81     _        -> f 1 cs
82 where f sgn cs =
83         case span isDigit cs of
84          (digits,'.':c:rest)
85                | isDigit c -> cont (TKrational (fromInteger sgn * r)) rest'
86                where ((r,rest'):_) = readFloat (digits ++ ('.':c:rest))
87                -- When reading a floating-point number, which is
88                -- a bit complicated, use the standard library function
89                -- "readFloat"
90          (digits,rest) -> cont (TKinteger (sgn * (read digits))) rest
91
92lexName :: (a -> String -> b) -> (String -> a) -> String -> b
93lexName cont cstr cs = cont (cstr name) rest
94   where (name,rest) = span isNameChar cs
95
96lexKeyword :: (Token -> [Char] -> Int -> ParseResult a) -> String -> Int
97           -> ParseResult a
98lexKeyword cont cs =
99   case span isKeywordChar cs of
100      ("module",rest) -> cont TKmodule rest
101      ("data",rest)  -> cont TKdata rest
102      ("newtype",rest) -> cont TKnewtype rest
103      ("forall",rest) -> cont TKforall rest
104      ("rec",rest) -> cont TKrec rest
105      ("let",rest) -> cont TKlet rest
106      ("in",rest) -> cont TKin rest
107      ("case",rest) -> cont TKcase rest
108      ("of",rest) -> cont TKof rest
109      ("cast",rest) -> cont TKcast rest
110      ("note",rest) -> cont TKnote rest
111      ("external",rest) -> cont TKexternal rest
112      ("local",rest) -> cont TKlocal rest
113      ("_",rest) -> cont TKwild rest
114      _ -> failP "invalid keyword" ('%':cs)
Note: See TracBrowser for help on using the browser.