@@ -1,39 +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
22+ | 'x' `elem` n = L.IntNum (read n)
15− | any (`elem` ".eE") n = L.FloatNum (read n)
23+ | any (`elem` ".eE") n = L.FloatNum (read n)
16− | otherwise = L.IntNum (read n)
24+ | otherwise = L.IntNum (read n)
27+rawNumber :: IParser String
18− number = concat <$> sequence
29+ concat <$> sequence
19− [ option "" minus
30+ [ option "" minus
35+base16 :: IParser String
38+ digits <- many1 hexDigit
39+ return ("0x" ++ digits)
42+base10 :: IParser String
20− , many1 digit
45+ [ many1 digit
21− , option "" decimals
46+ , option "" decimals
22− , option "" exponent ]
47+ , option "" exponent
51+minus :: IParser String
24− minus = try $ do
53+ try $ do
25− string "-"
54+ string "-"
26− lookAhead digit
55+ lookAhead digit
27− return "-"
56+ return "-"
29− decimals = do
59+decimals :: IParser String
30− try $ lookAhead (string "." >> digit)
61+ do try $ lookAhead (string "." >> digit)
31 string "."
62 string "."
32 n <- many1 digit
63 n <- many1 digit
33 return ('.' : n)
64 return ('.' : n)
67+exponent :: IParser String
35− exponent = do
68+exponent =
36− string "e" <|> string "E"
69+ do string "e" <|> string "E"
37 op <- option "" (string "+" <|> string "-")
70 op <- option "" (string "+" <|> string "-")
38 n <- many1 digit
71 n <- many1 digit
39 return ('e' : op ++ n)
72 return ('e' : op ++ n)