@@ -1,49 +1,72 @@
1module Parse.Literal (literal) where
1module Parse.Literal (literal) where
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
8literal :: IParser L.Literal
10literal :: IParser L.Literal
9−literal = num <|> (L.Str <$> str) <|> (L.Chr <$> chr) <?> "literal"
12+ num <|> (L.Str <$> str) <|> (L.Chr <$> chr) <?> "literal"
11num :: IParser L.Literal
15num :: IParser L.Literal
12−num = toLit <$> (number <?> "number")
16+num =
13− where
17+ toLiteral <$> (rawNumber <?> "number")
20+toLiteral :: String -> L.Literal
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)
27+rawNumber :: IParser String
19− number = concat <$> sequence
29+ concat <$> sequence
20− [ option "" minus
30+ [ option "" minus
21− , hexNum <|> decNum ]
31+ , base16 <|> base10
23− decNum = concat <$> sequence
33+
25− , option "" decimals
35+base16 :: IParser String
26− , option "" exponent ]
36+base16 =
29− try $ lookAhead (string "0x" >> hexDigit)
37+ do try (string "0x")
31− n <- many1 hexDigit
38+ digits <- many1 hexDigit
32− return $ "0x" ++ n
39+ return ("0x" ++ digits)
42+base10 :: IParser String
51+minus :: IParser String
34− minus = try $ do
53+ try $ do
35− string "-"
54+ string "-"
36− lookAhead digit
55+ lookAhead digit
37− return "-"
56+ return "-"
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)
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)