on master help sign in
Clean up literal parsing code
7f0733cEvan Czaplicki
src/Parse/Literal.hs+56−33
@@ -1,49 +1,72 @@
1module Parse.Literal (literal) where
1module Parse.Literal (literal) where
2
2
3+import Prelude hiding (exponent)
3import Control.Applicative ((<$>))
4import Control.Applicative ((<$>))
4−import Text.Parsec hiding (newline,spaces)
5+import Text.Parsec ((<|>), (<?>), digit, hexDigit, lookAhead, many1, oneOf, option, string, try)
5import Parse.Helpers (IParser, chr, str)
6import Parse.Helpers (IParser, chr, str)
6import qualified AST.Literal as L
7import qualified AST.Literal as L
7
8
9+
8literal :: IParser L.Literal
10literal :: IParser L.Literal
11+literal =
9−literal = num <|> (L.Str <$> str) <|> (L.Chr <$> chr) <?> "literal"
12+ num <|> (L.Str <$> str) <|> (L.Chr <$> chr) <?> "literal"
13+
10
14
11num :: IParser L.Literal
15num :: IParser L.Literal
12−num = toLit <$> (number <?> "number")
16+num =
13− where
17+ toLiteral <$> (rawNumber <?> "number")
14− toLit n
18+
19+
20+toLiteral :: String -> L.Literal
21+toLiteral n
15− | 'x' `elem` n = L.IntNum (read n)
22+ | 'x' `elem` n = L.IntNum (read n)
16− | any (`elem` ".eE") n = L.FloatNum (read n)
23+ | any (`elem` ".eE") n = L.FloatNum (read n)
17− | otherwise = L.IntNum (read n)
24+ | otherwise = L.IntNum (read n)
18−
25+
26+
27+rawNumber :: IParser String
28+rawNumber =
19− number = concat <$> sequence
29+ concat <$> sequence
20− [ option "" minus
30+ [ option "" minus
21− , hexNum <|> decNum ]
31+ , base16 <|> base10
22−
32+ ]
23− decNum = concat <$> sequence
33+
24− [ many1 digit
34+
25− , option "" decimals
35+base16 :: IParser String
26− , option "" exponent ]
36+base16 =
27−
28− hexNum = do
29− try $ lookAhead (string "0x" >> hexDigit)
37+ do try (string "0x")
30− string "0x"
31− n <- many1 hexDigit
38+ digits <- many1 hexDigit
32− return $ "0x" ++ n
39+ return ("0x" ++ digits)
33−
40+
41+
42+base10 :: IParser String
43+base10 =
44+ concat <$> sequence
45+ [ many1 digit
46+ , option "" decimals
47+ , option "" exponent
48+ ]
49+
50+
51+minus :: IParser String
52+minus =
34− minus = try $ do
53+ try $ do
35− string "-"
54+ string "-"
36− lookAhead digit
55+ lookAhead digit
37− return "-"
56+ return "-"
38−
57+
58+
59+decimals :: IParser String
39− decimals = do
60+decimals =
40− try $ lookAhead (string "." >> digit)
61+ do try $ lookAhead (string "." >> digit)
41 string "."
62 string "."
42 n <- many1 digit
63 n <- many1 digit
43 return ('.' : n)
64 return ('.' : n)
44
65
66+
67+exponent :: IParser String
45− exponent = do
68+exponent =
46− string "e" <|> string "E"
69+ do string "e" <|> string "E"
47 op <- option "" (string "+" <|> string "-")
70 op <- option "" (string "+" <|> string "-")
48 n <- many1 digit
71 n <- many1 digit
49 return ('e' : op ++ n)
72 return ('e' : op ++ n)